add select demo

pull/9/head
tjz 2018-02-25 16:48:19 +08:00
parent 64935c292f
commit 83c6483655
13 changed files with 317 additions and 45 deletions

View File

@ -0,0 +1,28 @@
<cn>
#### 自动分词
试下复制 `露西,杰克` 到输入框里。只在 tags 和 multiple 模式下可用。
</cn>
<us>
#### Automatic tokenization
Try to copy `Lucy,Jack` to the input. Only available in tags and multiple mode.
</us>
```html
<template>
<a-select mode="tags" style="width: 100%" :tokenSeparators="[',']" @change="handleChange">
<a-select-option v-for="i in 25" :key="(i + 9).toString(36) + i">{{(i + 9).toString(36) + i}}</a-select-option>
</a-select>
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(`selected ${value}`);
}
}
}
</script>
```

View File

@ -12,7 +12,7 @@ Basic Usage
```html
<template>
<div>
<a-select defaultValue="lucy" style='width: 120px' @change='handleChange'>
<a-select defaultValue="lucy" style="width: 120px" @change="handleChange">
<a-select-option value="jack">Jack</a-select-option>
<a-select-option value="lucy">Lucy</a-select-option>
<a-select-option value="disabled" disabled>Disabled</a-select-option>
@ -25,11 +25,11 @@ Basic Usage
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(`selected ${value}`);
}
methods: {
handleChange(value) {
console.log(`selected ${value}`);
}
}
}
</script>
```

View File

@ -0,0 +1,41 @@
<cn>
#### 智能提示
输入框自动完成功能,下面是一个账号注册表单的例子。
推荐使用 [AutoComplete](/components/auto-complete/) 组件。
</cn>
<us>
#### Automatic completion
Automatic completion of select input.
Using the [AutoComplete](/components/auto-complete/) component is strongly recommended instead as it is more flexible and capable.
</us>
```html
<template>
<a-select mode="combobox" style="width: 200px" @change="handleChange" :filterOption="false"
placeholder="Enter the account name">
<a-select-option v-for="opt in options" :key="opt">{{opt}}</a-select-option>
</a-select>
</template>
<script>
const domains = ['gmail.com', '163.com', 'qq.com']
export default {
data() {
return {
options: [],
}
},
methods: {
handleChange(value) {
if (!value || value.indexOf('@') >= 0) {
this.options = [];
} else {
this.options = domains.map(domain => `${value}@${domain}`)
}
}
}
}
</script>
```

View File

@ -0,0 +1,49 @@
<cn>
#### 联动
省市联动是典型的例子。
推荐使用 [Cascader](/components/cascader/) 组件。
</cn>
<us>
#### coordinate
Coordinating the selection of provinces and cities is a common use case and demonstrates how selection can be coordinated.
Using the [Cascader](/components/cascader) component is strongly recommended instead as it is more flexible and capable.
</us>
```html
<template>
<div>
<a-select :defaultValue="provinceData[0]" style="width: 120px" @change="handleProvinceChange">
<a-select-option v-for="province in provinceData" :key="province">{{province}}</a-select-option>
</a-select>
<a-select v-model="secondCity" style="width: 120px">
<a-select-option v-for="city in cities" :key="city">{{city}}</a-select-option>
</a-select>
</div>
</template>
<script>
const provinceData = ['Zhejiang', 'Jiangsu'];
const cityData = {
Zhejiang: ['Hangzhou', 'Ningbo', 'Wenzhou'],
Jiangsu: ['Nanjing', 'Suzhou', 'Zhenjiang'],
};
export default {
data() {
return {
provinceData,
cityData,
cities: cityData[provinceData[0]],
secondCity: cityData[provinceData[0]][0],
}
},
methods: {
handleProvinceChange(value) {
this.cities = cityData[value]
this.secondCity = cityData[value][0]
}
}
}
</script>
```

View File

@ -0,0 +1,31 @@
<cn>
#### 获得选项的文本
默认情况下 `onChange` 里只能拿到 value如果需要拿到选中的节点文本 label可以使用 `labelInValue` 属性。
选中项的 label 会被包装到 value 中传递给 `onChange` 等函数,此时 value 是一个对象。
</cn>
<us>
#### Get value of selected item
As a default behavior, the onChange callback can only get the value of the selected item. The labelInValue prop can be used to get the label property of the selected item.
The label of the selected item will be packed as an object for passing to the onChange callback.
</us>
```html
<template>
<a-select labelInValue :defaultValue="{ key: 'lucy' }" style="width: 120px" @change="handleChange">
<a-select-option value="jack">Jack (100)</a-select-option>
<a-select-option value="lucy">Lucy (101)</a-select-option>
</a-select>
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(value); // { key: "lucy", label: "Lucy (101)" }
}
}
}
</script>
```

View File

@ -0,0 +1,28 @@
<cn>
#### 多选
多选从已有条目中选择scroll the menu
</cn>
<us>
#### multiple selection
Multiple selection, selecting from existing items (scroll the menu).
</us>
```html
<template>
<a-select mode="multiple" :defaultValue="['a1', 'b2']" style="width: 100%" @change="handleChange" placeholder="Please select">
<a-select-option v-for="i in 25" :key="(i + 9).toString(36) + i">{{(i + 9).toString(36) + i}}</a-select-option>
</a-select>
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(`selected ${value}`);
}
}
}
</script>
```

