ソースを参照

Autocomplete: add value-key (#7671)

* Autocomplete: add value-key

* fix autocomplete test
杨奕 7 年 前
コミット
4517e3d9be

+ 18 - 0
build/deploy-faas.sh

@@ -0,0 +1,18 @@
+#! /bin/sh
+mkdir temp_web
+npm run deploy:build
+cd temp_web
+git clone -b gh-pages https://github.com/ElemeFE/element.git && cd element
+
+# build sub folder
+SUB_FOLDER='2.0'
+mkdir $SUB_FOLDER
+# rm -rf *.js *.css *.map static
+rm -rf $SUB_FOLDER/**
+# cp -rf ../../examples/element-ui/** .
+cp -rf ../../examples/element-ui/** $SUB_FOLDER/
+cp -rf ../../examples/element-ui/versions.json .
+cd ../..
+
+# deploy domestic site
+faas deploy alpha

+ 1 - 1
build/release.sh

@@ -16,7 +16,7 @@ then
   echo "Releasing theme-chalk $VERSION ..."
   cd packages/theme-chalk
   npm version $VERSION --message "[release] $VERSION"
-  npm publish --tag next
+  npm publish
   cd ../..
 
   # commit

+ 1 - 0
examples/components/footer.vue

@@ -50,6 +50,7 @@
 
     .container {
       box-sizing: border-box;
+      width: auto;
     }
 
     .footer-main {

+ 1 - 7
examples/docs/en-US/input.md

@@ -657,7 +657,7 @@ Attribute | Description | Type | Options | Default
 |----| ----| ----| ---- | -----|
 |placeholder| the placeholder of Autocomplete| string | — | — |
 |disabled | whether Autocomplete is disabled  | boolean | — | false|
-| props | configuration options, see the following table | object | — | — |
+| valueKey | key name of the input suggestion object for display | string | — | value |
 |icon | icon name | string | — | — |
 |value | binding value | string | — | — |
 | debounce | debounce delay when typing, in milliseconds | number | — | 300 |
@@ -669,12 +669,6 @@ Attribute | Description | Type | Options | Default
 | select-when-unmatched | whether to emit a `select` event on enter when there is no autocomplete match | boolean | — | false |
 | label | label text | string | — | — |
 
-### props
-| Attribute | Description | Type | Accepted Values | Default |
-| --------- | ----------------- | ------ | ------ | ------ |
-| label     | specify which key of option object is used as the option's label | string | — | value |
-| value     | specify which key of option object is used as the option's value | string | — | value |
-
 ### Autocomplete slots
 
 | Name | Description |

+ 24 - 25
examples/docs/en-US/tree.md

@@ -232,18 +232,19 @@
       resetChecked() {
         this.$refs.tree.setCheckedKeys([]);
       },
-      append(store, data) {
+      append(data) {
         const newChild = { id: id++, label: 'testtest', children: [] };
-        store.append(newChild, data);
-        data.children = data.children || [];
+        if (!data.children) {
+          this.$set(data, 'children', []);
+        }
         data.children.push(newChild);
       },
 
-      remove(store, node, data) {
+      remove(node, data) {
         const parent = node.parent;
-        const index = parent.data.children.findIndex(d => d.id === data.id);
-        parent.data.children.splice(index, 1);
-        store.remove(data);
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
       },
 
       renderContent(h, { node, data, store }) {
@@ -253,8 +254,8 @@
               <span>{node.label}</span>
             </span>
             <span>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(store, data) }>Append</el-button>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(store, node, data) }>Delete</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(data) }>Append</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
             </span>
           </span>);
       },
@@ -270,6 +271,7 @@
         data,
         data2,
         data3,
+        data4: JSON.parse(JSON.stringify(data2)),
         regions,
         defaultProps,
         props,
@@ -683,14 +685,10 @@ Tree nodes can be initially expanded or checked
 ### Custom node content
 The content of tree nodes can be customized, so you can add icons or buttons as you will
 
-:::warning
-`Append` and `remove` do not change `data`
-:::
-
 ::: demo Use `render-content` to assign a render function that returns the content of tree nodes. See Vue's documentation for a detailed introduction of render functions. Note that this demo can't run in jsfiddle because it doesn't support JSX syntax. In a real project, `render-content` will work if relevant dependencies are correctly configured.
 ```html
 <el-tree
-  :data="data2"
+  :data="data4"
   :props="defaultProps"
   show-checkbox
   node-key="id"
@@ -705,7 +703,7 @@ The content of tree nodes can be customized, so you can add icons or buttons as
   export default {
     data() {
       return {
-        data2: [{
+        data4: [{
           id: 1,
           label: 'Level one 1',
           children: [{
@@ -748,18 +746,19 @@ The content of tree nodes can be customized, so you can add icons or buttons as
     },
 
     methods: {
-      append(store, data) {
+      append(data) {
         const newChild = { id: id++, label: 'testtest', children: [] };
-        store.append(newChild, data); // need change data by yourself
-        data.children = data.children || [];
+        if (!data.children) {
+          this.$set(data, 'children', []);
+        }
         data.children.push(newChild);
       },
 
-      remove(store, node, data) {
+      remove(node, data) {
         const parent = node.parent;
-        const index = parent.data.children.findIndex(d => d.id === data.id);
-        parent.data.children.splice(index, 1);
-        store.remove(data); // need change data by yourself
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
       },
 
       renderContent(h, { node, data, store }) {
@@ -769,8 +768,8 @@ The content of tree nodes can be customized, so you can add icons or buttons as
               <span>{node.label}</span>
             </span>
             <span>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(store, data) }>Append</el-button>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(store, node, data) }>Delete</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(data) }>Append</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
             </span>
           </span>);
       }
@@ -939,7 +938,7 @@ Only one node among the same level can be expanded at one time.
 | node-key              | unique identity key name for nodes, its value should be unique across the whole tree | string                      | —               | —       |
 | props                 | configuration options, see the following table | object                      | —               | —       |
 | load                  | method for loading subtree data          | function(node, resolve)     | —               | —       |
-| render-content        | render function for tree node            | Function(h, { node }        | —               | —       |
+| render-content        | render function for tree node            | Function(h, { node, data, store }        | —               | —       |
 | highlight-current     | whether current node is highlighted      | boolean                     | —               | false   |
 | default-expand-all    | whether to expand all nodes by default   | boolean                     | —               | false   |
 | expand-on-click-node  | whether to expand or collapse node when clicking on the node, if false, then expand or collapse node only when clicking on the arrow icon. | —                           | true            |         |

+ 1 - 7
examples/docs/zh-CN/input.md

@@ -816,7 +816,7 @@ export default {
 |-------------  |---------------- |---------------- |---------------------- |-------- |
 | placeholder   | 输入框占位文本   | string          | — | — |
 | disabled      | 禁用            | boolean         | — | false   |
-| props | 配置选项,具体见下表 | object | — | — |
+| valueKey | 输入建议对象中用于显示的键名 | string | — | value |
 | value         | 必填值,输入绑定值   | string  | — | — |
 | debounce      | 获取输入建议的去抖延时 | number         | — | 300 |
 | fetch-suggestions | 返回输入建议的方法,仅当你的输入建议数据 resolve 时,通过调用 callback(data:[]) 来返回它  | Function(queryString, callback)  | — | — |
@@ -826,12 +826,6 @@ export default {
 | select-when-unmatched | 在输入没有任何匹配建议的情况下,按下回车是否触发 `select` 事件 | boolean | — | false |
 | label | 输入框关联的label文字 | string | — | — |
 
-### props
-| 参数     | 说明              | 类型   | 可选值 | 默认值 |
-| -------- | ----------------- | ------ | ------ | ------ |
-| value    | 指定选项的值为选项对象的某个属性值 | string | — | value |
-| label    | 指定选项标签为选项对象的某个属性值 | string | — | value |
-
 ### Autocomplete slots
 | name | 说明 |
 |------|--------|

+ 25 - 26
examples/docs/zh-CN/tree.md

@@ -232,29 +232,30 @@
       resetChecked() {
         this.$refs.tree.setCheckedKeys([]);
       },
-      append(store, data) {
+      append(data) {
         const newChild = { id: id++, label: 'testtest', children: [] };
-        store.append(newChild, data);
-        data.children = data.children || [];
+        if (!data.children) {
+          this.$set(data, 'children', []);
+        }
         data.children.push(newChild);
       },
 
-      remove(store, node, data) {
+      remove(node, data) {
         const parent = node.parent;
-        const index = parent.data.children.findIndex(d => d.id === data.id);
-        parent.data.children.splice(index, 1);
-        store.remove(data);
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
       },
 
-      renderContent(h, { node, data, store }) {
+      renderContent(h, { node, data }) {
         return (
           <span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;">
             <span>
               <span>{node.label}</span>
             </span>
             <span>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(store, data) }>Append</el-button>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(store, node, data) }>Delete</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(data) }>Append</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
             </span>
           </span>);
       },
@@ -270,6 +271,7 @@
         data,
         data2,
         data3,
+        data4: JSON.parse(JSON.stringify(data2)),
         regions,
         defaultProps,
         props,
@@ -682,14 +684,10 @@
 ### 自定义节点内容
 节点的内容支持自定义,可以在节点区添加按钮或图标等内容
 
-:::warning
-`append` 和 `remove` 方法不会改变 `data` 上的数据
-:::
-
 ::: demo 使用`render-content`指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。注意:由于 jsfiddle 不支持 JSX 语法,所以本例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。
 ```html
 <el-tree
-  :data="data2"
+  :data="data4"
   :props="defaultProps"
   show-checkbox
   node-key="id"
@@ -704,7 +702,7 @@
   export default {
     data() {
       return {
-        data2: [{
+        data4: [{
           id: 1,
           label: '一级 1',
           children: [{
@@ -747,18 +745,19 @@
     },
 
     methods: {
-      append(store, data) {
+      append(data) {
         const newChild = { id: id++, label: 'testtest', children: [] };
-        store.append(newChild, data); // append 不会改变 data
-        data.children = data.children || [];
+        if (!data.children) {
+          this.$set(data, 'children', []);
+        }
         data.children.push(newChild);
       },
 
-      remove(store, node, data) {
+      remove(node, data) {
         const parent = node.parent;
-        const index = parent.data.children.findIndex(d => d.id === data.id);
-        parent.data.children.splice(index, 1);
-        store.remove(data); // remove 不会改变 data
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
       },
 
       renderContent(h, { node, data, store }) {
@@ -768,8 +767,8 @@
               <span>{node.label}</span>
             </span>
             <span>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(store, data) }>Append</el-button>
-              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(store, node, data) }>Delete</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.append(data) }>Append</el-button>
+              <el-button style="font-size: 12px;" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
             </span>
           </span>);
       }
@@ -938,7 +937,7 @@
 | node-key              | 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的               | String                      | —    | —     |
 | props                 | 配置选项,具体看下表                               | object                      | —    | —     |
 | load                  | 加载子树数据的方法                                | function(node, resolve)     | —    | —     |
-| render-content        | 树节点的内容区的渲染 Function                      | Function(h, { node }        | —    | —     |
+| render-content        | 树节点的内容区的渲染 Function                      | Function(h, { node, data, store }        | —    | —     |
 | highlight-current     | 是否高亮当前选中节点,默认值是 false。                   | boolean                     | —    | false |
 | default-expand-all    | 是否默认展开所有节点                               | boolean                     | —    | false |
 | expand-on-click-node  | 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。 | boolean                     | —    | true  |

+ 0 - 1
examples/pages/template/index.tpl

@@ -23,7 +23,6 @@
     width: 890px;
     height: 465px;
     margin: 30px auto 100px;
-    /*border: solid 1px black;*/
     position: relative;
 
     div {

+ 2 - 2
package.json

@@ -25,14 +25,14 @@
     "dist:all": "node build/bin/build-all.js && npm run build:theme",
     "i18n": "node build/bin/i18n.js",
     "lint": "eslint src/**/* test/**/* packages/**/*.{js,vue} build/**/* --quiet",
-    "pub": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js",
+    "pub": "npm run bootstrap && sh build/git-release.sh && sh build/release.sh && node build/bin/gen-indices.js && sh build/deploy-faas.sh",
     "pub:all": "npm run dist:all && lerna publish --skip-git && git commit -am 'publish independent packages' && git push eleme dev",
     "test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ karma start test/unit/karma.conf.js --single-run",
     "test:watch": "npm run build:theme && karma start test/unit/karma.conf.js"
   },
   "faas": {
     "domain": "element",
-    "public": "examples/element-ui"
+    "public": "temp_web/element"
   },
   "repository": {
     "type": "git",

+ 7 - 11
packages/autocomplete/src/autocomplete.vue

@@ -51,7 +51,7 @@
         :aria-selected="highlightedIndex === index"
       >
         <slot :item="item">
-          {{ item[props.label] }}
+          {{ item[valueKey] }}
         </slot>
       </li>
     </el-autocomplete-suggestions>
@@ -82,14 +82,9 @@
     directives: { Clickoutside },
 
     props: {
-      props: {
-        type: Object,
-        default() {
-          return {
-            label: 'value',
-            value: 'value'
-          };
-        }
+      valueKey: {
+        type: String,
+        default: 'value'
       },
       popperClass: String,
       placeholder: String,
@@ -142,7 +137,8 @@
       getMigratingConfig() {
         return {
           props: {
-            'custom-item': 'custom-item is removed, use scoped slot intstead.'
+            'custom-item': 'custom-item is removed, use scoped slot instead.',
+            'props': 'props is removed, use value-key instead.'
           }
         };
       },
@@ -199,7 +195,7 @@
         }
       },
       select(item) {
-        this.$emit('input', item[this.props.label]);
+        this.$emit('input', item[this.valueKey]);
         this.$emit('select', item);
         this.$nextTick(_ => {
           this.suggestions = [];

+ 1 - 1
test/unit/specs/autocomplete.spec.js

@@ -133,7 +133,7 @@ describe('Autocomplete', () => {
         <el-autocomplete
           v-model="state"
           ref="autocomplete"
-          :props="{ label: 'address', value: 'name' }"
+          value-key="address"
           :fetch-suggestions="querySearch"
           placeholder="请输入内容autocomplete2"
         ></el-autocomplete>

+ 5 - 5
types/autocomplete.d.ts

@@ -34,14 +34,14 @@ export declare class ElAutocomplete extends ElementUIComponent {
   /** Debounce delay when typing */
   debounce: number
 
-  /** name for the inner native input */
+  /** Name for the inner native input */
   name: string
 
-  /** whether to emit select event on enter when there is no autocomplete match */
-  selectWhenUnmatched: boolean
+  /** Key name of the input suggestion object for display */
+  valueKey: string
 
-  /** Component name of your customized suggestion list item */
-  customItem: string
+  /** Whether to emit select event on enter when there is no autocomplete match */
+  selectWhenUnmatched: boolean
 
   /** A method to fetch input suggestions. When suggestions are ready, invoke callback(data:[]) to return them to Autocomplete */
   fetchSuggestions: FetchSuggestions