Commit 303ef68882af7d8e6b235acc89b0447735476d57

Authored by 刘汉宸
1 parent bffb3d99

feat: 优化SchemaTransfer

.env
1 1 # 版本号
2   -VUE_APP_VERSION = '2.0.0.alpha.9'
  2 +VUE_APP_VERSION = '2.0.0.alpha.12'
3 3 # 自定义变量 Cookie失效时间 1天
4 4 VUE_APP_NAME = 'Zee'
5 5 \ No newline at end of file
... ...
examples/views/docs/component/schema-transfer.md
... ... @@ -100,11 +100,86 @@ export default {
100 100  
101 101 可以单独配置已选中的表格
102 102  
103   -::: snippet `schema`中设置`selected`,格式与`z-schema-table`相同
  103 +::: snippet `schema`中设置`selected`,配置与`SchemaTable`相同。其中已选中项的表格字段可以与数据源不同,设置`choose-formatter`改变选择的数据格式
104 104  
105 105 ```html
106 106 <template>
107   - <z-schema-transfer v-model="model" :schema="schema" :source="source" value-key="id" size="small"></z-schema-transfer>
  107 + <z-schema-transfer v-model="model" :schema="schema" :source="source" value-key="id" size="small" :choose-formatter="chooseFormatter"></z-schema-transfer>
  108 +</template>
  109 +
  110 +<script>
  111 +export default {
  112 + data() {
  113 + return {
  114 + model: [],
  115 + source: [
  116 + { id: '0', name: '姓名0', age: 17 },
  117 + { id: '1', name: '姓名1', age: 26 },
  118 + ],
  119 + schema: {
  120 + table: {
  121 + items: [
  122 + { label: '姓名', prop: 'name', minWidth: 120 },
  123 + { label: '年龄', prop: 'age', minWidth: 120 },
  124 + { label: '地址', prop: 'address', minWidth: 120 },
  125 + ]
  126 + },
  127 + selected: {
  128 + props: { border: true, editable: true },
  129 + items: [
  130 + { label: '姓名', prop: 'name', minWidth: 120, editable: false },
  131 + { label: '性别', prop: 'gender', minWidth: 120, editable: false },
  132 + { label: '民族', prop: 'ethnicity', minWidth: 120, editalways: true },
  133 + ]
  134 + }
  135 + },
  136 + }
  137 + },
  138 + methods: {
  139 + chooseFormatter(row) {
  140 + return { id: row.id, name: row.name, gender: '男', ethnicity: '汉' };
  141 + }
  142 + }
  143 +}
  144 +</script>
  145 +```
  146 +
  147 +:::
  148 +
  149 +## 自定义插槽
  150 +
  151 +同其他组件一样,可以对部分内容设置插槽
  152 +
  153 +::: snippet 左侧插槽格式默认与`SchemaPage`组件相同,已选中表格的插槽以`selected-`开头
  154 +
  155 +```html
  156 +<template>
  157 + <z-schema-transfer v-model="model" :schema="schema" :source="source" value-key="id" size="small">
  158 + <template #table-cell-name="{ value, size }">
  159 + <el-tag :size="size">{{ value }}</el-tag>
  160 + </template>
  161 + <template #operation="{ choose }">
  162 + <el-table-column label="新操作" width="80" align="center" fixed="right">
  163 + <template #default="{ row, $index }">
  164 + <div class="z-schema-page__table-operation">
  165 + <el-button size="mini" @click="choose(row)">选中</el-button>
  166 + </div>
  167 + </template>
  168 + </el-table-column>
  169 + </template>
  170 + <template #selected-cell-name="{ value, size }">
  171 + <el-tag :size="size" type="success">{{ value }}</el-tag>
  172 + </template>
  173 + <template #selected-operation="{ remove }">
  174 + <el-table-column label="新操作" width="80" align="center" fixed="right">
  175 + <template #default="{ row, $index }">
  176 + <div class="z-schema-page__table-operation">
  177 + <el-button size="mini" @click="remove(row)">移除</el-button>
  178 + </div>
  179 + </template>
  180 + </el-table-column>
  181 + </template>
  182 + </z-schema-transfer>
108 183 </template>
109 184  
110 185 <script>
... ... @@ -151,15 +226,15 @@ export default {
151 226 <template>
152 227 <z-schema-transfer v-model="model" :schema="schema" :source="source" value-key="id" size="small">
153 228 <template #title-left>未选择 <i class="el-icon-minus"></i></template>
154   - <template #default="{ onChoose, valueFormatter }">
  229 + <template #default="{ choose, deselect }">
155 230 <div>
156   - <el-button size="mini" v-for="item in valueFormatter(source)" @click="onChoose(item)">{{ item.name }}</el-button>
  231 + <el-button size="mini" v-for="item in deselect(source)" @click="choose(item)">{{ item.name }}</el-button>
157 232 </div>
158 233 </template>
159 234 <template #title-right>已选择 <i class="el-icon-check"></i></template>
160   - <template #selected="{ onRemove }">
  235 + <template #selected="{ remove }">
161 236 <div>
162   - <el-button size="mini" v-for="item in model" @click="onRemove(item)">{{ item.name }}</el-button>
  237 + <el-button size="mini" v-for="item in model" @click="remove(item)">{{ item.name }}</el-button>
163 238 </div>
164 239 </template>
165 240 </z-schema-transfer>
... ...
packages/schema-transfer/index.vue
... ... @@ -29,11 +29,11 @@
29 29 <div class="z-schema-transfer__left">
30 30 <div class="z-schema-transfer__header">
31 31 <div class="z-schema-transfer__title">
32   - <slot name="title-left">{{ titles[0] }}</slot>
  32 + <slot name="title-left" v-bind="_slotScope">{{ titles[0] }}</slot>
33 33 </div>
34 34 </div>
35 35 <div class="z-schema-transfer__content">
36   - <slot :onChoose="onChoose" :valueFormatter="valueFormatter">
  36 + <slot v-bind="_slotScope">
37 37 <z-schema-page
38 38 :size="transferSize"
39 39 :value-filter="valueFilter"
... ... @@ -43,14 +43,19 @@
43 43 @update:value-filter="e => $emit('update:value-filter', e)"
44 44 :auto="auto"
45 45 >
  46 + <template v-for="item in getSlotKeys('table-')" #[item.name]="slotScope">
  47 + <slot :name="item.slot" v-bind="{ ..._slotScope, ...slotScope }"></slot>
  48 + </template>
46 49 <template #operation>
47   - <el-table-column label="操作" width="80" align="center" fixed="right">
48   - <template #default="{ row, $index }">
49   - <div class="z-schema-page__table-operation">
50   - <el-button type="text" :disabled="_rowDisabled(row, $index)" @click="onChoose(row)">选择</el-button>
51   - </div>
52   - </template>
53   - </el-table-column>
  50 + <slot name="operation" v-bind="_slotScope">
  51 + <el-table-column label="操作" width="80" align="center" fixed="right">
  52 + <template #default="{ row, $index }">
  53 + <div class="z-schema-page__table-operation">
  54 + <el-button type="text" :disabled="_rowDisabled(row, $index)" @click="onChoose(row)">选择</el-button>
  55 + </div>
  56 + </template>
  57 + </el-table-column>
  58 + </slot>
54 59 </template>
55 60 </z-schema-page>
56 61 </slot>
... ... @@ -63,15 +68,20 @@
63 68 </div>
64 69 </div>
65 70 <div class="z-schema-transfer__content">
66   - <slot name="selected" :onRemove="onRemove">
  71 + <slot name="selected" v-bind="_slotScope">
67 72 <z-schema-table :size="transferSize" :value="value" :schema="schemaRight" @input="onInput">
68   - <el-table-column label="操作" width="80" align="center" fixed="right">
69   - <template #default="{ row, $index }">
70   - <div class="z-schema-page__table-operation">
71   - <el-button type="text" :disabled="_rowDisabled(row, $index)" @click="onRemove(row, $index)">移除</el-button>
72   - </div>
73   - </template>
74   - </el-table-column>
  73 + <template v-for="item in getSlotKeys('selected-', true)" #[item.name]="slotScope">
  74 + <slot :name="item.slot" v-bind="{ ..._slotScope, ...slotScope }"></slot>
  75 + </template>
  76 + <slot name="selected-operation" v-bind="_slotScope">
  77 + <el-table-column label="操作" width="80" align="center" fixed="right">
  78 + <template #default="{ row, $index }">
  79 + <div class="z-schema-page__table-operation">
  80 + <el-button type="text" :disabled="_rowDisabled(row, $index)" @click="onRemove(row, $index)">移除</el-button>
  81 + </div>
  82 + </template>
  83 + </el-table-column>
  84 + </slot>
75 85 </z-schema-table>
76 86 </slot>
77 87 </div>
... ... @@ -114,6 +124,7 @@ export default {
114 124 auto: Boolean,
115 125 rowDisabled: Function,
116 126 apiSearch: Function,
  127 + chooseFormatter: Function,
117 128 valueFilter: {
118 129 type: Object,
119 130 default() {
... ... @@ -186,10 +197,37 @@ export default {
186 197 return this.value.map(item => item[this.valueKey]);
187 198 },
188 199 valueTable() {
189   - return this.valueFormatter(this.dataSource || []);
  200 + return this.deselect(this.dataSource || []);
  201 + },
  202 + slotKeys() {
  203 + return Object.keys(this.$scopedSlots);
  204 + },
  205 + _slotScope() {
  206 + const methods = ['deselect'];
  207 + const defaultScope = {
  208 + size: this.transferSize,
  209 + disabled: this.transferDisabled,
  210 + choose: this.onChoose,
  211 + remove: this.onRemove,
  212 + };
  213 + return [...methods].reduce((result, current) => {
  214 + result[current] = this[current];
  215 + return result;
  216 + }, defaultScope);
190 217 },
191 218 },
192 219 methods: {
  220 + getSlotKeys(prefix, fixed) {
  221 + return this.slotKeys.reduce((result, current) => {
  222 + if (current.indexOf(prefix) === 0) {
  223 + result.push({
  224 + slot: current,
  225 + name: fixed ? current.substring(prefix.length) : current,
  226 + });
  227 + }
  228 + return result;
  229 + }, []);
  230 + },
193 231 _rowDisabled(row, index) {
194 232 if (this.transferDisabled) {
195 233 return true;
... ... @@ -199,11 +237,15 @@ export default {
199 237 }
200 238 return false;
201 239 },
202   - valueFormatter(value) {
  240 + deselect(value) {
203 241 return value.filter(item => !this.valueKeys.includes(item[this.valueKey]));
204 242 },
205 243 onChoose(row) {
206   - this.$emit('input', [...this.value, row]);
  244 + let newRow = cloneDeep(row);
  245 + if (this.chooseFormatter) {
  246 + newRow = this.chooseFormatter(newRow);
  247 + }
  248 + this.$emit('input', [...this.value, newRow]);
207 249 },
208 250 onRemove(row, index) {
209 251 const newValue = cloneDeep(this.value || []);
... ...