View File

@ -0,0 +1,35 @@
<cn>
#### 分组
`OptGroup` 进行选项分组。
</cn>
<us>
#### Option Group
Using `OptGroup` to group the options.
</us>
```html
<template>
<a-select defaultValue="lucy" style="width: 200px" @change="handleChange">
<a-select-opt-group>
<span slot="label"><a-icon type="user"/>Manager</span>
<a-select-option value="jack">Jack</a-select-option>
<a-select-option value="lucy">Lucy</a-select-option>
</a-select-opt-group>
<a-select-opt-group label="Engineer">
<a-select-option value="Yiminghe">yiminghe</a-select-option>
</a-select-opt-group>
</a-select>
</template>
<script>
export default {
methods: {
handleChange(value) {
console.log(`selected ${value}`);
}
}
}
</script>
```

View File

@ -0,0 +1,83 @@
<cn>
#### 搜索框
省市联动是典型的例子。
自动补全和远程数据结合。
</cn>
<us>
#### Search Box
Autocomplete with remote ajax data.
</us>
```html
<template>
<a-select
mode="combobox"
:value="value"
placeholder="input search text"
style="width: 200px"
:defaultActiveFirstOption="false"
:showArrow="false"
:filterOption="false"
@change="handleChange"
>
<a-select-option v-for="d in data" :key="d.value">{{d.text}}</a-select-option>
</a-select>
</template>
<script>
import jsonp from 'fetch-jsonp';
import querystring from 'querystring';
let timeout;
let currentValue;
function fetch(value, callback) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
currentValue = value;
function fake() {
const str = querystring.encode({
code: 'utf-8',
q: value,
});
jsonp(`https://suggest.taobao.com/sug?${str}`)
.then(response => response.json())
.then((d) => {
if (currentValue === value) {
const result = d.result;
const data = [];
result.forEach((r) => {
data.push({
value: r[0],
text: r[0],
});
});
callback(data);
}
});
}
timeout = setTimeout(fake, 300);
}
export default {
data() {
return {
data: [],
value: '',
}
},
methods: {
handleChange (value) {
console.log(value)
this.value = value
fetch(value, data => this.data = data);
}
}
}
</script>
```

View File

@ -30,6 +30,7 @@ const AbstractSelectProps = {
const SelectValue = PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
PropTypes.object,
])
const SelectProps = {
@ -78,6 +79,10 @@ export default {
choiceTransitionName: PropTypes.string.def('zoom'),
},
propTypes: SelectPropTypes,
model: {
prop: 'value',
event: 'change',
},
methods: {
focus () {
this.$refs.vcSelect.focus()

View File

@ -1,45 +1,5 @@
import PropTypes from '../_util/vue-types'
function valueType (props, propName, componentName) {
const basicType = PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
])
const labelInValueShape = PropTypes.shape({
key: basicType.isRequired,
label: PropTypes.node,
})
if (props.labelInValue) {
const validate = PropTypes.oneOfType([
PropTypes.arrayOf(labelInValueShape),
labelInValueShape,
])
const error = validate(...arguments)
if (error) {
return new Error(
`Invalid prop \`${propName}\` supplied to \`${componentName}\`, ` +
`when you set \`labelInValue\` to \`true\`, \`${propName}\` should in ` +
`shape of \`{ key: string | number, label?: ReactNode }\`.`
)
}
} else if (
(props.mode === 'multiple' || props.mode === 'tags' || props.multiple || props.tags) &&
props[propName] === ''
) {
return new Error(
`Invalid prop \`${propName}\` of type \`string\` supplied to \`${componentName}\`, ` +
`expected \`array\` when \`multiple\` or \`tags\` is \`true\`.`
)
} else {
const validate = PropTypes.oneOfType([
PropTypes.arrayOf(basicType),
basicType,
])
return validate(...arguments)
}
}
export const SelectPropTypes = {
defaultActiveFirstOption: PropTypes.bool,
multiple: PropTypes.bool,

View File

@ -74,6 +74,10 @@ export default {
// onDeselect: noop,
// onInputKeydown: noop,
},
model: {
prop: 'value',
event: 'change',
},
data () {
this.labelMap = new Map()
this.titleMap = new Map()
@ -137,6 +141,7 @@ export default {
})
}
this.sValue = sValue
this.initLabelAndTitleMap()
if (this.combobox) {
this.setState({
inputValue: sValue.length ? this.labelMap.get((sValue[0].key)) : '',

6
package-lock.json generated
View File

@ -4023,6 +4023,12 @@
"pend": "1.2.0"
}
},
"fetch-jsonp": {
"version": "1.1.3",
"resolved": "http://registry.npm.taobao.org/fetch-jsonp/download/fetch-jsonp-1.1.3.tgz",
"integrity": "sha1-nrnlhboIqvcAVjU40Xu+u81aPbI=",
"dev": true
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",

View File

@ -48,6 +48,7 @@
"eslint-plugin-html": "^3.2.2",
"eslint-plugin-vue-libs": "^1.2.1",
"extract-text-webpack-plugin": "^3.0.2",
"fetch-jsonp": "^1.1.3",
"highlight.js": "^9.12.0",
"html-webpack-plugin": "^2.30.1",
"istanbul-instrumenter-loader": "^3.0.0",