web-component-gallery 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "web-component-gallery",
3
+ "version": "0.1.0",
4
+ "description": "vue-library-ui组件库",
5
+ "main": "dist/index.umd.js",
6
+ "files": [
7
+ "dist",
8
+ "plugins"
9
+ ],
10
+ "scripts": {
11
+ "serve": "vue-cli-service serve",
12
+ "build": "vue-cli-service build",
13
+ "lint": "vue-cli-service lint",
14
+ "build:js": "webpack --config ./webpack.components.js",
15
+ "build:css": "npx gulp less",
16
+ "build:lib": "npm run build:js && npm run build:css"
17
+ },
18
+ "dependencies": {
19
+ "ant-design-vue": "1.7.8",
20
+ "clean-webpack-plugin": "^4.0.0",
21
+ "core-js": "^3.8.3",
22
+ "vue": "^2.6.14"
23
+ },
24
+ "devDependencies": {
25
+ "@babel/core": "^7.12.16",
26
+ "@babel/eslint-parser": "^7.12.16",
27
+ "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
28
+ "@vue/cli-plugin-babel": "~5.0.0",
29
+ "@vue/cli-plugin-eslint": "~5.0.0",
30
+ "@vue/cli-service": "~5.0.0",
31
+ "babel-loader": "^9.1.3",
32
+ "eslint": "^7.32.0",
33
+ "eslint-plugin-vue": "^8.0.3",
34
+ "gulp": "^5.0.0",
35
+ "gulp-less": "^5.0.0",
36
+ "gulp-minify-css": "^1.2.4",
37
+ "vue-loader": "^15.10.1",
38
+ "vue-template-compiler": "^2.6.14",
39
+ "webpack-cli": "^5.1.4"
40
+ },
41
+ "eslintConfig": {
42
+ "root": true,
43
+ "env": {
44
+ "node": true
45
+ },
46
+ "extends": [
47
+ "plugin:vue/essential",
48
+ "eslint:recommended"
49
+ ],
50
+ "parserOptions": {
51
+ "parser": "@babel/eslint-parser"
52
+ },
53
+ "rules": {}
54
+ },
55
+ "browserslist": [
56
+ "> 1%",
57
+ "last 2 versions",
58
+ "not dead"
59
+ ]
60
+ }
@@ -0,0 +1,4 @@
1
+ .Table {
2
+ width: 100%;
3
+ height: 100%;
4
+ }
@@ -0,0 +1,90 @@
1
+ // import Bus from './Bus'
2
+ // import store from '@/store'
3
+ // import global from '@/config/index'
4
+ import Message from 'ant-design-vue/es/message'
5
+ import { Button, Upload, Popconfirm } from 'ant-design-vue'
6
+
7
+ let UploadUrl = `${global.WEBSWG}${global.BASEURL}`
8
+
9
+ export default {
10
+ name: "Button",
11
+ data() {
12
+ return {
13
+ PopconfirmProps: {
14
+ title: "确定执行此操作吗?",
15
+ okText: "确定",
16
+ cancelText: "取消",
17
+ placement: "topRight"
18
+ },
19
+ UploadProps: {
20
+ name: "file",
21
+ headers: { token: store.getters.token },
22
+ showUploadList: false
23
+ }
24
+ }
25
+ },
26
+ props: {
27
+ buttonProps: {
28
+ type: [ Array, Object ],
29
+ default: () => ({})
30
+ }
31
+ },
32
+ methods: {
33
+ UploadBtn( props ) {
34
+ const { $data: { UploadProps }, ButtonRender, UploadChange } = this
35
+ UploadProps.action = UploadUrl + props.action
36
+ return (
37
+ <Upload props={ UploadProps } {...{ on: { change: UploadChange,...props.event } }} >
38
+ { ButtonRender( props ) }
39
+ </Upload>
40
+ )
41
+ },
42
+ UploadChange({ file }) {
43
+ if(!file.hasOwnProperty('response')) return
44
+ const { code, msg } = file.response
45
+ code == 200 ?
46
+ Message.success('导入成功!'):
47
+ Message.error(msg)
48
+ Bus.$emit('ButtonUploadOver')
49
+ },
50
+ PopconfirmBtn( props ) {
51
+ const { $data: { PopconfirmProps }, ButtonRender } = this
52
+ return (
53
+ <Popconfirm props={ PopconfirmProps } {...{ on: props.event }} >
54
+ { ButtonRender( props ) }
55
+ </Popconfirm>
56
+ )
57
+ },
58
+ ButtonRender( props ) {
59
+ // const buttonEvent = props.type
60
+ return (
61
+ <Button
62
+ props={ props }
63
+ {...{ on: props.event }}
64
+ >
65
+ { props.text }
66
+ </Button>
67
+ )
68
+ },
69
+ SwitchButton( props ) {
70
+ const { PopconfirmBtn, UploadBtn, ButtonRender } = this
71
+ if( props.mode == 'popconfirm' ) return PopconfirmBtn( props )
72
+ else if( props.mode == 'upload' ) return UploadBtn( props )
73
+ return ButtonRender( props )
74
+ }
75
+ },
76
+ render() {
77
+ const { buttonProps, SwitchButton } = this
78
+ // console.log( buttonProps.constructor === Array )
79
+
80
+ return (
81
+ <div class='ButtonDiversity'>
82
+ { buttonProps.constructor === Array ? (
83
+ buttonProps.map( props => {
84
+ return SwitchButton( props )
85
+ })
86
+ ) : ( SwitchButton( buttonProps ) ) }
87
+ </div>
88
+ )
89
+ }
90
+ }
@@ -0,0 +1,166 @@
1
+ <template>
2
+
3
+ <FormModel :model="searchForm" ref="searchForm" layout="inline" @submit="handleSearch" class="AformSearch">
4
+
5
+ <FormModelItem
6
+ :key="i"
7
+ :prop="node.model"
8
+ :label="node.label"
9
+ :style="getFormWidth(node, matchMediaSize)"
10
+ v-for="(node,i) in formSetting.slice(0,count)"
11
+ >
12
+
13
+ <component
14
+ v-on="node.event"
15
+ v-bind="node.attrs"
16
+ :is="node.is || 'Input'"
17
+ :placeholder='node.is | defaultPlaceholder'
18
+ v-model="searchForm[node.model]"
19
+ />
20
+
21
+ </FormModelItem>
22
+
23
+ <div class="FormActions">
24
+ <Button type="primary" html-type="submit" >搜索</Button>
25
+ <Button :style="{ marginLeft: '8px' }" @click="handleReset">重置</Button>
26
+ <a @click="advanced = !advanced" style="margin-left: 8px" v-if="formSetting.length > 3">
27
+ {{ advanced ? '收起' : '展开' }}
28
+ <a-icon :type="advanced ? 'up' : 'down'"/>
29
+ </a>
30
+ </div>
31
+
32
+ </FormModel>
33
+
34
+ </template>
35
+ <script>
36
+
37
+ import { FormModel,Button,Radio,Input,InputNumber,Checkbox,DatePicker,TimePicker } from 'ant-design-vue'
38
+
39
+ export default {
40
+ components: {
41
+ FormModel,
42
+ FormModelItem: FormModel.Item,
43
+ Button,
44
+ Radio,
45
+ Input,
46
+ InputNumber,
47
+ Checkbox,
48
+ DatePicker,
49
+ TimePicker,
50
+ ASelectCustom: () => import('./components/form-select-custom')
51
+ },
52
+ data() {
53
+ return {
54
+ advanced: false,
55
+ matchMediaSize: 0
56
+ }
57
+ },
58
+ props: {
59
+ value: {
60
+ type: Object,
61
+ default: () => ({})
62
+ },
63
+ layoutSize: {
64
+ type: Number,
65
+ default: 4,
66
+ validator: (value) => {
67
+ return value <= 4
68
+ }
69
+ },
70
+ formSetting: {
71
+ type: Array,
72
+ default: () => ([])
73
+ },
74
+ // 紧凑型和宽松型
75
+ // default 宽松型
76
+ // middle 紧凑型
77
+ searchStyle: {
78
+ type: String,
79
+ default: 'default'
80
+ }
81
+ },
82
+ computed: {
83
+ matchMedia() {
84
+ return {
85
+ "(max-width: 576px)": 1,
86
+ "(min-width: 576px) and (max-width: 992px)": this.layoutSize - 2,
87
+ "(min-width: 992px)": this.layoutSize
88
+ }
89
+ },
90
+ count() {
91
+ return this.advanced ? this.formSetting.length : 3
92
+ },
93
+ searchForm: {
94
+ get() {
95
+ return this.value
96
+ },
97
+ set(newValue) {
98
+ this.$emit('input', newValue)
99
+ }
100
+ }
101
+ },
102
+ filters: {
103
+ defaultPlaceholder( is ) {
104
+ if( is && is.includes( 'range' ) ) return [ '开始时间', '结束时间' ]
105
+ return /(select|picker|radio|upload)/.test(is) ? "请选择" : "请输入"
106
+ }
107
+ },
108
+ mounted() {
109
+ this.matchMediaSize = this.layoutSize
110
+ Object.keys(this.matchMedia).forEach( media =>
111
+ window.matchMedia(media).addEventListener('change', this.handleResize) )
112
+ },
113
+ methods: {
114
+ handleResize(x) {
115
+ x.matches && ( this.matchMediaSize = this.matchMedia[x.media] )
116
+ },
117
+ getFormWidth(e) {
118
+ const gap = {
119
+ middle: '16px',
120
+ default: '24px'
121
+ }
122
+ return `flex: 0 1 calc((${( 100 / this.matchMediaSize ) * ( e.size ?? 1 )}% - ${gap[this.searchStyle]})); margin-right: ${gap[this.searchStyle]};`
123
+ },
124
+ handleSearch(e) {
125
+ e.preventDefault()
126
+ this.$emit('formSearch', this.searchForm)
127
+ },
128
+ handleReset() {
129
+ this.$refs.searchForm.resetFields()
130
+ this.$emit('formReset')
131
+ }
132
+ }
133
+ }
134
+ </script>
135
+ <style lang="less" scoped>
136
+ .AformSearch {
137
+ .flex-mixins(@justify: flex-start);
138
+
139
+ .ant-form-item {
140
+ display: inline-flex;
141
+ margin-right: unset;
142
+
143
+ :deep( .ant-form-item-label ) {
144
+ min-width: 70px;
145
+ max-width: 85px;
146
+ text-align: right;
147
+ }
148
+
149
+ :deep( .ant-form-item-control-wrapper ) {
150
+ flex: 1;
151
+ }
152
+
153
+ :deep(.ant-select),
154
+ :deep(.ant-input-number),
155
+ :deep(.ant-calendar-picker) {
156
+ width: 100% !important;
157
+ }
158
+ }
159
+
160
+ .FormActions {
161
+ flex: 1;
162
+ text-align: right;
163
+ margin-right: 16px;
164
+ }
165
+ }
166
+ </style>
@@ -0,0 +1,214 @@
1
+ <template>
2
+ <div :class="[tableStyle, 'publicTable']">
3
+ <Table
4
+ :size="tableSize"
5
+ v-bind="$attrs"
6
+ v-on="$listeners"
7
+ :data-source="datas"
8
+ :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
9
+ :rowKey="(record, i) => record.id ?? i"
10
+ :pagination="false"
11
+ :locale="locale"
12
+ class="tableDeploy"
13
+ >
14
+ <div class="tableTitle" slot="title">
15
+ <slot name="tableTitle" />
16
+ <div class="tableOperate">
17
+ <slot name="ActionsButton" />
18
+ <!-- <Button :buttonProps="tableButtonSet" class="tableButtonOperate" v-if="tableButtonSet?.length" /> -->
19
+ </div>
20
+ </div>
21
+
22
+ <template v-for="{ dataIndex } in $attrs.columns" #[dataIndex]>
23
+ <!-- 自定义头部渲染 -->
24
+ <slot :name="dataIndex" />
25
+ </template>
26
+
27
+ <template #customRender="text, record, i, column">
28
+ <slot :name="column.dataIndex" :customProps="record" :text="text" :index="i" />
29
+ </template>
30
+ </Table>
31
+
32
+ <Pagination
33
+ class="pagination"
34
+ size="small"
35
+ :pageSizeOptions="pageSizeOptions"
36
+ :show-total="total => `共 ${total} 条记录`"
37
+ show-size-changer
38
+ show-quick-jumper
39
+ :defaultCurrent="1"
40
+ :pageSize.sync="pagination.size"
41
+ :current="pagination.current"
42
+ @showSizeChange="paginationChange"
43
+ @change="paginationChange"
44
+ :total="pagination.total"
45
+ />
46
+
47
+ </div>
48
+ </template>
49
+
50
+ <script>
51
+
52
+ // import Bus from './Bus'
53
+ // import Button from '../Button'
54
+
55
+ // import API from '@/api/api_publicGlobal'
56
+
57
+ import { Table, Pagination } from 'ant-design-vue'
58
+
59
+ // import { downLoadFn } from '@/utils/public'
60
+
61
+ const setTips = {
62
+ Delete: '删除',
63
+ Deletes: '批量删除',
64
+ Export: '导出',
65
+ Import: '导入',
66
+ Template: '下载模板'
67
+ }
68
+
69
+ export default {
70
+ components: {
71
+ Table,
72
+ // Button,
73
+ Pagination,
74
+ // formSearch: () => import('@/components/public-form/formSearch')
75
+ },
76
+ name: 'UTable',
77
+ data() {
78
+ return {
79
+ selectedRowKeys: [],
80
+ datas: [],
81
+ locale: {
82
+ emptyText: <div class="tableEmpty">
83
+ <span>暂无数据</span>
84
+ </div>
85
+ },
86
+ AnimateReload: false,
87
+ pagination: {
88
+ total: 0,
89
+ size: 10,
90
+ current: 1
91
+ },
92
+ searchForm: {}
93
+ }
94
+ },
95
+ props: {
96
+ // 紧凑型和宽松型
97
+ // relax 宽松型
98
+ // compact 紧凑型
99
+ tableStyle: {
100
+ type: String,
101
+ default: 'compact'
102
+ },
103
+ // compact 紧凑型情况下是否有分割线
104
+ tableSplit: {
105
+ type: Boolean,
106
+ default: true
107
+ },
108
+ // 配置分页数据
109
+ pageSizeOptions: {
110
+ type: Array,
111
+ default: () => ['10', '15', '20', '30', '50']
112
+ },
113
+ tableCallback: Function,
114
+ // 配置查询表格URL 适用场景:没有search或者不需处理search结果的情景
115
+ tablePageUrl: String,
116
+ // 配置除tableButtonSet之外的操作按钮
117
+ tableOperateProps: [Array, Object],
118
+ // 配置导入、导出、下载模板、批量删除地址URL,根据配置结果来匹配按钮
119
+ tableButtonSetUrl: {
120
+ type: Object,
121
+ default: () => ({})
122
+ }
123
+ },
124
+ computed: {
125
+ tableSize() {
126
+ return this.tableStyle == 'compact' ? 'middle' : 'default'
127
+ },
128
+ tableButtonSet() {
129
+ let tableButtonSet = []
130
+ const setActions = {
131
+ Deletes: {
132
+ type: 'danger',
133
+ mode: 'popconfirm',
134
+ event: { confirm: () => this.tableActionsSet('Deletes') }
135
+ },
136
+ Export: { event: { click: () => this.tableActionsSet('Export') } },
137
+ Import: { mode: 'upload', action: this.tableButtonSetUrl.Import },
138
+ Template: { event: { click: () => this.tableActionsSet('Template') } }
139
+ }
140
+ Object.keys(setActions).forEach(action => {
141
+ if (this.tableButtonSetUrl.hasOwnProperty(action)) tableButtonSet.push({ text: setTips[action], ...setActions[action] })
142
+ })
143
+ this.tableOperateProps &&
144
+ (this.tableOperateProps.constructor === Array ? (tableButtonSet = [].concat(this.tableOperateProps, tableButtonSet)) : tableButtonSet.unshift(this.tableOperateProps))
145
+ return tableButtonSet
146
+ }
147
+ },
148
+ watch: {
149
+ // tableButtonSetUrl(){
150
+ // this.tableButtonSetType()
151
+ // }
152
+ '$attrs.formDefault': {
153
+ handler(e) {
154
+ this.searchForm = { ...e }
155
+ },
156
+ deep: true
157
+ }
158
+ },
159
+ mounted() {
160
+ // Bus.$on('ButtonUploadOver', () => this.queryTableList())
161
+ // this.$global.AModal_bus.$on('changeTableOperateProps', e => this.tableOperateProps = e)
162
+ // Bus.$on('tableActionsSet', (method, params) => this.tableActionsSet(method, params))
163
+ !this.$attrs.formSetting && this.queryTableList()
164
+ // this.tableButtonSetType()
165
+ },
166
+ methods: {
167
+ onSelectChange(selectedKey, selectedRecord) {
168
+ this.selectedRowKeys = selectedKey
169
+ this.$emit('selectedRecords', selectedRecord)
170
+ },
171
+ paginationChange(current, pageSize) {
172
+ this.pagination.size = pageSize
173
+ this.pagination.current = current
174
+ this.queryTableList()
175
+ },
176
+ tableToRefresh() {
177
+ this.queryTableList()
178
+ this.AnimateReload = true
179
+ setTimeout(() => (this.AnimateReload = false), 2000)
180
+ },
181
+ tableButtonSetType() {
182
+ let { tableButtonSetUrl, tableDefaultActions, tableOperateProps } = this
183
+ let tableButtonSet = tableDefaultActions.filter(action => Object.keys(tableButtonSetUrl).includes(action.method))
184
+ tableOperateProps && (tableOperateProps === Array ? (tableButtonSet = tableOperateProps.concat(tableButtonSet)) : tableButtonSet.unshift(tableOperateProps))
185
+ this.tableButtonSet = tableButtonSet
186
+ },
187
+ tableActionsSet(method, params = {}) {
188
+ // method为实际操作方法名称标识
189
+ // params为传参
190
+ const IsHasCheck = ['Export', 'Deletes'].includes(method)
191
+ let queryParams = IsHasCheck ? this.selectedRowKeys : params
192
+ if (IsHasCheck && !this.selectedRowKeys?.length) return this.$message.error('请先选择数据!')
193
+ // API[`tableSet${method}`](this.tableButtonSetUrl[method], queryParams).then(Response => {
194
+ // if (Response && Response.hasOwnProperty('headers')) {
195
+ // const i = Response.headers['content-disposition'].indexOf('%')
196
+ // // downLoadFn(Response.response, decodeURI(Response.headers['content-disposition'].slice(i)))
197
+ // }
198
+ // this.$message.success(`${setTips[method]}成功!`)
199
+ // this.queryTableList()
200
+ // })
201
+ },
202
+ async queryTableList() {
203
+ const params = { ...this.pagination, ...this.searchForm }
204
+ let request = this.tableCallback
205
+ // let request = this.tableCallback ?? API.queryTableList
206
+ await request(params, this.tablePageUrl).then(({ records, total }) => ((this.datas = records), this.$set(this.pagination, 'total', total)))
207
+ }
208
+ }
209
+ }
210
+ </script>
211
+
212
+ <style lang="less" scoped>
213
+ // @import url('../less/Table.less');
214
+ </style>
@@ -0,0 +1,7 @@
1
+ import Table from './Table.vue'
2
+
3
+ Table.install = function (Vue) {
4
+ Vue.component(Table.name, Table)
5
+ }
6
+
7
+ export default Table
@@ -0,0 +1,17 @@
1
+ // 将组件库中定义的所有组件引入并导出
2
+ import Table from './Table'
3
+
4
+ const components = {
5
+ Table
6
+ }
7
+
8
+ const install = function (Vue) {
9
+ if (install.installed) return
10
+ Object.keys(components).forEach(component => {
11
+ Vue.component(components[component].name, components[component])
12
+ })
13
+ }
14
+
15
+ export default {
16
+ install
17
+ }