Merge remote-tracking branch 'main/dev' into dev

This commit is contained in:
陈嘉涵 2017-09-01 10:19:40 +08:00
commit 0f3f9e3a8c
10 changed files with 392 additions and 15 deletions

View File

@ -29,4 +29,3 @@ gulp.task('copy', function(callback) {
});
runSequence('copy');

View File

@ -34,6 +34,7 @@ module.exports = {
chunkFilename: 'async.[name].js'
},
devServer: {
host: '0.0.0.0',
historyApiFallback: {
rewrites: [
{ from: /^\/zanui\/vue\/examples/, to: '/examples.html' },
@ -114,7 +115,7 @@ module.exports = {
},
render: function(tokens, idx) {
return tokens[idx].nesting === 1
return tokens[idx].nesting === 1
? `<demo-block class="demo-box"><div class="highlight" slot="highlight"å>`
:`</div></demo-block>\n`;
}

View File

@ -0,0 +1,169 @@
<script>
export default {
data() {
return {
items: [{
text: '所有城市',
children: [{
text: '杭州',
id: 1001
}, {
text: '温州',
id: 1002
}, {
text: '海南',
id: 1100
}, {
text: '宁波',
id: 1003
}, {
text: '义乌',
id: 1004
}, {
text: '无锡',
id: 1011
}, {
text: '常州',
id: 1012
}, {
text: '大连',
id: 1031
}, {
text: '诸暨',
id: 1005
}]
}, {
text: '浙江',
children: [{
text: '杭州',
id: 1001
}, {
text: '温州',
id: 1002
}, {
text: '宁波',
id: 1003
}, {
text: '义乌',
id: 1004
}]
}, {
text: '江苏',
children: [{
text: '无锡',
id: 1011
}, {
text: '常州',
id: 1012
}]
}],
mainActiveIndex: 0,
activeId: 1001
};
},
methods: {
onNavClick(index) {
this.mainActiveIndex = index;
},
onItemClick(data) {
console.log(data);
this.activeId = data.id;
}
}
}
</script>
## DeepSelect 分类选择组件
### 使用指南
``` javascript
import { DeepSelect } from 'vant';
Vue.component(DeepSelect.name, DeepSelect);
```
### 代码演示
#### 基础用法
:::demo 基础用法
```html
<van-deep-select
:items="items"
:main-active-index="mainActiveIndex"
:active-id="activeId"
@navclick="onNavClick"
@itemclick="onItemClick"
></van-deep-select>
```
```javascript
export default {
data() {
return {
items: items,
// 左侧高亮元素的index
mainActiveIndex: 0,
// 被选中元素的id
activeId: 1001
};
},
methods: {
onNavClick(index) {
this.mainActiveIndex = index;
},
onItemClick(data) {
console.log(data);
this.activeId = data.id;
}
}
}
</script>
```
:::
### API
#### 传入参数
| 参数 | 说明 | 类型 | 默认值 | 必须 |
|-----------|-----------|-----------|-------------|-------------|
| items | 分类显示所需的数据,具体数据结构可看 数据结构 | Array | [] | |
| mainActiveIndex | 左侧导航高亮的索引 | Number | 0 | |
| activeId | 右侧选择项高亮的数据id | Number | 0 | |
#### 事件
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| navclick | 左侧导航点击时,触发的事件 | index被点击的导航的索引 |
| itemclick | 右侧选择项被点击时,会触发的事件 | data: 该点击项的数据 |
### 数据格式
#### items 分类显示所需数据的数据结构
`items` 整体为一个数组,数组内包含一系列描述分类的 object。
每个分类里text表示当前分类的名称。children 表示分类里的可选项为数组结构id被用来唯一标识每个选项
```javascript
[
{
// 导航名称
text: '所有城市',
// 该导航下所有的可选项
children: [
{
// 可选项的名称
text: '温州',
// 可选项的id高亮的时候是根据id是否和选中的id是否相同进行判断的
id: 1002
},
{
// 可选项的名称
text: '杭州',
// 可选项的id高亮的时候是根据id是否和选中的id是否相同进行判断的
id: 1001
}
]
}
]
```

View File

@ -185,6 +185,10 @@ module.exports = {
{
"groupName": "业务组件",
"list": [
{
"path": "/deep-select",
"title": "DeepSelect 分类选择组件"
},
{
"path": "/express-way",
"title": "ExpressWay 配送方式"

View File

@ -0,0 +1,85 @@
<template>
<div class="van-deep-select" v-bind:style="{ height: mainHeight + 'px' }">
<div class="van-deep-select__nav">
<div
v-for="(item, index) in items"
class="van-deep-select__nitem"
v-bind:class="{ 'van-deep-select__nitem--active': mainActiveIndex === index }"
@click="onNavClick(index)">
{{ item.text }}
</div>
</div>
<div class="van-deep-select__content" v-bind:style="{ height: itemHeight + 'px' }">
<div
v-for="item in subItems"
:key="item.id"
class="van-deep-select__item"
v-bind:class="{ 'van-deep-select__item--active': activeId === item.id }"
@click="onItemSelect(item)">
{{ item.text }}
<van-icon
v-if="activeId === item.id"
name="success"
class="van-deep-select__selected"
></van-icon>
</div>
</div>
</div>
</template>
<script>
import Icon from 'packages/icon';
export default {
name: 'van-deep-select',
components: {
'van-icon': Icon
},
props: {
items: {
type: Array,
default () {
return [];
}
},
mainActiveIndex: {
type: Number,
default: 0
},
activeId: {
type: Number,
default: 0
},
maxHeight: {
type: Number,
default: 300
}
},
computed: {
subItems() {
const selectedItem = this.items[this.mainActiveIndex] || {};
return selectedItem.children || [];
},
mainHeight() {
const maxHeight = Math.max(this.items.length * 44, this.subItems.length * 44);
return Math.min(maxHeight, this.maxHeight);
},
itemHeight() {
return Math.min(this.subItems.length * 44, this.maxHeight);
}
},
methods: {
onNavClick(index) {
this.$emit('navclick', index);
},
onItemSelect(data) {
const exportData = Object.assign({}, data);
this.$emit('itemclick', exportData);
}
}
};
</script>

View File

@ -10,6 +10,7 @@ import Checkbox from './checkbox';
import CheckboxGroup from './checkbox-group';
import Col from './col';
import DatetimePicker from './datetime-picker';
import DeepSelect from './deep-select';
import Dialog from './dialog';
import ExpressWay from './express-way';
import Field from './field';
@ -60,6 +61,7 @@ const components = [
CheckboxGroup,
Col,
DatetimePicker,
DeepSelect,
ExpressWay,
Field,
GoodsAction,
@ -120,6 +122,7 @@ export {
CheckboxGroup,
Col,
DatetimePicker,
DeepSelect,
Dialog,
ExpressWay,
Field,

View File

@ -1,12 +1,7 @@
import Vue from 'vue';
let context;
const _global = Vue.prototype.$isServer ? global : window;
if (_global && _global.popupContext) {
context = _global.popupContext;
}
const DEFAULT_CONTEXT = {
idSeed: 1,
zIndex: 2000,
@ -15,23 +10,24 @@ const DEFAULT_CONTEXT = {
modalStack: []
};
context = _global.popupContext = {
...DEFAULT_CONTEXT,
...context
};
if (!_global.popupContext) {
_global.popupContext = {
...DEFAULT_CONTEXT
};
}
const PopupContext = {
getContext(key) {
return context[key];
return _global.popupContext[key];
},
setContext(key, value) {
context[key] = value;
_global.popupContext[key] = value;
},
plusKeyByOne(key) {
const oldVal = +context[key];
context[key] = oldVal + 1;
const oldVal = +_global.popupContext[key];
_global.popupContext[key] = oldVal + 1;
return oldVal;
}

View File

@ -0,0 +1,51 @@
@import "./mixins/ellipsis";
@import "./mixins/clearfix";
@import './common/var.css';
.van-deep-select {
user-select: none;
position: relative;
@mixin clearfix;
&__nav {
width: 143px;
/*float: left;*/
position: absolute;
left: 0;
top: 0;
bottom: 0;
overflow: scroll;
background-color: $c-white;
-webkit-overflow-scrolling: touch;
}
&__nitem {
line-height: 44px;
padding: 0 15px;
background-color: $c-white;
@mixin multi-ellipsis 1;
&--active {
background-color: $c-background;
}
}
&__content {
padding: 0 15px;
margin-left: 143px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
&__item {
position: relative;
line-height: 44px;
padding-left: 5px;
padding-right: 18px;
@mixin multi-ellipsis 1;
&--active {
color: $button-danger-background-color;
}
}
&__selected {
float: right;
position: absolute;
right: 0px;
top: 0;
bottom: 0;
}
}

View File

@ -6,6 +6,7 @@
@import './cell.css';
@import './cell-swipe.css';
@import './card.css';
@import './deep-select.css';
@import './dialog.css';
@import './field.css';
@import './icon.css';

View File

@ -0,0 +1,68 @@
import DeepSelect from 'packages/deep-select';
import { mount } from 'avoriaz';
describe('DeepSelect', () => {
let wrapper;
afterEach(() => {
wrapper && wrapper.destroy();
});
it('create an empty deep-select', () => {
wrapper = mount(DeepSelect);
expect(wrapper.hasStyle('height', '0px')).to.be.true;
});
it('create a deep-select correctly', () => {
wrapper = mount(DeepSelect, {
propsData: {
items: [{
text: 'A',
children: [{
text: 'Cc',
id: 123
}]
}],
maxHeight: 200
}
});
expect(wrapper.hasClass('van-deep-select')).to.be.true;
expect(wrapper.hasStyle('height', '44px')).to.be.true;
expect(wrapper.propsData().maxHeight).to.equal(200);
});
it('interact with this component', () => {
wrapper = mount(DeepSelect, {
propsData: {
items: [{
text: 'A',
children: [{
text: 'Cc',
id: 123
}, {
text: 'Bb',
id: 234
}]
}, {
text: 'B',
children: [{
text: 'Nmi',
id: 345
}]
}],
maxHeight: 220
}
});
wrapper.vm.$on('navclick', index => {
wrapper.vm.mainActiveIndex = index;
});
wrapper.vm.$on('itemclick', item => {
wrapper.vm.activeId = item.id;
});
const secondNav = wrapper.find('.van-deep-select__nitem')[1];
secondNav.trigger('click');
expect(wrapper.vm.mainActiveIndex).to.equal(1);
const target = wrapper.find('.van-deep-select__item')[0];
target.trigger('click');
expect(wrapper.vm.activeId).to.equal(345);
});
});