Commit 99246a895497d26e552bf5633ae6c07c07335726
Committed by
GitHub
Merge pull request #340 from huixisheng/2.0
Support Breadcrumb and add test unit and optimize webpack config
Showing
56 changed files
with
362 additions
and
143 deletions
Show diff stats
.gitignore
README.md
@@ -53,7 +53,7 @@ | @@ -53,7 +53,7 @@ | ||
53 | - [x] Tabs | 53 | - [x] Tabs |
54 | - [x] Dropdown | 54 | - [x] Dropdown |
55 | - [ ] Page | 55 | - [ ] Page |
56 | -- [ ] Breadcrumb | 56 | +- [x] Breadcrumb |
57 | - [x] Steps | 57 | - [x] Steps |
58 | - [ ] LoadingBar | 58 | - [ ] LoadingBar |
59 | - [x] Circle | 59 | - [x] Circle |
@@ -76,7 +76,7 @@ | @@ -76,7 +76,7 @@ | ||
76 | 76 | ||
77 | ## Install | 77 | ## Install |
78 | 78 | ||
79 | -### Install vue-webpack project in the first place | 79 | +### Install vue-webpack project in the first place |
80 | 80 | ||
81 | Use [iview-project](https://github.com/iview/iview-project)(Recommended) Or [vue-cli](https://github.com/vuejs/vue-cli) | 81 | Use [iview-project](https://github.com/iview/iview-project)(Recommended) Or [vue-cli](https://github.com/vuejs/vue-cli) |
82 | 82 |
1 | +/** | ||
2 | + * 公共配置 | ||
3 | + */ | ||
4 | +var webpack = require('webpack'); | ||
5 | +var path = require('path'); | ||
6 | +function resolve (dir) { | ||
7 | + return path.join(__dirname, '..', dir) | ||
8 | +} | ||
9 | + | ||
10 | +module.exports = { | ||
11 | + // 加载器 | ||
12 | + module: { | ||
13 | + // https://doc.webpack-china.org/guides/migrating/#module-loaders-module-rules | ||
14 | + rules: [ | ||
15 | + { | ||
16 | + // https://vue-loader.vuejs.org/en/configurations/extract-css.html | ||
17 | + test: /\.vue$/, | ||
18 | + loader: 'vue-loader', | ||
19 | + options: { | ||
20 | + loaders: { | ||
21 | + css: 'vue-style-loader!css-loader', | ||
22 | + less: 'vue-style-loader!css-loader!less-loader' | ||
23 | + }, | ||
24 | + postLoaders: { | ||
25 | + html: 'babel-loader' | ||
26 | + } | ||
27 | + } | ||
28 | + }, | ||
29 | + { | ||
30 | + test: /\.js$/, | ||
31 | + loader: 'babel-loader', exclude: /node_modules/ | ||
32 | + }, | ||
33 | + { | ||
34 | + test: /\.css$/, | ||
35 | + use: [ | ||
36 | + 'style-loader', | ||
37 | + 'css-loader', | ||
38 | + 'autoprefixer-loader' | ||
39 | + ] | ||
40 | + }, | ||
41 | + { | ||
42 | + test: /\.less$/, | ||
43 | + use: [ | ||
44 | + 'style-loader', | ||
45 | + 'css-loader', | ||
46 | + 'less-loader' | ||
47 | + ] | ||
48 | + }, | ||
49 | + { | ||
50 | + test: /\.scss$/, | ||
51 | + use: [ | ||
52 | + 'style-loader', | ||
53 | + 'css-loader', | ||
54 | + 'sass-loader?sourceMap' | ||
55 | + ] | ||
56 | + }, | ||
57 | + { test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader: 'url-loader?limit=8192'}, | ||
58 | + { test: /\.(html|tpl)$/, loader: 'html-loader' } | ||
59 | + ] | ||
60 | + }, | ||
61 | + resolve: { | ||
62 | + extensions: ['.js', '.vue'], | ||
63 | + alias: { | ||
64 | + 'vue': 'vue/dist/vue.esm.js', | ||
65 | + '@': resolve('src'), | ||
66 | + } | ||
67 | + } | ||
68 | +}; |
build/webpack.dev.config.js
@@ -6,109 +6,37 @@ var path = require('path'); | @@ -6,109 +6,37 @@ var path = require('path'); | ||
6 | var webpack = require('webpack'); | 6 | var webpack = require('webpack'); |
7 | // var ExtractTextPlugin = require('extract-text-webpack-plugin'); | 7 | // var ExtractTextPlugin = require('extract-text-webpack-plugin'); |
8 | var HtmlWebpackPlugin = require('html-webpack-plugin'); | 8 | var HtmlWebpackPlugin = require('html-webpack-plugin'); |
9 | +var merge = require('webpack-merge') | ||
10 | +var webpackBaseConfig = require('./webpack.base.config.js'); | ||
11 | +var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') | ||
9 | 12 | ||
10 | -module.exports = { | 13 | + |
14 | +module.exports = merge(webpackBaseConfig, { | ||
11 | // 入口 | 15 | // 入口 |
12 | entry: { | 16 | entry: { |
13 | - main: './test/main', | 17 | + main: './examples/main', |
14 | vendors: ['vue', 'vue-router'] | 18 | vendors: ['vue', 'vue-router'] |
15 | }, | 19 | }, |
16 | // 输出 | 20 | // 输出 |
17 | output: { | 21 | output: { |
18 | - path: path.join(__dirname, '../test/dist'), | 22 | + path: path.join(__dirname, '../examples/dist'), |
19 | publicPath: '', | 23 | publicPath: '', |
20 | filename: '[name].js', | 24 | filename: '[name].js', |
21 | chunkFilename: '[name].chunk.js' | 25 | chunkFilename: '[name].chunk.js' |
22 | }, | 26 | }, |
23 | - // 加载器 | ||
24 | - module: { | ||
25 | - // https://doc.webpack-china.org/guides/migrating/#module-loaders-module-rules | ||
26 | - rules: [ | ||
27 | - { | ||
28 | - // https://vue-loader.vuejs.org/en/configurations/extract-css.html | ||
29 | - test: /\.vue$/, | ||
30 | - loader: 'vue-loader', | ||
31 | - options: { | ||
32 | - loaders: { | ||
33 | - css: 'vue-style-loader!css-loader', | ||
34 | - less: 'vue-style-loader!css-loader!less-loader' | ||
35 | - }, | ||
36 | - postLoaders: { | ||
37 | - html: 'babel-loader' | ||
38 | - } | ||
39 | - } | ||
40 | - }, | ||
41 | - // { test: /\.vue$/, loader: 'vue' }, | ||
42 | - // Module build failed: Error: The node API for `babel` has been moved to `babel-core`. | ||
43 | - // https://github.com/babel/babel-loader/blob/master/README.md#the-node-api-for-babel-has-been-moved-to-babel-core | ||
44 | - { | ||
45 | - test: /\.js$/, | ||
46 | - loader: 'babel-loader', exclude: /node_modules/ | ||
47 | - }, | ||
48 | - { | ||
49 | - test: /\.css$/, | ||
50 | - use: [ | ||
51 | - 'style-loader', | ||
52 | - 'css-loader', | ||
53 | - 'autoprefixer-loader' | ||
54 | - ] | ||
55 | - }, | ||
56 | - { | ||
57 | - test: /\.less$/, | ||
58 | - use: [ | ||
59 | - 'style-loader', | ||
60 | - 'css-loader', | ||
61 | - 'less-loader' | ||
62 | - ] | ||
63 | - // loader: 'style!css!less' | ||
64 | - }, | ||
65 | - { | ||
66 | - test: /\.scss$/, | ||
67 | - use: [ | ||
68 | - 'style-loader', | ||
69 | - 'css-loader', | ||
70 | - 'sass-loader?sourceMap' | ||
71 | - ] | ||
72 | - // loader: 'style!css!sass?sourceMap' | ||
73 | - }, | ||
74 | - { test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader: 'url-loader?limit=8192'}, | ||
75 | - { test: /\.(html|tpl)$/, loader: 'html-loader' } | ||
76 | - ] | ||
77 | - }, | ||
78 | - // vue: { | ||
79 | - // loaders: { | ||
80 | - // css: ExtractTextPlugin.extract( | ||
81 | - // "style-loader", | ||
82 | - // "css-loader?sourceMap", | ||
83 | - // { | ||
84 | - // publicPath: "/test/dist/" | ||
85 | - // } | ||
86 | - // ), | ||
87 | - // less: ExtractTextPlugin.extract( | ||
88 | - // 'vue-style-loader', | ||
89 | - // 'css-loader!less-loader' | ||
90 | - // ), | ||
91 | - // js: 'babel' | ||
92 | - // } | ||
93 | - // }, | ||
94 | resolve: { | 27 | resolve: { |
95 | - // require时省略的扩展名,如:require('module') 不需要module.js | ||
96 | - extensions: ['.js', '.vue'], | ||
97 | alias: { | 28 | alias: { |
98 | iview: '../../src/index', | 29 | iview: '../../src/index', |
99 | vue: 'vue/dist/vue.js' | 30 | vue: 'vue/dist/vue.js' |
100 | } | 31 | } |
101 | }, | 32 | }, |
102 | plugins: [ | 33 | plugins: [ |
103 | - // new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true }), | ||
104 | - // new ExtractTextPlugin("[name].css",{ allChunks : true,resolve : ['modules'] }), // 提取CSS | ||
105 | - // https://doc.webpack-china.org/plugins/commons-chunk-plugin/ | ||
106 | new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', filename: 'vendor.bundle.js' }), | 34 | new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', filename: 'vendor.bundle.js' }), |
107 | new HtmlWebpackPlugin({ | 35 | new HtmlWebpackPlugin({ |
108 | inject: true, | 36 | inject: true, |
109 | - filename: path.join(__dirname, '../test/dist/index.html'), | ||
110 | - template: path.join(__dirname, '../test/index.html') // 模版文件 | ||
111 | - }) | ||
112 | - // new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js'), // 提取第三方库 | 37 | + filename: path.join(__dirname, '../examples/dist/index.html'), |
38 | + template: path.join(__dirname, '../examples/index.html') | ||
39 | + }), | ||
40 | + new FriendlyErrorsPlugin() | ||
113 | ] | 41 | ] |
114 | -}; | 42 | +}); |
build/webpack.dist.dev.config.js
1 | var path = require('path'); | 1 | var path = require('path'); |
2 | var webpack = require('webpack'); | 2 | var webpack = require('webpack'); |
3 | +var merge = require('webpack-merge') | ||
4 | +var webpackBaseConfig = require('./webpack.base.config.js'); | ||
3 | 5 | ||
4 | -module.exports = { | 6 | +module.exports = merge(webpackBaseConfig, { |
5 | entry: { | 7 | entry: { |
6 | main: './src/index.js' | 8 | main: './src/index.js' |
7 | }, | 9 | }, |
@@ -21,26 +23,6 @@ module.exports = { | @@ -21,26 +23,6 @@ module.exports = { | ||
21 | amd: 'vue' | 23 | amd: 'vue' |
22 | } | 24 | } |
23 | }, | 25 | }, |
24 | - resolve: { | ||
25 | - extensions: ['.js', '.vue'] | ||
26 | - }, | ||
27 | - module: { | ||
28 | - rules: [ | ||
29 | - { | ||
30 | - test: /\.vue$/, | ||
31 | - loader: 'vue-loader', | ||
32 | - options: { | ||
33 | - postLoaders: { | ||
34 | - html: 'babel-loader' | ||
35 | - } | ||
36 | - } | ||
37 | - }, | ||
38 | - { | ||
39 | - test: /\.js$/, | ||
40 | - loader: 'babel-loader', exclude: /node_modules/ | ||
41 | - } | ||
42 | - ] | ||
43 | - }, | ||
44 | plugins: [ | 26 | plugins: [ |
45 | new webpack.DefinePlugin({ | 27 | new webpack.DefinePlugin({ |
46 | 'process.env': { | 28 | 'process.env': { |
@@ -48,4 +30,4 @@ module.exports = { | @@ -48,4 +30,4 @@ module.exports = { | ||
48 | } | 30 | } |
49 | }) | 31 | }) |
50 | ] | 32 | ] |
51 | -} | 33 | +}); |
build/webpack.dist.prod.config.js
1 | var path = require('path'); | 1 | var path = require('path'); |
2 | var webpack = require('webpack'); | 2 | var webpack = require('webpack'); |
3 | +var merge = require('webpack-merge') | ||
4 | +var webpackBaseConfig = require('./webpack.base.config.js'); | ||
3 | 5 | ||
4 | -module.exports = { | 6 | + |
7 | + | ||
8 | +module.exports = merge(webpackBaseConfig, { | ||
5 | entry: { | 9 | entry: { |
6 | main: './src/index.js' | 10 | main: './src/index.js' |
7 | }, | 11 | }, |
@@ -21,26 +25,6 @@ module.exports = { | @@ -21,26 +25,6 @@ module.exports = { | ||
21 | amd: 'vue' | 25 | amd: 'vue' |
22 | } | 26 | } |
23 | }, | 27 | }, |
24 | - resolve: { | ||
25 | - extensions: ['.js', '.vue'] | ||
26 | - }, | ||
27 | - module: { | ||
28 | - rules: [ | ||
29 | - { | ||
30 | - test: /\.vue$/, | ||
31 | - loader: 'vue-loader', | ||
32 | - options: { | ||
33 | - postLoaders: { | ||
34 | - html: 'babel-loader' | ||
35 | - } | ||
36 | - } | ||
37 | - }, | ||
38 | - { | ||
39 | - test: /\.js$/, | ||
40 | - loader: 'babel-loader', exclude: /node_modules/ | ||
41 | - } | ||
42 | - ] | ||
43 | - }, | ||
44 | plugins: [ | 28 | plugins: [ |
45 | new webpack.DefinePlugin({ | 29 | new webpack.DefinePlugin({ |
46 | 'process.env': { | 30 | 'process.env': { |
@@ -53,4 +37,4 @@ module.exports = { | @@ -53,4 +37,4 @@ module.exports = { | ||
53 | } | 37 | } |
54 | }) | 38 | }) |
55 | ] | 39 | ] |
56 | -} | 40 | +}); |
1 | +/** | ||
2 | + * 用于单元测试 | ||
3 | + */ | ||
4 | + | ||
5 | +var webpack = require('webpack') | ||
6 | +var merge = require('webpack-merge') | ||
7 | +var webpackBaseConfig = require('./webpack.base.config.js'); | ||
8 | + | ||
9 | + | ||
10 | +var webpackConfig = merge(webpackBaseConfig, { | ||
11 | + // use inline sourcemap for karma-sourcemap-loader | ||
12 | + devtool: '#inline-source-map', | ||
13 | + plugins: [ | ||
14 | + new webpack.DefinePlugin({ | ||
15 | + 'process.env': { | ||
16 | + NODE_ENV: '"testing"' | ||
17 | + } | ||
18 | + }) | ||
19 | + ] | ||
20 | +}) | ||
21 | + | ||
22 | +// no need for app entry during tests | ||
23 | +delete webpackConfig.entry | ||
24 | + | ||
25 | +module.exports = webpackConfig |
test/app.vue renamed to examples/app.vue
@@ -39,6 +39,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } | @@ -39,6 +39,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } | ||
39 | <li><router-link to="/poptip">Poptip</router-link></li> | 39 | <li><router-link to="/poptip">Poptip</router-link></li> |
40 | <li><router-link to="/slider">Slider</router-link></li> | 40 | <li><router-link to="/slider">Slider</router-link></li> |
41 | <li><router-link to="/dropdown">Dropdown</router-link></li> | 41 | <li><router-link to="/dropdown">Dropdown</router-link></li> |
42 | + <li><router-link to="/breadcrumb">Breadcrumb</router-link></li> | ||
42 | </ul> | 43 | </ul> |
43 | </nav> | 44 | </nav> |
44 | <router-view></router-view> | 45 | <router-view></router-view> |
test/index.html renamed to examples/index.html
test/main.js renamed to examples/main.js
@@ -120,6 +120,10 @@ const router = new VueRouter({ | @@ -120,6 +120,10 @@ const router = new VueRouter({ | ||
120 | { | 120 | { |
121 | path: '/dropdown', | 121 | path: '/dropdown', |
122 | component: require('./routers/dropdown.vue') | 122 | component: require('./routers/dropdown.vue') |
123 | + }, | ||
124 | + { | ||
125 | + path: '/breadcrumb', | ||
126 | + component: require('./routers/breadcrumb.vue') | ||
123 | } | 127 | } |
124 | ] | 128 | ] |
125 | }); | 129 | }); |
test/routers/affix.vue renamed to examples/routers/affix.vue
test/routers/alert.vue renamed to examples/routers/alert.vue
test/routers/badge.vue renamed to examples/routers/badge.vue
1 | +<style> | ||
2 | + .demo-breadcrumb-separator{ | ||
3 | + color: #ff5500; | ||
4 | + padding: 0 5px; | ||
5 | + } | ||
6 | +</style> | ||
7 | +<template> | ||
8 | +<div> | ||
9 | + <Breadcrumb separator="<b class='demo-breadcrumb-separator'>=></b>"> | ||
10 | + <Breadcrumb-item href="/">Home4</Breadcrumb-item> | ||
11 | + <Breadcrumb-item href="/components/breadcrumb">Components</Breadcrumb-item> | ||
12 | + <Breadcrumb-item>Breadcrumb</Breadcrumb-item> | ||
13 | + </Breadcrumb> | ||
14 | + <Breadcrumb separator=""> | ||
15 | + <Breadcrumb-item href="/"> | ||
16 | + <template>Home</template> | ||
17 | + <template slot="separator"> | ||
18 | + <b style="color: #ff5500;">-></b> | ||
19 | + </template> | ||
20 | + </Breadcrumb-item> | ||
21 | + <Breadcrumb-item href="/components/breadcrumb"> | ||
22 | + <template>Breadcrumb</template> | ||
23 | + <template slot="separator"> | ||
24 | + <b style="color: #ff5500;">-></b> | ||
25 | + </template> | ||
26 | + </Breadcrumb-item> | ||
27 | + <Breadcrumb-item>Breadcrumb</Breadcrumb-item> | ||
28 | + </Breadcrumb> | ||
29 | +</div> | ||
30 | +</template> | ||
31 | +<script> | ||
32 | + export default { | ||
33 | + | ||
34 | + } | ||
35 | +</script> | ||
0 | \ No newline at end of file | 36 | \ No newline at end of file |
test/routers/button.vue renamed to examples/routers/button.vue
test/routers/card.vue renamed to examples/routers/card.vue
test/routers/carousel.vue renamed to examples/routers/carousel.vue
test/routers/cascader.vue renamed to examples/routers/cascader.vue
test/routers/checkbox.vue renamed to examples/routers/checkbox.vue
test/routers/circle.vue renamed to examples/routers/circle.vue
test/routers/collapse.vue renamed to examples/routers/collapse.vue
test/routers/date.vue renamed to examples/routers/date.vue
test/routers/dropdown.vue renamed to examples/routers/dropdown.vue
test/routers/form.vue renamed to examples/routers/form.vue
test/routers/grid.vue renamed to examples/routers/grid.vue
test/routers/input-number.vue renamed to examples/routers/input-number.vue
test/routers/input.vue renamed to examples/routers/input.vue
test/routers/menu.vue renamed to examples/routers/menu.vue
test/routers/message.vue renamed to examples/routers/message.vue
test/routers/more.vue renamed to examples/routers/more.vue
test/routers/notice.vue renamed to examples/routers/notice.vue
test/routers/page.vue renamed to examples/routers/page.vue
test/routers/poptip.vue renamed to examples/routers/poptip.vue
test/routers/progress.vue renamed to examples/routers/progress.vue
test/routers/radio.vue renamed to examples/routers/radio.vue
test/routers/rate.vue renamed to examples/routers/rate.vue
test/routers/select.vue renamed to examples/routers/select.vue
test/routers/slider.vue renamed to examples/routers/slider.vue
test/routers/steps.vue renamed to examples/routers/steps.vue
test/routers/switch.vue renamed to examples/routers/switch.vue
test/routers/table.vue renamed to examples/routers/table.vue
test/routers/tabs.vue renamed to examples/routers/tabs.vue
test/routers/tag.vue renamed to examples/routers/tag.vue
test/routers/timeline.vue renamed to examples/routers/timeline.vue
test/routers/tooltip.vue renamed to examples/routers/tooltip.vue
test/routers/transfer.vue renamed to examples/routers/transfer.vue
test/routers/tree.vue renamed to examples/routers/tree.vue
test/routers/upload.vue renamed to examples/routers/upload.vue
package.json
@@ -25,7 +25,8 @@ | @@ -25,7 +25,8 @@ | ||
25 | "dist:prod": "webpack --config build/webpack.dist.prod.config.js", | 25 | "dist:prod": "webpack --config build/webpack.dist.prod.config.js", |
26 | "dist": "npm run dist:style && npm run dist:dev && npm run dist:prod", | 26 | "dist": "npm run dist:style && npm run dist:dev && npm run dist:prod", |
27 | "lint": "eslint --fix --ext .js,.vue src", | 27 | "lint": "eslint --fix --ext .js,.vue src", |
28 | - "test": "npm run dist && npm run lint", | 28 | + "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", |
29 | + "test": "npm run lint && npm run unit", | ||
29 | "prepublish": "npm run dist" | 30 | "prepublish": "npm run dist" |
30 | }, | 31 | }, |
31 | "repository": { | 32 | "repository": { |
@@ -54,11 +55,15 @@ | @@ -54,11 +55,15 @@ | ||
54 | "babel-plugin-transform-runtime": "^6.12.0", | 55 | "babel-plugin-transform-runtime": "^6.12.0", |
55 | "babel-preset-es2015": "^6.9.0", | 56 | "babel-preset-es2015": "^6.9.0", |
56 | "babel-runtime": "^6.11.6", | 57 | "babel-runtime": "^6.11.6", |
58 | + "chai": "^3.5.0", | ||
59 | + "cross-env": "^3.1.4", | ||
57 | "css-loader": "^0.23.1", | 60 | "css-loader": "^0.23.1", |
58 | "eslint": "^3.12.2", | 61 | "eslint": "^3.12.2", |
59 | "eslint-plugin-html": "^1.7.0", | 62 | "eslint-plugin-html": "^1.7.0", |
60 | "extract-text-webpack-plugin": "^2.0.0", | 63 | "extract-text-webpack-plugin": "^2.0.0", |
61 | "file-loader": "^0.8.5", | 64 | "file-loader": "^0.8.5", |
65 | + "friendly-errors-webpack-plugin": "^1.6.1", | ||
66 | + "function-bind": "^1.1.0", | ||
62 | "gulp": "^3.9.1", | 67 | "gulp": "^3.9.1", |
63 | "gulp-autoprefixer": "^3.1.1", | 68 | "gulp-autoprefixer": "^3.1.1", |
64 | "gulp-clean-css": "^2.0.13", | 69 | "gulp-clean-css": "^2.0.13", |
@@ -66,8 +71,21 @@ | @@ -66,8 +71,21 @@ | ||
66 | "gulp-rename": "^1.2.2", | 71 | "gulp-rename": "^1.2.2", |
67 | "html-loader": "^0.3.0", | 72 | "html-loader": "^0.3.0", |
68 | "html-webpack-plugin": "^2.28.0", | 73 | "html-webpack-plugin": "^2.28.0", |
74 | + "karma": "^1.4.1", | ||
75 | + "karma-coverage": "^1.1.1", | ||
76 | + "karma-mocha": "^1.3.0", | ||
77 | + "karma-phantomjs-launcher": "^1.0.2", | ||
78 | + "karma-sinon-chai": "^1.2.4", | ||
79 | + "karma-sourcemap-loader": "^0.3.7", | ||
80 | + "karma-spec-reporter": "0.0.26", | ||
81 | + "karma-webpack": "^2.0.2", | ||
69 | "less": "^2.7.1", | 82 | "less": "^2.7.1", |
70 | "less-loader": "^2.2.3", | 83 | "less-loader": "^2.2.3", |
84 | + "lolex": "^1.5.2", | ||
85 | + "mocha": "^3.2.0", | ||
86 | + "phantomjs-prebuilt": "^2.1.13", | ||
87 | + "sinon": "^1.17.7", | ||
88 | + "sinon-chai": "^2.8.0", | ||
71 | "style-loader": "^0.13.1", | 89 | "style-loader": "^0.13.1", |
72 | "url-loader": "^0.5.7", | 90 | "url-loader": "^0.5.7", |
73 | "vue": "^2.2.1", | 91 | "vue": "^2.2.1", |
@@ -78,6 +96,11 @@ | @@ -78,6 +96,11 @@ | ||
78 | "vue-style-loader": "^1.0.0", | 96 | "vue-style-loader": "^1.0.0", |
79 | "vue-template-compiler": "^2.2.1", | 97 | "vue-template-compiler": "^2.2.1", |
80 | "webpack": "^2.2.1", | 98 | "webpack": "^2.2.1", |
81 | - "webpack-dev-server": "^2.4.1" | 99 | + "webpack-dev-server": "^2.4.1", |
100 | + "webpack-merge": "^3.0.0" | ||
101 | + }, | ||
102 | + "engines": { | ||
103 | + "node": ">= 4.0.0", | ||
104 | + "npm": ">= 3.0.0" | ||
82 | } | 105 | } |
83 | } | 106 | } |
src/components/breadcrumb/breadcrumb-item.vue
@@ -6,8 +6,10 @@ | @@ -6,8 +6,10 @@ | ||
6 | <span v-else :class="linkClasses"> | 6 | <span v-else :class="linkClasses"> |
7 | <slot></slot> | 7 | <slot></slot> |
8 | </span> | 8 | </span> |
9 | - <span :class="separatorClasses"> | ||
10 | - <slot name="separator">{{{ separator }}}</slot> | 9 | + <span :class="separatorClasses" v-html="separator" v-if="!showSeparator"> |
10 | + </span> | ||
11 | + <span :class="separatorClasses" v-else> | ||
12 | + <slot name="separator"></slot> | ||
11 | </span> | 13 | </span> |
12 | </span> | 14 | </span> |
13 | </template> | 15 | </template> |
@@ -18,12 +20,17 @@ | @@ -18,12 +20,17 @@ | ||
18 | props: { | 20 | props: { |
19 | href: { | 21 | href: { |
20 | type: String | 22 | type: String |
21 | - }, | ||
22 | - separator: { | ||
23 | - type: String, | ||
24 | - default: '/' | ||
25 | } | 23 | } |
26 | }, | 24 | }, |
25 | + data () { | ||
26 | + return { | ||
27 | + separator: '', | ||
28 | + showSeparator: false | ||
29 | + }; | ||
30 | + }, | ||
31 | + mounted () { | ||
32 | + this.showSeparator = this.$slots.separator !== undefined; | ||
33 | + }, | ||
27 | computed: { | 34 | computed: { |
28 | linkClasses () { | 35 | linkClasses () { |
29 | return `${prefixCls}-link`; | 36 | return `${prefixCls}-link`; |
src/components/breadcrumb/breadcrumb.vue
src/index.js
@@ -5,7 +5,7 @@ import Affix from './components/affix'; | @@ -5,7 +5,7 @@ import Affix from './components/affix'; | ||
5 | import Alert from './components/alert'; | 5 | import Alert from './components/alert'; |
6 | // import BackTop from './components/back-top'; | 6 | // import BackTop from './components/back-top'; |
7 | import Badge from './components/badge'; | 7 | import Badge from './components/badge'; |
8 | -// import Breadcrumb from './components/breadcrumb'; | 8 | +import Breadcrumb from './components/breadcrumb'; |
9 | import Button from './components/button'; | 9 | import Button from './components/button'; |
10 | import Card from './components/card'; | 10 | import Card from './components/card'; |
11 | import Carousel from './components/carousel'; | 11 | import Carousel from './components/carousel'; |
@@ -51,8 +51,8 @@ const iview = { | @@ -51,8 +51,8 @@ const iview = { | ||
51 | Alert, | 51 | Alert, |
52 | // BackTop, | 52 | // BackTop, |
53 | Badge, | 53 | Badge, |
54 | - // Breadcrumb, | ||
55 | - // BreadcrumbItem: Breadcrumb.Item, | 54 | + Breadcrumb, |
55 | + BreadcrumbItem: Breadcrumb.Item, | ||
56 | // iButton: Button, | 56 | // iButton: Button, |
57 | Button, | 57 | Button, |
58 | ButtonGroup: Button.Group, | 58 | ButtonGroup: Button.Group, |
1 | +import Vue from 'vue'; | ||
2 | +Vue.config.productionTip = false; | ||
3 | + | ||
4 | +// Polyfill fn.bind() for PhantomJS | ||
5 | +/* eslint-disable no-extend-native */ | ||
6 | +Function.prototype.bind = require('function-bind'); | ||
7 | + | ||
8 | +// require all test files (files that ends with .spec.js) | ||
9 | +const testsContext = require.context('./specs', true, /\.spec$/); | ||
10 | +testsContext.keys().forEach(testsContext); | ||
11 | + | ||
12 | +// require all src files except main.js for coverage. | ||
13 | +// you can also change this to match only the subset of files that | ||
14 | +// you want coverage for. | ||
15 | +// const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/); | ||
16 | +// @todo | ||
17 | +const srcContext = require.context('../../src/components/breadcrumb', true, /^\.\/(?!styles.*?(\.less)?$)/); | ||
18 | +srcContext.keys().forEach(srcContext); |
1 | +// This is a karma config file. For more details see | ||
2 | +// http://karma-runner.github.io/0.13/config/configuration-file.html | ||
3 | +// we are also using it with karma-webpack | ||
4 | +// https://github.com/webpack/karma-webpack | ||
5 | + | ||
6 | +var webpackConfig = require('../../build/webpack.test.config.js'); | ||
7 | + | ||
8 | +module.exports = function (config) { | ||
9 | + config.set({ | ||
10 | + // to run in additional browsers: | ||
11 | + // 1. install corresponding karma launcher | ||
12 | + // http://karma-runner.github.io/0.13/config/browsers.html | ||
13 | + // 2. add it to the `browsers` array below. | ||
14 | + browsers: ['PhantomJS'], | ||
15 | + frameworks: ['mocha', 'sinon-chai'], | ||
16 | + reporters: ['spec', 'coverage'], | ||
17 | + files: ['./index.js'], | ||
18 | + preprocessors: { | ||
19 | + './index.js': ['webpack', 'sourcemap'] | ||
20 | + }, | ||
21 | + webpack: webpackConfig, | ||
22 | + webpackMiddleware: { | ||
23 | + noInfo: true, | ||
24 | + }, | ||
25 | + coverageReporter: { | ||
26 | + dir: './coverage', | ||
27 | + reporters: [ | ||
28 | + { type: 'lcov', subdir: '.' }, | ||
29 | + { type: 'text-summary' }, | ||
30 | + ] | ||
31 | + }, | ||
32 | + }); | ||
33 | +}; |
1 | +import { createVue, destroyVM } from '../util'; | ||
2 | + | ||
3 | +describe('Breadcrumb.vue', () => { | ||
4 | + let vm; | ||
5 | + afterEach(() => { | ||
6 | + destroyVM(vm); | ||
7 | + }); | ||
8 | + it('create', done => { | ||
9 | + vm = createVue(` | ||
10 | + <Breadcrumb separator="<b class='demo-breadcrumb-separator'>=></b>"> | ||
11 | + <Breadcrumb-item href="/">Home4</Breadcrumb-item> | ||
12 | + <Breadcrumb-item href="/components/breadcrumb">Components</Breadcrumb-item> | ||
13 | + <Breadcrumb-item>Breadcrumb</Breadcrumb-item> | ||
14 | + </Breadcrumb> | ||
15 | + `); | ||
16 | + expect(vm.$el.querySelectorAll('.ivu-breadcrumb-item-link').length).to.equal(3); | ||
17 | + | ||
18 | + vm.$nextTick(_ => { | ||
19 | + // console.log(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML); | ||
20 | + expect(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML).to.equal('<b class="demo-breadcrumb-separator">=></b>'); | ||
21 | + done(); | ||
22 | + }); | ||
23 | + }); | ||
24 | +}); | ||
0 | \ No newline at end of file | 25 | \ No newline at end of file |
1 | +import Vue from 'vue'; | ||
2 | +import iView from '../../src/index'; | ||
3 | + | ||
4 | +Vue.use(iView); | ||
5 | + | ||
6 | +let id = 0; | ||
7 | + | ||
8 | +const createElm = function() { | ||
9 | + const elm = document.createElement('div'); | ||
10 | + | ||
11 | + elm.id = 'app' + ++id; | ||
12 | + document.body.appendChild(elm); | ||
13 | + | ||
14 | + return elm; | ||
15 | +}; | ||
16 | + | ||
17 | +/** | ||
18 | + * 回收 vm | ||
19 | + * @param {Object} vm | ||
20 | + */ | ||
21 | +exports.destroyVM = function(vm) { | ||
22 | + vm.$el && | ||
23 | + vm.$el.parentNode && | ||
24 | + vm.$el.parentNode.removeChild(vm.$el); | ||
25 | +}; | ||
26 | + | ||
27 | +/** | ||
28 | + * 创建一个 Vue 的实例对象 | ||
29 | + * @param {Object|String} Compo 组件配置,可直接传 template | ||
30 | + * @param {Boolean=false} mounted 是否添加到 DOM 上 | ||
31 | + * @return {Object} vm | ||
32 | + */ | ||
33 | +exports.createVue = function(Compo, mounted = false) { | ||
34 | + const elm = createElm(); | ||
35 | + | ||
36 | + if (Object.prototype.toString.call(Compo) === '[object String]') { | ||
37 | + Compo = { template: Compo }; | ||
38 | + } | ||
39 | + return new Vue(Compo).$mount(mounted === false ? null : elm); | ||
40 | +}; | ||
41 | + | ||
42 | +/** | ||
43 | + * 创建一个测试组件实例 | ||
44 | + * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components | ||
45 | + * @param {Object} Compo - 组件对象 | ||
46 | + * @param {Object} propsData - props 数据 | ||
47 | + * @param {Boolean=false} mounted - 是否添加到 DOM 上 | ||
48 | + * @return {Object} vm | ||
49 | + */ | ||
50 | +exports.createTest = function(Compo, propsData = {}, mounted = false) { | ||
51 | + if (propsData === true || propsData === false) { | ||
52 | + mounted = propsData; | ||
53 | + propsData = {}; | ||
54 | + } | ||
55 | + const elm = createElm(); | ||
56 | + const Ctor = Vue.extend(Compo); | ||
57 | + return new Ctor({ propsData }).$mount(mounted === false ? null : elm); | ||
58 | +}; | ||
59 | + | ||
60 | +/** | ||
61 | + * 触发一个事件 | ||
62 | + * mouseenter, mouseleave, mouseover, keyup, change, click 等 | ||
63 | + * @param {Element} elm | ||
64 | + * @param {String} name | ||
65 | + * @param {*} opts | ||
66 | + */ | ||
67 | +exports.triggerEvent = function(elm, name, ...opts) { | ||
68 | + let eventName; | ||
69 | + | ||
70 | + if (/^mouse|click/.test(name)) { | ||
71 | + eventName = 'MouseEvents'; | ||
72 | + } else if (/^key/.test(name)) { | ||
73 | + eventName = 'KeyboardEvent'; | ||
74 | + } else { | ||
75 | + eventName = 'HTMLEvents'; | ||
76 | + } | ||
77 | + const evt = document.createEvent(eventName); | ||
78 | + | ||
79 | + evt.initEvent(name, ...opts); | ||
80 | + elm.dispatchEvent | ||
81 | + ? elm.dispatchEvent(evt) | ||
82 | + : elm.fireEvent('on' + name, evt); | ||
83 | + | ||
84 | + return elm; | ||
85 | +}; |