Merge branch 'origin/dev' into dev

This commit is contained in:
陈嘉涵 2017-12-05 20:05:38 +08:00
commit 2327e75516
29 changed files with 635 additions and 832 deletions

View File

@ -5,6 +5,7 @@
<p align="center"> <p align="center">
<img alt="项目logo" src="https://img.yzcdn.cn/upload_files/2017/04/20/FlkVrSlOr-SGK9qQqtilN6-IFZyT.png"> <img alt="项目logo" src="https://img.yzcdn.cn/upload_files/2017/04/20/FlkVrSlOr-SGK9qQqtilN6-IFZyT.png">
</p> </p>
<p align="center">A Vue.js 2.0 Mobile UI at YouZan</p> <p align="center">A Vue.js 2.0 Mobile UI at YouZan</p>
[![Build Status](https://travis-ci.org/youzan/vant.svg?branch=master)](https://travis-ci.org/youzan/vant) [![Build Status](https://travis-ci.org/youzan/vant.svg?branch=master)](https://travis-ci.org/youzan/vant)

View File

@ -5,6 +5,12 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const cache = {
loader: 'cache-loader',
options: {
cacheDirectory: path.resolve(__dirname, '../node_modules/.cache-loader')
}
};
module.exports = { module.exports = {
entry: { entry: {
@ -16,7 +22,6 @@ module.exports = {
path: path.join(__dirname, '../docs/dist'), path: path.join(__dirname, '../docs/dist'),
publicPath: '/', publicPath: '/',
filename: '[name].js', filename: '[name].js',
umdNamedDefine: true,
chunkFilename: 'async_[name].js' chunkFilename: 'async_[name].js'
}, },
devServer: { devServer: {
@ -44,6 +49,7 @@ module.exports = {
{ {
test: /\.vue$/, test: /\.vue$/,
use: [ use: [
cache,
{ {
loader: 'vue-loader', loader: 'vue-loader',
options: { options: {
@ -57,6 +63,7 @@ module.exports = {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules|vue-router\/|vue-loader\//, exclude: /node_modules|vue-router\/|vue-loader\//,
use: [ use: [
cache,
'babel-loader' 'babel-loader'
] ]
}, },
@ -72,6 +79,7 @@ module.exports = {
{ {
test: /\.md/, test: /\.md/,
use: [ use: [
cache,
'vue-loader', 'vue-loader',
'fast-vue-md-loader' 'fast-vue-md-loader'
] ]

View File

@ -5,7 +5,7 @@
</demo-block> </demo-block>
<demo-block :title="$t('title2')"> <demo-block :title="$t('title2')">
<van-area :areaList="areaList" value="110101" /> <van-area :areaList="areaList" :value="value" />
</demo-block> </demo-block>
<demo-block :title="$t('title3')"> <demo-block :title="$t('title3')">
@ -31,7 +31,8 @@ export default {
data() { data() {
return { return {
areaList: AreaList areaList: AreaList,
value: '110101'
}; };
} }
}; };

View File

@ -1,19 +1,26 @@
<template> <template>
<demo-section> <demo-section>
<demo-block :title="$t('basicUsage')"> <demo-block :title="$t('basicUsage')">
<van-picker :columns="columns" @change="onChange" /> <van-picker :columns="$t('column1')" @change="onChange1" />
</demo-block> </demo-block>
<demo-block :title="$t('title2')"> <demo-block :title="$t('title2')">
<van-picker :columns="$t('column2')" />
</demo-block>
<demo-block :title="$t('title3')">
<van-picker <van-picker
showToolbar showToolbar
:title="$t('area')" :title="$t('area')"
:columns="columns" :columns="$t('column1')"
@change="onChange"
@cancel="onCancel" @cancel="onCancel"
@confirm="onConfirm" @confirm="onConfirm"
/> />
</demo-block> </demo-block>
<demo-block :title="$t('title4')">
<van-picker :columns="columns" @change="onChange2" />
</demo-block>
</demo-section> </demo-section>
</template> </template>
@ -21,26 +28,45 @@
export default { export default {
i18n: { i18n: {
'zh-CN': { 'zh-CN': {
area: '地区选择', area: '标题',
title2: '带 toolbar 的 Picker', title2: '禁用选项',
column: { title3: '展示顶部栏',
'浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州'], title4: '多列联动',
'福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩'] column1: ['杭州', '宁波', '温州', '嘉兴', '湖州'],
} column2: [
{ text: '杭州', disabled: true },
{ text: '宁波' },
{ text: '温州' }
],
column3: {
浙江: ['杭州', '宁波', '温州', '嘉兴', '湖州'],
福建: ['福州', '厦门', '莆田', '三明', '泉州']
},
toastContent: (value, index) => `当前值:${value}, 当前索引:${index}`
}, },
'en-US': { 'en-US': {
area: 'Title', area: 'Title',
title2: 'Disable Option',
title3: 'Show Toolbar',
title4: 'Multi Columns',
title2: 'Picker with toolbar', title2: 'Picker with toolbar',
column: { column1: ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'],
'Group1': ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'], column2: [
'Group2': ['Alabama', 'Kansas', 'Louisiana', 'Texas'] { text: 'Delaware', disabled: true },
} { text: 'Florida' },
{ text: 'Georqia' }
],
column3: {
Group1: ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'],
Group2: ['Alabama', 'Kansas', 'Louisiana', 'Texas']
},
toastContent: (value, index) => `Value: ${value}, Index${index}`
} }
}, },
computed: { computed: {
columns() { columns() {
const column = this.$t('column'); const column = this.$t('column3');
return [ return [
{ {
values: Object.keys(column), values: Object.keys(column),
@ -48,27 +74,26 @@ export default {
}, },
{ {
values: column[Object.keys(column)[0]], values: column[Object.keys(column)[0]],
className: 'column2' className: 'column2',
defaultIndex: 2
} }
]; ];
} }
}, },
methods: { methods: {
onChange(picker, values) { onChange1(picker, value, index) {
picker.setColumnValues(1, this.$t('column')[values[0]]); Toast(this.$t('toastContent', value, index));
},
onChange2(picker, values) {
picker.setColumnValues(1, this.$t('column3')[values[0]]);
},
onConfirm(value, index) {
Toast(this.$t('toastContent', value, index));
}, },
onCancel() { onCancel() {
Toast('picker cancel'); Toast(this.$t('cancel'));
},
onConfirm() {
Toast('picker confirm');
} }
} }
}; };
</script> </script>
<style lang="postcss">
</style>

View File

@ -42,13 +42,9 @@
<!-- 自定义sku actions --> <!-- 自定义sku actions -->
<template slot="sku-actions" slot-scope="props"> <template slot="sku-actions" slot-scope="props">
<div class="van-sku-actions"> <div class="van-sku-actions">
<button class="van-sku__add-cart-btn" @click="handlePointClicked"> <van-button bottomAction @click="handlePointClicked">积分兑换</van-button>
积分兑换
</button>
<!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 --> <!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 -->
<button class="van-sku__buy-btn" @click="props.skuEventBus.$emit('sku:buy')"> <van-button type="primary" bottomAction @click="props.skuEventBus.$emit('sku:buy')">买买买</van-button>
买买买
</button>
</div> </div>
</template> </template>
</van-sku> </van-sku>

View File

@ -11,55 +11,79 @@ Vue.component(Picker.name, Picker);
#### Basic Usage #### Basic Usage
```html ```html
<van-picker :columns="pickerColumns" @change="onChange" /> <van-picker :columns="columns" @change="onChange" />
``` ```
```javascript ```javascript
const states = {
'Group1': ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'],
'Group2': ['Alabama', 'Kansas', 'Louisiana', 'Texas']
};
export default { export default {
data() { data() {
return { return {
pickerColumns: [ columns: ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine']
{
values: Object.keys(states),
className: 'column1'
},
{
values: states.Group1,
className: 'column2'
}
]
}; };
}, },
onChange(picker, value, index) {
methods: { Toast(`Value: ${value}, Index: ${index}`);
onChange(picker, values) {
picker.setColumnValues(1, citys[values[0]]);
}
} }
}; };
``` ```
#### Disable option
#### Picker with toolbar ```html
<van-picker :columns="columns" />
```
```javascript
export default {
data() {
return {
columns: [
{ text: 'Delaware', disabled: true },
{ text: 'Florida' },
{ text: 'Georqia' }
]
};
}
};
```
#### Show Toolbar
```html ```html
<van-picker <van-picker
showToolbar showToolbar
:title="title" :title="Title"
:columns="pickerColumns" :columns="columns"
@change="onChange"
@cancel="onCancel" @cancel="onCancel"
@confirm="onConfirm" @confirm="onConfirm"
/> />
``` ```
```javascript
export default {
data() {
return {
columns: ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine']
}
},
methods: {
onConfirm(value, index) {
Toast(`Value: ${value}, Index: ${index}`);
},
onCancel() {
Toast('Cancel');
}
}
};
```
#### Multi columns
```html
<van-picker :columns="columns" @change="onChange" />
```
```javascript ```javascript
const states = { const states = {
'Group1': ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'], 'Group1': ['Delaware', 'Florida', 'Georqia', 'Indiana', 'Maine'],
@ -69,29 +93,22 @@ const states = {
export default { export default {
data() { data() {
return { return {
title: 'Title', columns: [
pickerColumns: [
{ {
values: Object.keys(states), values: Object.keys(states),
className: 'column1' className: 'column1'
}, },
{ {
values: states.Group1, values: states.Group1,
className: 'column2' className: 'column2',
defaultIndex: 2
} }
] ]
}; };
}, },
methods: { methods: {
onChange(picker, values) { onChange(picker, values) {
picker.setColumnValues(1, citys[values[0]]); picker.setColumnValues(1, states[values[0]]);
},
onCancel() {
Toast('Cancel');
},
onConfirm() {
Toast('Confirm');
} }
} }
}; };
@ -101,11 +118,12 @@ export default {
| Attribute | Description | Type | Default | Accepted Values | | Attribute | Description | Type | Default | Accepted Values |
|-----------|-----------|-----------|-------------|-------------| |-----------|-----------|-----------|-------------|-------------|
| visibileColumnCount | Count of columns to show | `Number` | `5` | - | | columns | Columns data | `Array` | `[]` | - |
| itemHeight | Item height | `Number` | `44` | - | | showToolbar | Whether to show toolbar | `Boolean` | `false` | - |
| columns | Columns data | `Array` | - | - | | title | Toolbar title | `String` | `''` | - |
| showToolbar | Whether to show toolbar | `Boolean` | `true` | - | | itemHeight | Option height | `Number` | `44` | - |
| title | Toolbar title | `String` | - | - | | visibileColumnCount | Count of visible columns | `Number` | `5` | - |
| valueKey | Key of option text | `String` | `text` | - |
### Data struct of columns ### Data struct of columns
@ -116,13 +134,17 @@ export default {
| className | ClassName for this column | | className | ClassName for this column |
### Picker instance ### Picker instance
The first argument of change event's callback function is a picker instance with some methods You can get the picker instance in 'change' event, and
| Method | Description | | Method | Description |
|-----------|-----------| |-----------|-----------|
| getColumnValue(index) | get current value of the column | | getValues() | Get current values of all columns |
| setColumnValue(index, value) | set current value of the column | | setValues(values) | Set current values of all columns |
| getColumnValues(index) | get all values of the column | | getIndexes() | Get current indexes of all columns |
| setColumnValues(index, values) | set all values of the column | | setIndexes(indexes) | Set current indexes of all columns |
| getValues() | get current values of all columns | | getColumnValue(columnIndex) | Get current value of the column |
| setValues(values) | set current values of all columns | | setColumnValue(columnIndex, value) | Set current value of the column |
| getColumnIndex(columnIndex) | Get current index of the column |
| setColumnIndex(columnIndex, optionIndex) | Set current index of the column |
| getColumnValues(columnIndex) | Get columns data of the column |
| setColumnValues(columnIndex, values) | Set columns data of the column |

View File

@ -44,7 +44,7 @@ Use `position` prop to set popup display position
| lockOnScroll | Lock body scroll | `Boolean` | `false` | - | | lockOnScroll | Lock body scroll | `Boolean` | `false` | - |
| position | Position | `String` | - | `top` `bottom` `right` `left` | | position | Position | `String` | - | `top` `bottom` `right` `left` |
| overlayClass | Custom overlay class | `String` | `` | - | | overlayClass | Custom overlay class | `String` | `` | - |
| overlayStyle | Custom overlay style | `Object` | `` | - | | overlayStyle | Custom overlay style | `Object` | - | - |
| closeOnClickOverlay | Close popup when click overlay | `Boolean` | `true` | - | | closeOnClickOverlay | Close popup when click overlay | `Boolean` | `true` | - |
| transition | Transition | `String` | `popup-slide` | - | | transition | Transition | `String` | `popup-slide` | - |
| preventScroll | Prevent background scroll | `Boolean` | `false` | - | | preventScroll | Prevent background scroll | `Boolean` | `false` | - |

View File

@ -49,13 +49,9 @@ Vue.component(Sku.name, Sku);
<!-- 自定义sku actions --> <!-- 自定义sku actions -->
<template slot="sku-actions" slot-scope="props"> <template slot="sku-actions" slot-scope="props">
<div class="van-sku-actions"> <div class="van-sku-actions">
<button class="van-sku__add-cart-btn" @click="handlePointClicked"> <van-button bottomAction @click="handlePointClicked">积分兑换</van-button>
积分兑换
</button>
<!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 --> <!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 -->
<button class="van-sku__buy-btn" @click="props.skuEventBus.$emit('sku:buy')"> <van-button type="primary" bottomAction @click="props.skuEventBus.$emit('sku:buy')">买买买</van-button>
买买买
</button>
</div> </div>
</template> </template>
</van-sku> </van-sku>

View File

@ -58,14 +58,14 @@ Vue.component(Button.name, Button);
#### 页面底部操作按钮 #### 页面底部操作按钮
```html ```html
<van-button type="primary" bottom-action>按钮</van-button> <van-button type="primary" bottomAction>按钮</van-button>
<van-row> <van-row>
<van-col span="12"> <van-col span="12">
<van-button bottom-action>按钮</van-button> <van-button bottomAction>按钮</van-button>
</van-col> </van-col>
<van-col span="12"> <van-col span="12">
<van-button type="primary" bottom-action>按钮</van-button> <van-button type="primary" bottomAction>按钮</van-button>
</van-col> </van-col>
</van-row> </van-row>
``` ```

View File

@ -9,87 +9,108 @@ Vue.component(Picker.name, Picker);
### 代码演示 ### 代码演示
#### 基础用法 #### 基础用法
```html ```html
<van-picker :columns="pickerColumns" @change="onChange" /> <van-picker :columns="columns" @change="onChange" />
``` ```
```javascript ```javascript
const citys = {
'浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州'],
'福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩']
};
export default { export default {
data() { data() {
return { return {
pickerColumns: [ columns: ['杭州', '宁波', '温州', '嘉兴', '湖州']
{
values: Object.keys(citys),
className: 'column1'
},
{
values: citys['浙江'],
className: 'column2'
}
]
}; };
}, },
onChange(picker, value, index) {
methods: { Toast(`当前值:${value}, 当前索引:${index}`);
onChange(picker, values) {
picker.setColumnValues(1, citys[values[0]]);
}
} }
}; };
``` ```
#### 带 toolbar 的 Picker #### 禁用选项
选项可以为对象结构,通过设置 disabled 来禁用该选项
```html
<van-picker :columns="columns" />
```
```javascript
export default {
data() {
return {
columns: [
{ text: '杭州', disabled: true },
{ text: '宁波' },
{ text: '温州' }
]
};
}
};
```
#### 展示顶部栏
```html ```html
<van-picker <van-picker
showToolbar showToolbar
:title="title" :title="标题"
:columns="pickerColumns" :columns="columns"
@change="onChange"
@cancel="onCancel" @cancel="onCancel"
@confirm="onConfirm" @confirm="onConfirm"
/> />
``` ```
```javascript
export default {
data() {
return {
columns: ['杭州', '宁波', '温州', '嘉兴', '湖州']
}
},
methods: {
onConfirm(value, index) {
Toast(`当前值:${value}, 当前索引:${index}`);
},
onCancel() {
Toast('取消');
}
}
};
```
#### 多列联动
```html
<van-picker :columns="columns" @change="onChange" />
```
```javascript ```javascript
const citys = { const citys = {
'浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州'], '浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州'],
'福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩'] '福建': ['福州', '厦门', '莆田', '三明', '泉州']
}; };
export default { export default {
data() { data() {
return { return {
title: '地区选择', columns: [
pickerColumns: [
{ {
values: Object.keys(citys), values: Object.keys(citys),
className: 'column1' className: 'column1'
}, },
{ {
values: citys['浙江'], values: citys['浙江'],
className: 'column2' className: 'column2',
defaultIndex: 2
} }
] ]
}; };
}, },
methods: { methods: {
onChange(picker, values) { onChange(picker, values) {
picker.setColumnValues(1, citys[values[0]]); picker.setColumnValues(1, citys[values[0]]);
},
onCancel() {
Toast('picker cancel');
},
onConfirm() {
Toast('picker confirm');
} }
} }
}; };
@ -99,31 +120,34 @@ export default {
| 参数 | 说明 | 类型 | 默认值 | 可选值 | | 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------| |-----------|-----------|-----------|-------------|-------------|
| visibileColumnCount | 每一列可见备选元素的个数 | `Number` | `5` | - | | columns | 对象数组,配置每一列显示的数据 | `Array` | `[]` | - |
| itemHeight | 选中元素区高度 | `Number` | `44` | - | | showToolbar | 是否显示顶部栏 | `Boolean` | `false` | - |
| columns | 对象数组,配置每一列显示的数据 | `Array` | - | - | | title | 顶部栏标题 | `String` | `''` | - |
| showToolbar | 是否在组件顶部显示一个toolbar | `Boolean` | `true` | - | | itemHeight | 选项高度 | `Number` | `44` | - |
| title | 在toolbar上显示的标题文字 | `String` | - | - | | visibileColumnCount | 可见的选项个数 | `Number` | `5` | - |
| valueKey | 选项对象中,文字对应的 key | `String` | `text` | - |
### columns ### Columns 数据结构
当传入多列数据时,`columns`为一个对象数组,数组中的每一个对象配置每一列,每一列有以下`key`
`API`中的`columns`为一个对象数组,数组中的每一个对象配置每一列,每一列有以下`key`
| key | 说明 | | key | 说明 |
|-----------|-----------| |-----------|-----------|
| values | 列中对应的备选值 | | values | 列中对应的备选值 |
| defaultIndex | 初始选中值的索引,默认为0 | | defaultIndex | 初始选中项的索引,默认为 0 |
| className | 为对应列添加特殊`class` | | className | 为对应列添加额外`class` |
### change事件 ### Picker 实例
`change`事件中,可以获取到`picker`实例,通过实例方法可以灵活控制 Picker 内容
`change`事件中,可以获取到`picker`实例,对`picker`进行相应的更新等操作:
| 函数 | 说明 | | 函数 | 说明 |
|-----------|-----------| |-----------|-----------|
| getColumnValue(index) | 获取对应列中选中的值 | | getValues() | 获取所有列选中的值,返回一个数组 |
| setColumnValue(index, value) | 设置对应列中选中的值 | | setValues(values) | 设置所有列选中的值 |
| getColumnValues(index) | 获取对应列中所有的备选值 | | getIndexes() | 获取所有列选中值对应的索引,返回一个数组 |
| setColumnValues(index, values) | 设置对应列中所有的备选值 | | setIndexes(indexes) | 设置所有列选中值对应的索引 |
| getValues() | 获取所有列中被选中的值,返回一个数组 | | getColumnValue(columnIndex) | 获取对应列选中的值 |
| setValues(values) | `values`为一个数组,设置所有列中被选中的值 | | setColumnValue(columnIndex, value) | 设置对应列选中的值 |
| getColumnIndex(columnIndex) | 获取对应列选中项的索引 |
| setColumnIndex(columnIndex, optionIndex) | 设置对应列选中项的索引 |
| getColumnValues(columnIndex) | 获取对应列中所有选项 |
| setColumnValues(columnIndex, values) | 设置对应列中所有选项 |

View File

@ -49,13 +49,9 @@ Vue.component(Sku.name, Sku);
<!-- 自定义sku actions --> <!-- 自定义sku actions -->
<template slot="sku-actions" slot-scope="props"> <template slot="sku-actions" slot-scope="props">
<div class="van-sku-actions"> <div class="van-sku-actions">
<button class="van-sku__add-cart-btn" @click="handlePointClicked"> <van-button bottomAction @click="handlePointClicked">积分兑换</van-button>
积分兑换
</button>
<!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 --> <!-- 直接触发sku内部事件通过内部事件执行handleBuyClicked回调 -->
<button class="van-sku__buy-btn" @click="props.skuEventBus.$emit('sku:buy')"> <van-button type="primary" bottomAction @click="props.skuEventBus.$emit('sku:buy')">买买买</van-button>
买买买
</button>
</div> </div>
</template> </template>
</van-sku> </van-sku>

View File

@ -58,7 +58,7 @@ export default {
</script> </script>
<style lang="postcss"> <style lang="postcss">
@import '../../../packages/vant-css/src/common/var'; @import '../../../packages/vant-css/src/common/var.css';
.side-nav { .side-nav {
width: 100%; width: 100%;

View File

@ -51,7 +51,7 @@
"vue": ">= 2.5.0" "vue": ">= 2.5.0"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^7.1.6", "autoprefixer": "^7.2.1",
"avoriaz": "2.0.0", "avoriaz": "2.0.0",
"babel-cli": "^6.26.0", "babel-cli": "^6.26.0",
"babel-core": "^6.26.0", "babel-core": "^6.26.0",
@ -63,6 +63,7 @@
"babel-plugin-transform-vue-jsx": "^3.5.0", "babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1", "babel-preset-env": "^1.6.1",
"cache-loader": "^1.2.0",
"chai": "^4.1.2", "chai": "^4.1.2",
"cheerio": "^0.22.0", "cheerio": "^0.22.0",
"codecov": "^3.0.0", "codecov": "^3.0.0",
@ -70,7 +71,7 @@
"css-loader": "^0.28.7", "css-loader": "^0.28.7",
"dependency-tree": "^5.12.0", "dependency-tree": "^5.12.0",
"eslint-plugin-vue": "^2.1.0", "eslint-plugin-vue": "^2.1.0",
"extract-text-webpack-plugin": "2.0.0", "extract-text-webpack-plugin": "3.0.2",
"fast-vue-md-loader": "^1.0.2", "fast-vue-md-loader": "^1.0.2",
"felint": "^0.5.0-alpha.3", "felint": "^0.5.0-alpha.3",
"file-save": "^0.2.0", "file-save": "^0.2.0",
@ -115,7 +116,7 @@
"vue-style-loader": "^3.0.0", "vue-style-loader": "^3.0.0",
"vue-template-compiler": "^2.5.9", "vue-template-compiler": "^2.5.9",
"vue-template-es2015-compiler": "^1.6.0", "vue-template-es2015-compiler": "^1.6.0",
"webpack": "^3.8.1", "webpack": "^3.9.1",
"webpack-bundle-analyzer": "^2.9.1", "webpack-bundle-analyzer": "^2.9.1",
"webpack-dev-server": "^2.9.4", "webpack-dev-server": "^2.9.4",
"webpack-merge": "^4.1.1" "webpack-merge": "^4.1.1"

View File

@ -59,6 +59,7 @@ export default {
const columns = []; const columns = [];
const curValue = this.value || ''; const curValue = this.value || '';
const { columnsNum } = this;
columns.push({ columns.push({
values: [DEFAULT_PROVINCE].concat(this.computedAreaList(PROVINCE_TYPE)), values: [DEFAULT_PROVINCE].concat(this.computedAreaList(PROVINCE_TYPE)),
@ -66,7 +67,6 @@ export default {
defaultIndex: this.getAreaIndex(PROVINCE_TYPE, curValue) defaultIndex: this.getAreaIndex(PROVINCE_TYPE, curValue)
}); });
const columnsNum = this.columnsNum;
if (+columnsNum > 1) { if (+columnsNum > 1) {
columns.push({ columns.push({
values: [DEFAULT_CITY].concat(this.computedAreaList(CITY_TYPE, curValue.slice(0, 2))), values: [DEFAULT_CITY].concat(this.computedAreaList(CITY_TYPE, curValue.slice(0, 2))),

View File

@ -225,7 +225,7 @@ export default {
}, },
onChange(picker) { onChange(picker) {
const values = picker.$children.filter(child => child.currentValue !== undefined).map(child => child.currentValue); const values = picker.getValues();
let value; let value;
if (this.type === 'time') { if (this.type === 'time') {
@ -279,20 +279,7 @@ export default {
if (!this.$refs.picker) { if (!this.$refs.picker) {
return; return;
} }
const setColumnValue = this.$refs.picker.setColumnValue; this.$refs.picker.setValues(values);
if (this.type === 'time') {
setColumnValue(0, values[0]);
setColumnValue(1, values[1]);
} else {
setColumnValue(0, values[0]);
setColumnValue(1, values[1]);
setColumnValue(2, values[2]);
if (this.type === 'datetime') {
setColumnValue(3, values[3]);
setColumnValue(4, values[4]);
}
}
[].forEach.call(this.$refs.picker.$children, child => child.doOnValueChange());
} }
}, },

View File

@ -3,41 +3,24 @@ import context from './popup-context';
export default { export default {
props: { props: {
// popup 当前显示状态 // whether to show popup
value: { value: Boolean,
type: Boolean, // whether to show overlay
default: false overlay: Boolean,
}, // overlay custom style
// 是否显示遮罩层 overlayStyle: Object,
overlay: { // overlay custom class name
type: Boolean, overlayClass: String,
default: false // whether to close popup when click overlay
}, closeOnClickOverlay: Boolean,
// 点击遮罩层是否关闭 popup // z-index
closeOnClickOverlay: {
type: Boolean,
default: false
},
zIndex: [String, Number], zIndex: [String, Number],
// popup 滚动时是否禁用 body 滚动 // prevent touchmove scroll
preventScroll: Boolean,
// prevent body scroll
lockOnScroll: { lockOnScroll: {
type: Boolean, type: Boolean,
default: true default: true
},
// 防止滚动穿透
preventScroll: {
type: Boolean,
default: false
},
// 遮罩层额外样式
overlayStyle: {
type: String,
default: ''
},
// 遮罩层额外类
overlayClass: {
type: String,
default: ''
} }
}, },

View File

@ -1,245 +1,178 @@
<template> <template>
<div class="van-picker-column" :class="classNames"> <div class="van-picker-column" :class="className">
<div class="van-picker-column-wrapper" :class="{ dragging: isDragging }" ref="wrapper" :style="{ height: visibleContentHeight + 'px' }"> <div class="van-picker-column__frame van-hairline--top-bottom" :style="frameStyle" />
<div <ul
v-for="(item, index) in currentValues" :style="wrapperStyle"
:key="index" @touchstart="onTouchStart"
class="van-picker-column__item" @touchmove.prevent="onTouchMove"
:class="{ 'van-picker-column__item--selected': item === currentValue }" @touchend="onTouchEnd"
:style="{ height: itemHeight + 'px', lineHeight: itemHeight + 'px' }"> @touchcancel="onTouchEnd"
{{ typeof item === 'object' && item[valueKey] ? item[valueKey] : item }} >
</div> <li
</div> v-for="(option, index) in options"
v-text="getOptionText(option)"
:class="{
'van-picker-column--disabled': isDisabled(option),
'van-picker-column--selected': index === currentIndex
}"
@click="setIndex(index)"
/>
</ul>
</div> </div>
</template> </template>
<script> <script>
import translateUtil from '../utils/transition'; const DEFAULT_DURATION = 200;
import draggable from './draggable'; const range = (num, arr) => Math.min(Math.max(num, arr[0]), arr[1]);
const DEFAULT_ITEM_HEIGHT = 44;
export default { export default {
name: 'van-picker-column', name: 'van-picker-column',
props: { props: {
/** valueKey: String,
* 每一列可见备选元素的个数 className: String,
*/ options: {
type: Array,
default: () => []
},
itemHeight: {
type: Number,
default: 44
},
visibileColumnCount: { visibileColumnCount: {
type: Number, type: Number,
default: 5 default: 5
}, },
/** defaultIndex: {
* 该列所有的可选值
*/
values: {
type: Array,
default() {
return [];
}
},
/**
* 每列添加额外的`className`
*/
className: {
type: String,
default: ''
},
/**
* 行高
*/
itemHeight: {
type: Number, type: Number,
default: DEFAULT_ITEM_HEIGHT default: 0
}, }
value: {},
valueKey: String
}, },
data() { data() {
return { return {
currentValue: this.value, startY: 0,
currentValues: this.values, offset: 0,
isDragging: false duration: 0,
startOffset: 0,
currentIndex: this.defaultIndex
}; };
}, },
created() {
this.$parent && this.$parent.children.push(this);
},
mounted() {
this.setIndex(this.currentIndex);
},
destroyed() {
this.$parent && this.$parent.children.splice(this.$parent.children.indexOf(this), 1);
},
watch: { watch: {
values(val) { defaultIndex() {
this.currentValues = val; this.setIndex(this.defaultIndex);
}, },
currentValues(val) {
/* istanbul ignore else */ options(next, prev) {
if (this.valueIndex === -1) { if (JSON.stringify(next) !== JSON.stringify(prev)) {
this.currentValue = (val || [])[0]; this.setIndex(this.defaultIndex);
} }
}, },
value(val) {
this.currentValue = val;
},
currentValue(val) {
this.doOnValueChange();
this.$emit('input', val); currentIndex(index) {
this.$emit('columnChange', this); this.$emit('change', index);
} }
}, },
computed: { computed: {
/** count() {
* picker可见备选元素总高度 return this.options.length;
*/
visibleContentHeight() {
return this.itemHeight * this.visibileColumnCount;
}, },
/** wrapperStyle() {
* 当前选中值在`values`中的索引 const { itemHeight, visibileColumnCount } = this;
*/ return {
valueIndex() { transition: `${this.duration}ms`,
return this.currentValues.indexOf(this.currentValue); transform: `translate3d(0, ${this.offset}px, 0)`,
lineHeight: itemHeight + 'px',
height: itemHeight * visibileColumnCount + 'px',
paddingTop: itemHeight * (visibileColumnCount - 1) / 2 + 'px'
};
}, },
/** frameStyle() {
* 计算picker的拖动范围 return {
*/ height: this.itemHeight + 'px'
dragRange() {
var values = this.currentValues;
var visibileColumnCount = this.visibileColumnCount;
var itemHeight = this.itemHeight;
return [-itemHeight * (values.length - Math.ceil(visibileColumnCount / 2)), itemHeight * Math.floor(visibileColumnCount / 2)];
},
/**
* 计算`classNames`
*/
classNames() {
return this.className.split(' ');
}
},
mounted() {
this.initEvents();
this.doOnValueChange();
},
methods: {
/**
* 将当前`value`值转换成需要垂直方向需要`translate`的值
*/
value2Translate(value) {
const values = this.currentValues;
const valueIndex = values.indexOf(value);
const offset = Math.floor(this.visibileColumnCount / 2);
const itemHeight = this.itemHeight;
if (valueIndex !== -1) {
return (valueIndex - offset) * (-itemHeight);
} }
}, },
/** currentValue() {
* 根据当前`translate`的值转换成当前选中的`value` return this.options[this.currentIndex];
*/ }
translate2Value(translate) { },
const itemHeight = this.itemHeight;
translate = Math.round(translate / itemHeight) * itemHeight;
const index = -(translate - Math.floor(this.visibileColumnCount / 2) * itemHeight) / itemHeight; methods: {
onTouchStart(event) {
return this.currentValues[index]; this.startY = event.touches[0].clientY;
this.startOffset = this.offset;
this.duration = 0;
}, },
/** onTouchMove(event) {
* 初始化拖动事件 const deltaY = event.touches[0].clientY - this.startY;
*/ this.offset = range(this.startOffset + deltaY, [
initEvents() { -(this.count * this.itemHeight),
var el = this.$refs.wrapper; this.itemHeight
var dragState = {}; ]);
},
var velocityTranslate; onTouchEnd() {
var prevTranslate; if (this.offset !== this.startOffset) {
var pickerItems; // eslint-disable-line this.duration = DEFAULT_DURATION;
const index = range(Math.round(-this.offset / this.itemHeight), [
0,
this.count - 1
]);
this.setIndex(index);
}
},
draggable(el, { adjustIndex(index) {
start: (event) => { index = range(index, [0, this.count]);
// for (let i = index; i < this.count; i++) {
dragState = { if (!this.isDisabled(this.options[i])) return i;
range: this.dragRange, }
start: new Date(), for (let i = index - 1; i >= 0; i--) {
startLeft: event.pageX, if (!this.isDisabled(this.options[i])) return i;
startTop: event.pageY, }
startTranslateTop: translateUtil.getElementTranslate(el).top },
};
pickerItems = el.querySelectorAll('.van-picker-item'); // eslint-disable-line isDisabled(option) {
}, return typeof option === 'object' && option.disabled;
},
drag: (event) => { getOptionText(option) {
this.isDragging = true; return typeof option === 'object' && this.valueKey in option ? option[this.valueKey] : option;
},
dragState.left = event.pageX; setIndex(index) {
dragState.top = event.pageY; index = this.adjustIndex(index);
this.offset = -index * this.itemHeight;
this.currentIndex = index;
},
const deltaY = dragState.top - dragState.startTop; setValue(value) {
const translate = dragState.startTranslateTop + deltaY; const { options, valueKey } = this;
for (let i = 0; i < options.length; i++) {
translateUtil.translateElement(el, null, translate); if (this.getOptionText(options[i]) === value) {
this.setIndex(i);
velocityTranslate = translate - prevTranslate || translate; return;
prevTranslate = translate;
},
end: () => {
/* istanbul ignore else */
if (this.isDragging) {
this.isDragging = false;
var momentumRatio = 7;
var currentTranslate = translateUtil.getElementTranslate(el).top;
var duration = new Date() - dragState.start;
var momentumTranslate;
if (duration < 300) {
momentumTranslate = currentTranslate + velocityTranslate * momentumRatio;
}
var dragRange = dragState.range;
this.$nextTick(() => {
var translate;
var itemHeight = this.itemHeight;
if (momentumTranslate) {
translate = Math.round(momentumTranslate / itemHeight) * itemHeight;
} else {
translate = Math.round(currentTranslate / itemHeight) * itemHeight;
}
translate = Math.max(Math.min(translate, dragRange[1]), dragRange[0]);
translateUtil.translateElement(el, null, translate);
this.currentValue = this.translate2Value(translate);
});
}
dragState = {};
} }
}); }
},
/**
* `value`改变时调用
*/
doOnValueChange() {
const value = this.currentValue;
const wrapper = this.$refs.wrapper;
translateUtil.translateElement(wrapper, null, this.value2Translate(value));
} }
} }
}; };

View File

@ -1,51 +0,0 @@
import Vue from 'vue';
let isDragging = false;
const supportTouch = !Vue.prototype.$isServer && 'ontouchstart' in window;
export default function(element, options) {
const moveFn = function(event) {
if (options.drag) {
options.drag(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
};
const endFn = function(event) {
if (!supportTouch) {
document.removeEventListener('mousemove', moveFn);
document.removeEventListener('mouseup', endFn);
}
document.onselectstart = null;
document.ondragstart = null;
isDragging = false;
if (options.end) {
options.end(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
};
element.addEventListener(supportTouch ? 'touchstart' : 'mousedown', function(event) {
if (isDragging) return;
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
if (!supportTouch) {
document.addEventListener('mousemove', moveFn);
document.addEventListener('mouseup', endFn);
}
isDragging = true;
if (options.start) {
event.preventDefault();
options.start(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
});
if (supportTouch) {
element.addEventListener('touchmove', moveFn);
element.addEventListener('touchend', endFn);
element.addEventListener('touchcancel', endFn);
}
};

View File

@ -1,34 +1,32 @@
<template> <template>
<div class="van-picker"> <div class="van-picker">
<div class="van-picker__toolbar van-hairline--top-bottom" v-show="showToolbar"> <div class="van-picker__toolbar van-hairline--top-bottom" v-if="showToolbar">
<slot> <slot>
<a href="javascript:void(0)" class="van-picker__cancel" @click="handlePickerCancel">{{ $t('cancel') }}</a> <div class="van-picker__cancel" @click="emit('cancel')">{{ $t('cancel') }}</div>
<a href="javascript:void(0)" class="van-picker__confirm" @click="handlePickerConfirm">{{ $t('confirm') }}</a> <div class="van-picker__confirm" @click="emit('confirm')">{{ $t('confirm') }}</div>
<div v-if="title" class="van-picker__title">{{ title }}</div> <div class="van-picker__title" v-if="title" v-text="title" />
</slot> </slot>
</div> </div>
<div class="van-picker__columns" :class="`van-picker__columns--${columns.length}`"> <div class="van-picker__columns">
<van-picker-column <van-picker-column
v-for="(item, index) in columns" v-for="(item, index) in currentColumns"
:key="index" :key="index"
v-model="values[index]"
:values="item.values"
:className="item.className"
:itemHeight="itemHeight"
:visibleItemCount="visibileColumnCount"
:valueKey="valueKey" :valueKey="valueKey"
@columnChange="columnValueChange(index)" :options="item.values"
:className="item.className"
:defaultIndex="item.defaultIndex"
:itemHeight="itemHeight"
:visibileColumnCount="visibileColumnCount"
@change="onChange(index)"
/> />
<div class="van-picker-center-highlight" :style="{ height: itemHeight + 'px', marginTop: -itemHeight / 2 + 'px' }"></div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import PickerColumn from './PickerColumn';
import { i18n } from '../locale'; import { i18n } from '../locale';
import Column from './PickerColumn';
const DEFAULT_ITEM_HEIGHT = 44; import deepClone from '../utils/deep-clone';
export default { export default {
name: 'van-picker', name: 'van-picker',
@ -36,132 +34,126 @@ export default {
mixins: [i18n], mixins: [i18n],
components: { components: {
[PickerColumn.name]: PickerColumn [Column.name]: Column
}, },
props: { props: {
/** title: String,
* 每一列可见备选元素的个数 valueKey: {
*/ type: String,
visibileColumnCount: { default: 'text'
type: Number,
default: 5
}, },
/** itemHeight: Number,
* 选中元素区高度 showToolbar: Boolean,
*/ visibileColumnCount: Number,
itemHeight: {
type: Number,
default: DEFAULT_ITEM_HEIGHT
},
/**
* 对象数组配置每一列显示的数据
*/
columns: { columns: {
type: Array, type: Array,
default() { default: () => []
return [];
}
}, },
/**
* 否在组件顶部显示一个toolbar
*/
showToolbar: {
type: Boolean,
default: false
},
/**
* 顶部toolbar 显示的title
*/
title: String,
valueKey: String
}, },
computed: { data() {
values() { return {
const columns = this.columns || []; children: [],
const values = []; currentColumns: []
};
},
columns.forEach(column => { created() {
values.push(column.value || column.values[column.defaultIndex || 0]); this.initColumns();
}); },
return values; watch: {
} columns() {
this.initColumns();
},
}, },
methods: { methods: {
handlePickerCancel() { initColumns() {
this.$emit('cancel', this.values); const columns = this.columns.map(deepClone);
}, this.isSimpleColumn = columns.length && !columns[0].values;
handlePickerConfirm() { this.currentColumns = this.isSimpleColumn ? [{ values: columns }] : columns;
this.$emit('confirm', this.values);
},
/**
* 处理列`change`事件
*/
columnValueChange(index) {
this.$emit('change', this, this.values, index);
}, },
/** emit(event) {
* 获取对应索引的列的实例 if (this.isSimpleColumn) {
*/ this.$emit(event, this.getColumnValue(0), this.getColumnIndex(0));
} else {
this.$emit(event, this.getValues(), this.getIndexes());
}
},
onChange(columnIndex) {
if (this.isSimpleColumn) {
this.$emit('change', this, this.getColumnValue(0), this.getColumnIndex(0));
} else {
this.$emit('change', this, this.getValues(), columnIndex);
}
},
// get column instance by index
getColumn(index) { getColumn(index) {
const children = this.$children.filter(child => child.$options.name === 'van-picker-column'); return this.children[index];
return children[index];
}, },
/** // get column value by index
* 获取对应列中选中的值
*/
getColumnValue(index) { getColumnValue(index) {
const column = this.getColumn(index); return (this.getColumn(index) || {}).currentValue;
return column && column.values[column.valueIndex];
}, },
/** // set column value by index
* 设置对应列中选中的值
*/
setColumnValue(index, value) { setColumnValue(index, value) {
const column = this.getColumn(index); const column = this.getColumn(index);
if (column) { column && column.setValue(value);
column.currentValue = value;
}
}, },
/** // get column option index by column index
* 获取对应列中所有的备选值 getColumnIndex(columnIndex) {
*/ return (this.getColumn(columnIndex) || {}).currentIndex;
},
// set column option index by column index
setColumnIndex(columnIndex, optionIndex) {
const column = this.getColumn(columnIndex);
column && column.setIndex(optionIndex);
},
// get options of column by index
getColumnValues(index) { getColumnValues(index) {
const column = this.getColumn(index); return (this.currentColumns[index] || {}).values;
return column && column.currentValues;
}, },
/** // set options of column by index
* 设置对应列中所有的备选值 setColumnValues(index, options) {
*/ const column = this.currentColumns[index];
setColumnValues(index, values) {
const column = this.getColumn(index);
if (column) { if (column) {
column.currentValues = values; column.values = options;
} }
}, },
/** // get values of all columns
* 获取所有列中被选中的值返回一个数组
*/
getValues() { getValues() {
return this.values; return this.children.map(child => child.currentValue);
}, },
/** // set values of all columns
* `values`为一个数组设置所有列中被选中的值
*/
setValues(values) { setValues(values) {
values.forEach((value, index) => { values.forEach((value, index) => {
this.setColumnValue(index, value); this.setColumnValue(index, value);
}); });
},
// get indexes of all columns
getIndexes() {
return this.children.map(child => child.currentIndex);
},
// set indexes of all columns
setIndexes(indexes) {
indexes.forEach((optionIndex, columnIndex) => {
this.setColumnIndex(columnIndex, optionIndex);
});
} }
} }
}; };

View File

@ -1,18 +1,20 @@
<template> <template>
<div class="van-sku-actions"> <div class="van-sku-actions">
<button v-if="showAddCartBtn" class="van-sku__add-cart-btn" @click="onAddCartClicked"> <van-button v-if="showAddCartBtn" bottomAction @click="onAddCartClicked">加入购物车</van-button>
加入购物车 <van-button type="primary" bottomAction @click="onBuyClicked">{{ buyText }}</van-button>
</button>
<button class="van-sku__buy-btn" @click="onBuyClicked">
{{ buyText }}
</button>
</div> </div>
</template> </template>
<script> <script>
import Button from '../../button';
export default { export default {
name: 'van-sku-actions', name: 'van-sku-actions',
components: {
[Button.name]: Button
},
props: { props: {
skuEventBus: Object, skuEventBus: Object,
showAddCartBtn: Boolean, showAddCartBtn: Boolean,

View File

@ -0,0 +1,10 @@
import deepAssign from './deep-assign';
export default function deepClone(obj) {
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item));
} else if (typeof obj === 'object') {
return deepAssign({}, obj);
}
return obj;
}

View File

@ -1,7 +1,9 @@
@import './common/var.css'; @import './common/var.css';
@import './mixins/ellipsis.css';
.van-picker { .van-picker {
overflow: hidden; overflow: hidden;
user-select: none;
background-color: $white; background-color: $white;
&__toolbar { &__toolbar {
@ -12,6 +14,7 @@
&__cancel, &__cancel,
&__confirm { &__confirm {
color: $blue;
padding: 0 15px; padding: 0 15px;
&:active { &:active {
@ -20,132 +23,56 @@
} }
&__cancel { &__cancel {
color: $blue;
float: left; float: left;
} }
&__confirm { &__confirm {
color: $blue;
float: right; float: right;
} }
&__title { &__title {
height: 40px;
padding: 0 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
word-break: break-all;
text-align: center; text-align: center;
@mixin ellipsis;
} }
&__columns { &__columns {
display: flex;
position: relative; position: relative;
overflow: hidden;
&--1 {
.van-picker-column {
width: 100%;
}
}
&--2 {
.van-picker-column {
width: 50%;
}
}
&--3 {
.van-picker-column {
width: 33.333%;
}
}
&--4 {
.van-picker-column {
width: 25%;
}
}
&--5 {
.van-picker-column {
width: 20%;
}
}
}
.van-picker-center-highlight {
box-sizing: border-box;
position: absolute;
left: 0;
width: 100%;
top: 50%;
margin-top: -18px;
pointer-events: none;
}
.van-picker-center-highlight:before,
.van-picker-center-highlight:after {
content: '';
position: absolute;
height: 1px;
width: 100%;
background-color: #eaeaea;
display: block;
transform: scaleY(0.5);
}
.van-picker-center-highlight:before {
left: 0;
top: 0;
bottom: auto;
right: auto;
}
.van-picker-center-highlight:after {
left: 0;
bottom: 0;
right: auto;
top: auto;
} }
&-column { &-column {
font-size: 18px; flex: 1;
overflow: hidden; overflow: hidden;
font-size: 18px;
position: relative; position: relative;
max-height: 100%;
float: left;
text-align: center; text-align: center;
&__item { ul {
height: 44px;
line-height: 44px;
padding: 0 10px;
white-space: nowrap;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
color: #707274;
left: 0;
top: 0;
width: 100%;
box-sizing: border-box; box-sizing: border-box;
transition-duration: .3s; }
&--selected { li {
color: $black; padding: 0 10px;
} color: $gray-darker;
@mixin ellipsis;
}
li&--selected {
color: $black;
}
li&--disabled {
opacity: .3;
}
&__frame {
top: 50%;
left: 0;
width: 100%;
z-index: 1;
position: absolute;
pointer-events: none;
transform: translateY(-50%);
} }
} }
.picker-column-wrapper {
transition-duration: 0.3s;
transition-timing-function: ease-out;
}
.picker-column-wrapper.dragging,
.picker-column-wrapper.dragging .picker-item {
transition-duration: 0s;
}
} }

View File

@ -174,35 +174,7 @@
/* sku actions */ /* sku actions */
&-actions { &-actions {
display: flex;
margin-top: 10px; margin-top: 10px;
font-size: 0;
}
&__add-cart-btn {
width: 50%;
height: 50px;
padding: 0;
border: 0;
background: #f85;
color: $white;
font-size: 16px;
line-height: 50px;
text-align: center;
& + .van-sku__buy-btn {
width: 50%;
}
}
&__buy-btn {
width: 100%;
height: 50px;
padding: 0;
border: 0;
background: $red;
color: $white;
font-size: 16px;
line-height: 50px;
text-align: center;
} }
} }

View File

@ -1,6 +1,7 @@
import Area from 'packages/area'; import Area from 'packages/area';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import AreaList from '../mock/area.json'; import AreaList from '../mock/area.json';
import { setTimeout } from 'timers';
describe('Area', () => { describe('Area', () => {
let wrapper; let wrapper;
@ -54,10 +55,10 @@ describe('Area', () => {
wrapper.setProps({ wrapper.setProps({
value: '110102' value: '110102'
}); });
wrapper.vm.$nextTick(() => { setTimeout(() => {
expect(wrapper.vm.$refs.picker.getColumnValue(2).code).to.equal('110102'); expect(wrapper.vm.$refs.picker.getColumnValue(2).code).to.equal('110102');
done(); done();
}); }, 50);
}); });
it('create an area with invalid areaList', () => { it('create an area with invalid areaList', () => {

View File

@ -1,15 +1,6 @@
import DatetimePicker from 'packages/datetime-picker'; import DatetimePicker from 'packages/datetime-picker';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import { triggerTouch } from '../utils'; import { dragHelper } from '../utils';
const dragHelper = (el, position) => {
triggerTouch(el, 'touchstart', 0, 0);
triggerTouch(el, 'touchmove', 0, position / 4);
triggerTouch(el, 'touchmove', 0, position / 3);
triggerTouch(el, 'touchmove', 0, position / 2);
triggerTouch(el, 'touchmove', 0, position);
triggerTouch(el, 'touchend', 0, position);
};
const testTime = '10:00'; const testTime = '10:00';
const testDate = new Date('2017/03/10 10:00'); const testDate = new Date('2017/03/10 10:00');
@ -64,12 +55,12 @@ describe('DatetimePicker', () => {
} }
}); });
const [hour, minute] = wrapper.find('.van-picker-column-wrapper'); const [hour, minute] = wrapper.find('.van-picker-column ul');
dragHelper(hour, -50); dragHelper(hour, -50);
dragHelper(minute, -50); dragHelper(minute, -50);
setTimeout(() => { setTimeout(() => {
expect(wrapper.vm.innerValue).to.equal('5:05'); expect(wrapper.vm.innerValue).to.equal('10:01');
done(); done();
}, 10); }, 10);
}); });
@ -86,7 +77,7 @@ describe('DatetimePicker', () => {
}); });
setTimeout(() => { setTimeout(() => {
const [year, month, day] = wrapper.find('.van-picker-column-wrapper'); const [year, month, day] = wrapper.find('.van-picker-column ul');
dragHelper(year, -50); dragHelper(year, -50);
dragHelper(month, -50); dragHelper(month, -50);
dragHelper(day, -50); dragHelper(day, -50);
@ -94,9 +85,9 @@ describe('DatetimePicker', () => {
const newYear = wrapper.vm.innerValue.getFullYear(); const newYear = wrapper.vm.innerValue.getFullYear();
const newMonth = wrapper.vm.innerValue.getMonth() + 1; const newMonth = wrapper.vm.innerValue.getMonth() + 1;
const newDay = wrapper.vm.innerValue.getDate(); const newDay = wrapper.vm.innerValue.getDate();
expect(newYear).to.equal(2022); expect(newYear).to.equal(2018);
expect(newMonth).to.equal(8); expect(newMonth).to.equal(4);
expect(newDay).to.equal(15); expect(newDay).to.equal(1);
done(); done();
}, 10); }, 10);
}, 10); }, 10);
@ -114,7 +105,7 @@ describe('DatetimePicker', () => {
}); });
setTimeout(() => { setTimeout(() => {
const [year, month, day, hour, minute] = wrapper.find('.van-picker-column-wrapper'); const [year, month, day, hour, minute] = wrapper.find('.van-picker-column ul');
dragHelper(year, -50); dragHelper(year, -50);
dragHelper(month, -50); dragHelper(month, -50);
dragHelper(day, -50); dragHelper(day, -50);
@ -126,11 +117,11 @@ describe('DatetimePicker', () => {
const newDay = wrapper.vm.innerValue.getDate(); const newDay = wrapper.vm.innerValue.getDate();
const newHour = wrapper.vm.innerValue.getHours(); const newHour = wrapper.vm.innerValue.getHours();
const newMinute = wrapper.vm.innerValue.getMinutes(); const newMinute = wrapper.vm.innerValue.getMinutes();
expect(newYear).to.equal(2022); expect(newYear).to.equal(2018);
expect(newMonth).to.equal(8); expect(newMonth).to.equal(4);
expect(newDay).to.equal(15); expect(newDay).to.equal(1);
expect(newHour).to.equal(15); expect(newHour).to.equal(11);
expect(newMinute).to.equal(5); expect(newMinute).to.equal(1);
done(); done();
}, 10); }, 10);
}, 10); }, 10);

View File

@ -1,8 +1,7 @@
import Picker from 'packages/picker'; import Picker from 'packages/picker';
import PickerColumn from 'packages/picker/PickerColumn'; import PickerColumn from 'packages/picker/PickerColumn';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import { dragHelper } from '../utils';
const itemHeight = 44;
const pickerColumns = [ const pickerColumns = [
{ {
@ -29,7 +28,6 @@ describe('Picker', () => {
}); });
expect(wrapper.hasClass('van-picker')).to.be.true; expect(wrapper.hasClass('van-picker')).to.be.true;
expect(wrapper.contains('.van-picker__columns--2')).to.be.true;
expect(wrapper.vm.getColumnValues(0).length).to.equal(2); expect(wrapper.vm.getColumnValues(0).length).to.equal(2);
expect(wrapper.vm.getValues().length).to.equal(2); expect(wrapper.vm.getValues().length).to.equal(2);
@ -42,7 +40,6 @@ describe('Picker', () => {
} }
}); });
expect(wrapper.contains('.van-picker__columns--2')).to.be.true;
expect(wrapper.vm.getColumnValues(0).length).to.equal(2); expect(wrapper.vm.getColumnValues(0).length).to.equal(2);
expect(wrapper.vm.getColumnValues(1).length).to.equal(6); expect(wrapper.vm.getColumnValues(1).length).to.equal(6);
@ -52,16 +49,25 @@ describe('Picker', () => {
wrapper.vm.setColumnValue(0, 'normal'); wrapper.vm.setColumnValue(0, 'normal');
expect(wrapper.vm.getColumnValue(0)).to.equal('normal'); expect(wrapper.vm.getColumnValue(0)).to.equal('normal');
wrapper.vm.setColumnIndex(0, 0);
expect(wrapper.vm.getColumnValue(0)).to.equal('vip');
wrapper.vm.setColumnValue(1, '1991'); wrapper.vm.setColumnValue(1, '1991');
expect(wrapper.vm.getColumnValue(1)).to.equal('1991'); expect(wrapper.vm.getColumnValue(1)).to.equal('1991');
wrapper.vm.setColumnValues(0, ['vip', 'normal', 'other']); wrapper.vm.setColumnValues(0, ['vip', 'normal', 'other']);
expect(wrapper.vm.getColumnValues(0).length).to.equal(3); expect(wrapper.vm.getColumnValues(0).length).to.equal(3);
expect(wrapper.vm.getValues().length).to.equal(2); expect(wrapper.vm.getValues().length).to.equal(2);
wrapper.vm.setValues(['vip', '1992']); wrapper.vm.setValues(['vip', '1992']);
expect(wrapper.vm.getColumnValue(0)).to.equal('vip'); expect(wrapper.vm.getColumnIndex(0)).to.equal(0);
expect(wrapper.vm.getColumnValue(1)).to.equal('1992'); expect(wrapper.vm.getColumnIndex(1)).to.equal(2);
expect(wrapper.vm.getColumnIndex(2)).to.equal(undefined);
wrapper.vm.setIndexes([1, 4]);
expect(wrapper.vm.getColumnValue(0)).to.equal('normal');
expect(wrapper.vm.getColumnValue(1)).to.equal('1994');
expect(wrapper.vm.getColumnValue(2)).to.equal(undefined);
}); });
it('create a invalid columns picker', () => { it('create a invalid columns picker', () => {
@ -72,7 +78,7 @@ describe('Picker', () => {
}); });
expect(wrapper.hasClass('van-picker')).to.be.true; expect(wrapper.hasClass('van-picker')).to.be.true;
expect(wrapper.vm.values.length).to.equal(0); expect(wrapper.vm.currentColumns.length).to.equal(0);
}); });
it('set invalid index columns', () => { it('set invalid index columns', () => {
@ -99,10 +105,7 @@ describe('Picker', () => {
}); });
const eventStub = sinon.stub(wrapper.vm, '$emit'); const eventStub = sinon.stub(wrapper.vm, '$emit');
const firstColumn = wrapper.find(PickerColumn)[0]; wrapper.vm.setColumnValue(0, 'normal');
firstColumn.vm.currentValue = 'normal';
firstColumn.update();
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
expect(eventStub.calledOnce).to.be.true; expect(eventStub.calledOnce).to.be.true;
expect(eventStub.calledWith('change')); expect(eventStub.calledWith('change'));
@ -119,7 +122,7 @@ describe('Picker', () => {
expect(wrapper.hasClass('van-picker')).to.be.true; expect(wrapper.hasClass('van-picker')).to.be.true;
expect(wrapper.contains('.van-picker__toolbar')).to.be.true; expect(wrapper.contains('.van-picker__toolbar')).to.be.true;
expect(wrapper.vm.values.length).to.equal(0); expect(wrapper.vm.currentColumns.length).to.equal(0);
const eventStub = sinon.stub(wrapper.vm, '$emit'); const eventStub = sinon.stub(wrapper.vm, '$emit');
const cancelBtn = wrapper.find('.van-picker__cancel')[0]; const cancelBtn = wrapper.find('.van-picker__cancel')[0];
@ -164,25 +167,20 @@ describe('PickerColumn', () => {
wrapper = mount(PickerColumn); wrapper = mount(PickerColumn);
expect(wrapper.hasClass('van-picker-column')).to.be.true; expect(wrapper.hasClass('van-picker-column')).to.be.true;
expect(wrapper.vm.values.length).to.equal(0); expect(wrapper.vm.options.length).to.equal(0);
expect(wrapper.vm.visibleContentHeight).to.equal(itemHeight * 5);
expect(wrapper.vm.dragRange[0]).to.equal(3 * itemHeight);
expect(wrapper.vm.dragRange[1]).to.equal(2 * itemHeight);
}); });
it('change picker-column value', (done) => { it('change picker-column value', (done) => {
wrapper = mount(PickerColumn, { wrapper = mount(PickerColumn, {
propsData: { propsData: {
values: [1, 2, 3, 4, 5], options: [1, 2, 3, 4, 5],
value: 1 value: 1
} }
}); });
expect(wrapper.hasClass('van-picker-column')).to.be.true; expect(wrapper.vm.options.length).to.equal(5);
expect(wrapper.vm.values.length).to.equal(5);
wrapper.vm.value = 3; wrapper.vm.setValue(3);
wrapper.update();
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
expect(wrapper.vm.currentValue).to.equal(3); expect(wrapper.vm.currentValue).to.equal(3);
done(); done();
@ -192,77 +190,46 @@ describe('PickerColumn', () => {
it('change picker-column values', (done) => { it('change picker-column values', (done) => {
wrapper = mount(PickerColumn); wrapper = mount(PickerColumn);
expect(wrapper.hasClass('van-picker-column')).to.be.true; expect(wrapper.vm.options.length).to.equal(0);
expect(wrapper.vm.values.length).to.equal(0);
wrapper.vm.values = [1, 2]; wrapper.vm.options = [1, 2];
wrapper.update();
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
expect(wrapper.vm.values.length).to.equal(2); expect(wrapper.vm.options.length).to.equal(2);
expect(wrapper.vm.currentValues.length).to.equal(2);
done(); done();
}); });
}); });
it('create a picker test translate', () => { it('select disabled options', () => {
wrapper = mount(PickerColumn, { wrapper = mount(PickerColumn, {
propsData: { propsData: {
values: [1, 2, 3, 4, 5], options: [
value: 1 { text: '1', disabled: true },
{ text: '2' },
{ text: '3', disabled: true },
{ text: '4', disabled: true }
],
valueKey: 'text'
} }
}); });
expect(wrapper.vm.currentIndex).to.equal(1);
expect(wrapper.vm.values.length).to.equal(5); wrapper.vm.setIndex(3);
expect(wrapper.vm.value2Translate(2)).to.equal((1 - Math.floor(5 / 2)) * (-itemHeight)); expect(wrapper.vm.currentIndex).to.equal(1);
expect(wrapper.vm.translate2Value(0)).to.equal(3);
}); });
it('test draggable', done => { it('drag options', () => {
wrapper = mount(PickerColumn, { wrapper = mount(PickerColumn, {
propsData: { propsData: {
values: [1, 2, 3, 4, 5] options: pickerColumns[1].values
}, }
attachToDocument: true
}); });
expect(wrapper.vm.currentIndex).to.equal(0);
expect(wrapper.vm.values.length).to.equal(5); const column = wrapper.find('.van-picker-column ul')[0];
dragHelper(column, 0);
expect(wrapper.vm.currentIndex).to.equal(0);
setTimeout(() => { dragHelper(column, -100);
const nColumn = wrapper.find('.van-picker-column-wrapper')[0]; expect(wrapper.vm.currentIndex).to.equal(2);
const eventMouseObject = new window.Event('mousedown');
eventMouseObject.pageY = 0;
nColumn.element.dispatchEvent(eventMouseObject);
const eventTouchObject = new window.Event('touchstart');
eventTouchObject.changedTouches = [{ pageY: 0 }];
nColumn.element.dispatchEvent(eventTouchObject);
}, 500);
setTimeout(() => {
const nColumn = wrapper.find('.van-picker-column-wrapper')[0];
const eventMouseMoveObject = new window.Event('mousemove');
eventMouseMoveObject.pageY = 40;
document.dispatchEvent(eventMouseMoveObject);
const eventObject = new window.Event('touchmove');
eventObject.changedTouches = [{ pageY: 40 }];
nColumn.element.dispatchEvent(eventObject);
// 结束滚动
const eventMouseUpObject = new window.Event('mouseup');
document.dispatchEvent(eventMouseUpObject);
const eventEndObject = new window.Event('touchend');
eventEndObject.changedTouches = [{}];
nColumn.element.dispatchEvent(eventEndObject);
}, 1000);
setTimeout(() => {
const nItem = wrapper.find('.van-picker-column__item');
expect(nItem[1].hasClass('van-picker-column__item--selected')).to.be.true;
done();
}, 1200);
}); });
}); });

View File

@ -82,8 +82,8 @@ describe('Sku', (done) => {
const buyCallback = sinon.spy(); const buyCallback = sinon.spy();
const addCartCallback = sinon.spy(); const addCartCallback = sinon.spy();
const buyBtn = wrapper.find('.van-sku__buy-btn')[0]; const buyBtn = wrapper.find('.van-button--bottom-action')[1];
const addCartBtn = wrapper.find('.van-sku__add-cart-btn')[0]; const addCartBtn = wrapper.find('.van-button--bottom-action')[0];
wrapper.vm.$on('buy-clicked', buyCallback); wrapper.vm.$on('buy-clicked', buyCallback);
wrapper.vm.$on('add-cart', addCartCallback); wrapper.vm.$on('add-cart', addCartCallback);
@ -187,7 +187,7 @@ describe('Sku', (done) => {
} }
}); });
const buyBtn = wrapper.find('.van-sku__buy-btn')[0]; const buyBtn = wrapper.find('.van-button--bottom-action')[0];
const skuMessages = wrapper.find('.van-sku-messages')[0]; const skuMessages = wrapper.find('.van-sku-messages')[0];
const inputs = skuMessages.find('input'); const inputs = skuMessages.find('input');
const textarea = skuMessages.find('textarea')[0]; const textarea = skuMessages.find('textarea')[0];
@ -272,7 +272,7 @@ describe('Sku', (done) => {
} }
}); });
const buyBtn = wrapper.find('.van-sku__buy-btn')[0]; const buyBtn = wrapper.find('.van-button--bottom-action')[0];
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
buyBtn.trigger('click'); buyBtn.trigger('click');

View File

@ -73,3 +73,12 @@ export function triggerTouch(wrapper, eventName, x, y) {
el.dispatchEvent(event); el.dispatchEvent(event);
} }
export function dragHelper(el, position) {
triggerTouch(el, 'touchstart', 0, 0);
triggerTouch(el, 'touchmove', 0, position / 4);
triggerTouch(el, 'touchmove', 0, position / 3);
triggerTouch(el, 'touchmove', 0, position / 2);
triggerTouch(el, 'touchmove', 0, position);
triggerTouch(el, 'touchend', 0, position);
}

View File

@ -56,11 +56,11 @@ ajv-keywords@^1.0.0:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
ajv-keywords@^2.0.0: ajv-keywords@^2.0.0, ajv-keywords@^2.1.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: ajv@^4.7.0, ajv@^4.9.1:
version "4.11.8" version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies: dependencies:
@ -300,7 +300,7 @@ async@1.x, async@^1.4.0, async@^1.5.2:
version "1.5.2" version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@2.6.0, async@^2.1.2: async@2.6.0, async@^2.1.2, async@^2.4.1:
version "2.6.0" version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies: dependencies:
@ -325,15 +325,15 @@ autoprefixer@^6.3.1:
postcss "^5.2.16" postcss "^5.2.16"
postcss-value-parser "^3.2.3" postcss-value-parser "^3.2.3"
autoprefixer@^7.1.6: autoprefixer@^7.2.1:
version "7.1.6" version "7.2.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.1.tgz#906b1447a0e6a9e13b371f7909bc4e36da5a5a79"
dependencies: dependencies:
browserslist "^2.5.1" browserslist "^2.9.1"
caniuse-lite "^1.0.30000748" caniuse-lite "^1.0.30000777"
normalize-range "^0.1.2" normalize-range "^0.1.2"
num2fraction "^1.2.2" num2fraction "^1.2.2"
postcss "^6.0.13" postcss "^6.0.14"
postcss-value-parser "^3.2.3" postcss-value-parser "^3.2.3"
avoriaz@2.0.0: avoriaz@2.0.0:
@ -1109,7 +1109,7 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-db "^1.0.30000639" caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7" electron-to-chromium "^1.2.7"
browserslist@^2.1.2, browserslist@^2.5.1: browserslist@^2.1.2, browserslist@^2.9.1:
version "2.9.1" version "2.9.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.9.1.tgz#b72d3982ab01b5cd24da62ff6d45573886aff275" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.9.1.tgz#b72d3982ab01b5cd24da62ff6d45573886aff275"
dependencies: dependencies:
@ -1144,6 +1144,15 @@ bytes@3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
cache-loader@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-1.2.0.tgz#cdc313ae53b3c13ce8ee0c9296cf16c736b15252"
dependencies:
async "^2.4.1"
loader-utils "^1.1.0"
mkdirp "^0.5.1"
schema-utils "^0.4.2"
caller-path@^0.1.0: caller-path@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
@ -1205,10 +1214,14 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000775" version "1.0.30000775"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000775.tgz#04bccdd0214edf25b97f61a096609f7ad6904333" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000775.tgz#04bccdd0214edf25b97f61a096609f7ad6904333"
caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000770: caniuse-lite@^1.0.30000770:
version "1.0.30000775" version "1.0.30000775"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000775.tgz#74d27feddc47f3c84cfbcb130c3092a35ebc2de2" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000775.tgz#74d27feddc47f3c84cfbcb130c3092a35ebc2de2"
caniuse-lite@^1.0.30000777:
version "1.0.30000778"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000778.tgz#f1e7cb8b13b1f6744402291d75f0bcd4c3160369"
caseless@~0.12.0: caseless@~0.12.0:
version "0.12.0" version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@ -2711,14 +2724,14 @@ extglob@^0.3.1:
dependencies: dependencies:
is-extglob "^1.0.0" is-extglob "^1.0.0"
extract-text-webpack-plugin@2.0.0: extract-text-webpack-plugin@3.0.2:
version "2.0.0" version "3.0.2"
resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.0.0.tgz#8640f72609800a3528f13a2a9634d566a5c1ae60" resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
dependencies: dependencies:
ajv "^4.11.2" async "^2.4.1"
async "^2.1.2" loader-utils "^1.1.0"
loader-utils "^1.0.2" schema-utils "^0.3.0"
webpack-sources "^0.1.0" webpack-sources "^1.0.1"
extract-zip@^1.6.5: extract-zip@^1.6.5:
version "1.6.6" version "1.6.6"
@ -6729,6 +6742,14 @@ schema-utils@^0.3.0:
dependencies: dependencies:
ajv "^5.0.0" ajv "^5.0.0"
schema-utils@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.2.tgz#86d92aedf4dfc51c9b321ef16bd33a9417b122d0"
dependencies:
ajv "^5.0.0"
ajv-keywords "^2.1.0"
chalk "^2.3.0"
select-hose@^2.0.0: select-hose@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@ -6952,10 +6973,6 @@ source-list-map@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
source-list-map@~0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
source-map-support@^0.4.15: source-map-support@^0.4.15:
version "0.4.18" version "0.4.18"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
@ -6968,7 +6985,7 @@ source-map@0.4.x, source-map@^0.4.4:
dependencies: dependencies:
amdefine ">=0.0.4" amdefine ">=0.0.4"
source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6: source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6:
version "0.5.7" version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@ -7848,13 +7865,6 @@ webpack-merge@^4.1.1:
dependencies: dependencies:
lodash "^4.17.4" lodash "^4.17.4"
webpack-sources@^0.1.0:
version "0.1.5"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750"
dependencies:
source-list-map "~0.1.7"
source-map "~0.5.3"
webpack-sources@^1.0.1: webpack-sources@^1.0.1:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
@ -7862,9 +7872,9 @@ webpack-sources@^1.0.1:
source-list-map "^2.0.0" source-list-map "^2.0.0"
source-map "~0.6.1" source-map "~0.6.1"
webpack@^3.8.1: webpack@^3.9.1:
version "3.8.1" version "3.9.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.9.1.tgz#9a60aa544ed5d4d454c069e3f521aa007e02643c"
dependencies: dependencies:
acorn "^5.0.0" acorn "^5.0.0"
acorn-dynamic-import "^2.0.0" acorn-dynamic-import "^2.0.0"