├── .gitignore
├── LICENSE
├── README.md
├── generator
├── index.js
└── templates
│ └── default
│ ├── .editorconfig
│ ├── .env.local
│ ├── .eslintignore
│ ├── public
│ ├── favicon.ico
│ ├── icons
│ │ ├── android-chrome-192x192.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── msapplication-icon-144x144.png
│ │ └── safari-pinned-tab.svg
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── assets
│ │ ├── less
│ │ │ └── var.less
│ │ └── sass
│ │ │ └── var.scss
│ ├── bootstrap.js
│ ├── components
│ │ ├── charts
│ │ │ ├── bar.vue
│ │ │ ├── index.js
│ │ │ ├── pie.vue
│ │ │ └── theme.json
│ │ ├── common-icon.vue
│ │ ├── count-to
│ │ │ └── index.vue
│ │ ├── icons.vue
│ │ ├── index.js
│ │ └── info-card
│ │ │ └── index.vue
│ ├── config.js
│ ├── i18n
│ │ ├── en-US.js
│ │ ├── index.js
│ │ └── zh-CN.js
│ ├── lib
│ │ └── services
│ │ │ └── index.js
│ ├── pages
│ │ └── index
│ │ │ ├── App.vue
│ │ │ ├── components
│ │ │ ├── common
│ │ │ │ ├── footer.vue
│ │ │ │ └── header.vue
│ │ │ ├── index.js
│ │ │ ├── language.vue
│ │ │ └── layout.vue
│ │ │ ├── index.html
│ │ │ ├── main.js
│ │ │ ├── routes
│ │ │ ├── index.js
│ │ │ ├── manage.js
│ │ │ ├── report.js
│ │ │ └── system.js
│ │ │ ├── store
│ │ │ └── index.js
│ │ │ └── views
│ │ │ ├── 404.vue
│ │ │ ├── account.vue
│ │ │ ├── home.vue
│ │ │ ├── login.vue
│ │ │ ├── manage
│ │ │ ├── hello.vue
│ │ │ ├── index.vue
│ │ │ └── world.vue
│ │ │ ├── report.vue
│ │ │ └── system.vue
│ ├── registerServiceWorker.js
│ ├── router.js
│ └── store
│ │ ├── index.js
│ │ ├── modules
│ │ ├── Language.js
│ │ ├── User.js
│ │ ├── Webconfig.js
│ │ └── index.js
│ │ ├── mutation-type.js
│ │ └── plugins.js
│ └── vue.config.js
├── package.json
├── preset.json
├── prompts.js
└── screenshot
├── element-ui.png
├── iview-en.png
└── iview.png
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | package-lock.json
3 | yarn.lock
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Kuaizi™
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | <<<<<<< HEAD
22 | SOFTWARE.
23 | =======
24 | SOFTWARE.
25 | >>>>>>> 6accc9d8a11e7126c2eb3f2bff463ba5843424ba
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-cli-preset-kz
2 |
3 | vue项目开发预设模板
4 |
5 | [https://kuaizi-co.github.io/vue-cli-preset-kz](https://kuaizi-co.github.io/vue-cli-preset-kz)
6 |
7 | ## Install
8 |
9 | ```
10 | # 首先安装vue-cli 3.0
11 | > npm install -g @vue/cli
12 |
13 | > vue create --preset kuaizi-co/vue-cli-preset-kz project-name --no-git
14 |
15 | # OR more faster!!!
16 | # - project-name
17 | # - vue-cli-preset-kz
18 | project-name> cd ..
19 | > git clone https://github.com/Kuaizi-co/vue-cli-preset-kz.git
20 | > cd vue-cli-preset-kz
21 | > git pull origin master
22 | > cd ..
23 | > vue create --preset ./vue-cli-preset-kz project-name --no-git
24 | ```
25 |
26 | ## Develop
27 |
28 | ```
29 | npm run dev
30 | ```
31 |
32 | ## Build
33 |
34 | ```
35 | npm run build
36 | ```
37 |
38 | ## Review
39 |
40 | ```
41 | npm run review
42 | ```
43 |
44 | ## 功能列表
45 |
46 | - [x] postcss/less/sass
47 | - [x] ES6/Typescript
48 | - [x] element-ui/iview
49 | - [x] vue-router/vuex
50 | - [x] mock server
51 | - [x] style-resources-loader
52 | - [x] i18n
53 | - [x] axios
54 | - [x] PWA
55 | - [x] unit(mocha)/e2e(Nightwatch)
56 | - [ ] nuxt.js/egg.js
57 |
58 | ### css预处理器全局变量
59 |
60 | 内置`style-resources-loader`,支持`less`、`sass` 加载全局变量文件。
61 |
62 | ```
63 | # vue.config.js
64 | /**
65 | * 样式预处理器全局变量资源插件
66 | * @param {String} rule webpack 规则
67 | */
68 | function addStyleResource (rule) {
69 | rule.use('style-resource')
70 | .loader('style-resources-loader')
71 | .options({
72 | patterns: [
73 | resolve('./src/assets/less/var.less')
74 | ]
75 | })
76 | }
77 | ```
78 |
79 | 在`*.vue`文件中直接使用 `var.less(scss)`定义的变量,增加共同`mixin`只需手动添加文件的路径。
80 |
81 | ```
82 | # App.vue
83 |
89 | ```
90 |
91 | ### preset模板
92 |
93 | 当前 preset 模板暂只有 `default` 默认模板,对于 `ts`、`egg`、`nuxt` 模板添加时间待定。
94 |
95 | ### UI 框架
96 |
97 | 本 preset 支持 `element-ui` 和 `iview`(默认)两种。
98 |
99 | 
100 |
101 | iView
102 |
103 | 
104 |
105 | element-ui
106 |
107 | ### I18n 多语言
108 |
109 | 多语言采用模块异步延迟加载方式,首先检测语言环境及用户上次使用的语言。在切换语言后,如果尚未加载的语言包将从服务器中加载,达到项目按需加载资源优化。
110 |
111 | ```
112 | src
113 | i18n
114 | index.js
115 | zh-CN.js
116 | en-US.js
117 | ```
118 |
119 | 
120 |
121 | 英文版页面
122 |
123 | ### 多页模式
124 |
125 | 通过配置`vue.config.js`的`pages`参数,默认读取 `src/pages`下的各个目录
126 |
127 | ```
128 | - src
129 | - pages
130 | - index
131 | - components
132 | - routes
133 | - store
134 | - views
135 | App.vue
136 | index.html
137 | main.js
138 | - about
139 | ```
140 |
141 | 每个单页基本包含3个文件
142 |
143 | ```
144 | App.vue
145 | index.html
146 | main.js
147 | ```
148 |
149 | #
150 | copyright (c) www.kuaizi.ai
--------------------------------------------------------------------------------
/generator/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 |
3 | module.exports = (api, opts, rootOpts) => {
4 |
5 | // 添加 npm 命令
6 | api.extendPackage({
7 | scripts: {
8 | dev: 'vue-cli-service serve --copy',
9 | build: 'vue-cli-service build',
10 | review: 'serve -s dist',
11 | lint: 'vue-cli-service lint',
12 | serve: 'vue-cli-service serve'
13 | }
14 | })
15 |
16 | // 开发依赖包
17 | api.extendPackage({
18 | devDependencies: {
19 | 'serve': '^10.0.1',
20 | 'style-resources-loader': '1.2.1'
21 | }
22 | })
23 |
24 | api.extendPackage({
25 | dependencies: {
26 | 'axios': '^0.18.0',
27 | 'babel-polyfill': '^6.22.0',
28 | 'lodash': '^4.17.11',
29 | 'normalize.css': '^8.0.0',
30 | 'nprogress': '^0.2.0',
31 | 'vue-i18n': '^8.1.0',
32 | 'countup': '^1.8.2',
33 | "echarts": "^4.2.0-rc.1",
34 | [opts['ui-framework']]: opts['ui-framework'] === 'element-ui' ? '^2.4.7' : '^3.1.1'
35 | }
36 | })
37 |
38 | // # less
39 | if (opts['cssPreprocessor'] === 'less') {
40 | api.extendPackage({
41 | devDependencies: {
42 | "less": "^2.7.2",
43 | "less-loader": "^3.0.0"
44 | }
45 | })
46 | }
47 |
48 | // # sass
49 | if (opts['cssPreprocessor'] === 'sass') {
50 | api.extendPackage({
51 | devDependencies: {
52 | "node-sass": "^4.9.3",
53 | "sass-loader": "^7.1.0"
54 | }
55 | })
56 | }
57 |
58 | // 扩展.babelrc 配置
59 | // api.extendPackage({
60 | // babel: {
61 | // env: {
62 | // test: {
63 | // plugins: ["babel-plugin-transform-es2015-modules-commonjs"]
64 | // }
65 | // }
66 | // }
67 | // })
68 |
69 | // 扩展 .eslintrc 配置
70 | api.extendPackage({
71 | eslintConfig: {
72 | "rules": {
73 | "vue/no-parsing-error": [
74 | 2,
75 | { "x-invalid-end-tag": false }
76 | ]
77 | }
78 | }
79 | })
80 |
81 | // 删除多余的模板
82 | api.render(files => {
83 | Object.keys(files)
84 | .filter(path => path.startsWith('src/') || path.startsWith('public/'))
85 | .forEach(path => delete files[path])
86 | })
87 |
88 |
89 |
90 | // 选择生成的模板
91 | // if (opts.Typescript) {
92 | // api.render("./templates/ts")
93 | // } else
94 | if(opts.SSR === 'nuxt') {
95 | api.render("./templates/nuxt")
96 | // } else if (opts.SSR === 'egg') {
97 | // api.render("./templates/egg")
98 | } else {
99 | api.render("./templates/default")
100 | }
101 |
102 | // 删除多余目录
103 | const pwaFiles = [
104 | 'public/robots.txt',
105 | 'public/manifest.json',
106 | 'src/registerServiceWorker.js',
107 | 'public/icons/android-chrome-192x192.png',
108 | 'public/icons/apple-touch-icon-152x152.png',
109 | 'public/icons/msapplication-icon-144x144.png',
110 | 'public/icons/safari-pinned-tab.svg'
111 | ]
112 |
113 | if (opts.pwa) {
114 | api.extendPackage({
115 | dependencies: {
116 | "register-service-worker": "^1.0.0",
117 | "sass-loader": "^7.1.0"
118 | },
119 | devDependencies: {
120 | "@vue/cli-plugin-pwa": "^3.0.3"
121 | }
122 | })
123 | }
124 |
125 | api.render(files => {
126 | Object.keys(files)
127 | .filter(path => path.includes(`/${opts.cssPreprocessor === 'sass' ? 'less' : 'sass' }/`))
128 | .forEach(path => delete files[path])
129 |
130 | if (!opts.pwa) {
131 | Object.keys(files)
132 | .filter(path => {
133 | return pwaFiles.find(file => path.includes(file))
134 | })
135 | .forEach(path => delete files[path])
136 | }
137 | })
138 | }
--------------------------------------------------------------------------------
/generator/templates/default/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/generator/templates/default/.env.local:
--------------------------------------------------------------------------------
1 | # 只允许访问的路由
2 | # VUE_APP_ALLOW_ROUTES=manage
3 | # 只允许访问的单页
4 | # VUE_APP_ALLOW_ENTRY=index
5 |
--------------------------------------------------------------------------------
/generator/templates/default/.eslintignore:
--------------------------------------------------------------------------------
1 | # src/lib/ajax.js
--------------------------------------------------------------------------------
/generator/templates/default/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/generator/templates/default/public/favicon.ico
--------------------------------------------------------------------------------
/generator/templates/default/public/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/generator/templates/default/public/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/generator/templates/default/public/icons/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/generator/templates/default/public/icons/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/generator/templates/default/public/icons/msapplication-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/generator/templates/default/public/icons/msapplication-icon-144x144.png
--------------------------------------------------------------------------------
/generator/templates/default/public/icons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
150 |
--------------------------------------------------------------------------------
/generator/templates/default/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pwa",
3 | "short_name": "pwa",
4 | "icons": [
5 | {
6 | "src": "/img/icons/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/img/icons/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "start_url": "/index.html",
17 | "display": "standalone",
18 | "background_color": "#000000",
19 | "theme_color": "#4DBA87"
20 | }
21 |
--------------------------------------------------------------------------------
/generator/templates/default/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/generator/templates/default/src/assets/less/var.less:
--------------------------------------------------------------------------------
1 | @color: #2c3e50;
2 |
--------------------------------------------------------------------------------
/generator/templates/default/src/assets/sass/var.scss:
--------------------------------------------------------------------------------
1 | $color: #2c3e50;
2 |
--------------------------------------------------------------------------------
/generator/templates/default/src/bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 页面初始化函数
3 | * by www.kuaizi.ai
4 | * http://www.kuaizi.ai
5 | */
6 |
7 | // css reset
8 | import 'normalize.css'
9 | import Vue from 'vue'
10 | import i18n from '@/i18n'
11 |
12 | <% if (options['ui-framework'] === 'element-ui') {%>
13 | // 使用ElementUI
14 | import ElementUI from 'element-ui'
15 | import 'element-ui/lib/theme-chalk/index.css'
16 | Vue.use(ElementUI)
17 | <% } %>
18 |
19 | <% if (options['ui-framework'] === 'iview') {%>
20 | // 使用iView
21 | import iView from 'iview';
22 | import 'iview/dist/styles/iview.css';
23 | Vue.use(iView)
24 | <% } %>
25 |
26 | import Store from './store'
27 | import components from './components'
28 |
29 | <% if (options.pwa) {%>
30 | import './registerServiceWorker'
31 | <% } %>
32 |
33 | export default ({ Router, Component, routes, states = {}, options }, resolve = () => {}) => {
34 | // 批量注册组件
35 | Object.values(components)
36 | .forEach(component => {
37 | Vue.component(component.name, component)
38 | })
39 |
40 | const store = Store(states)
41 |
42 | // 绑定路由
43 | const router = Router ? Router(store, routes, options) : {}
44 |
45 | // 动态加载当前语言包
46 | store.dispatch('setSystemLanguage', Vue.config.lang)
47 | .then(res => {
48 | // 创建单页实例
49 | const app = new Vue({
50 | el: '#app',
51 | render: h => h(Component),
52 | store,
53 | router,
54 | i18n
55 | })
56 |
57 | // 回调函数
58 | resolve(app)
59 | })
60 |
61 | // const app = new Vue({
62 | // el: '#app',
63 | // render: h => h(Component),
64 | // store,
65 | // router,
66 | // i18n
67 | // })
68 |
69 | // // 回调函数
70 | // resolve(app)
71 | }
72 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/charts/bar.vue:
--------------------------------------------------------------------------------
1 |
2 | v-loading="spinShow"<% }%>
4 | >
5 |
6 |
7 | <% if (options['ui-framework'] === 'iview') {%>
8 |
9 | <% } %>
10 |
11 |
12 |
13 |
66 |
67 |
72 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/charts/index.js:
--------------------------------------------------------------------------------
1 | import ChartPie from './pie.vue'
2 | import ChartBar from './bar.vue'
3 |
4 | export const requireEcharts = () => import(/* webpackChunkName: "echarts" */ 'echarts')
5 |
6 | export {
7 | ChartPie,
8 | ChartBar
9 | }
10 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/charts/pie.vue:
--------------------------------------------------------------------------------
1 |
2 | v-loading="spinShow"<% }%>
4 | >
5 |
6 |
7 | <% if (options['ui-framework'] === 'iview') {%>
8 |
9 | <% } %>
10 |
11 |
12 |
13 |
78 |
83 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/charts/theme.json:
--------------------------------------------------------------------------------
1 | {
2 | "color": [
3 | "#2d8cf0",
4 | "#19be6b",
5 | "#ff9900",
6 | "#E46CBB",
7 | "#9A66E4",
8 | "#ed3f14"
9 | ],
10 | "backgroundColor": "rgba(0,0,0,0)",
11 | "textStyle": {},
12 | "title": {
13 | "textStyle": {
14 | "color": "#516b91"
15 | },
16 | "subtextStyle": {
17 | "color": "#93b7e3"
18 | }
19 | },
20 | "line": {
21 | "itemStyle": {
22 | "normal": {
23 | "borderWidth": "2"
24 | }
25 | },
26 | "lineStyle": {
27 | "normal": {
28 | "width": "2"
29 | }
30 | },
31 | "symbolSize": "6",
32 | "symbol": "emptyCircle",
33 | "smooth": true
34 | },
35 | "radar": {
36 | "itemStyle": {
37 | "normal": {
38 | "borderWidth": "2"
39 | }
40 | },
41 | "lineStyle": {
42 | "normal": {
43 | "width": "2"
44 | }
45 | },
46 | "symbolSize": "6",
47 | "symbol": "emptyCircle",
48 | "smooth": true
49 | },
50 | "bar": {
51 | "itemStyle": {
52 | "normal": {
53 | "barBorderWidth": 0,
54 | "barBorderColor": "#ccc"
55 | },
56 | "emphasis": {
57 | "barBorderWidth": 0,
58 | "barBorderColor": "#ccc"
59 | }
60 | }
61 | },
62 | "pie": {
63 | "itemStyle": {
64 | "normal": {
65 | "borderWidth": 0,
66 | "borderColor": "#ccc"
67 | },
68 | "emphasis": {
69 | "borderWidth": 0,
70 | "borderColor": "#ccc"
71 | }
72 | }
73 | },
74 | "scatter": {
75 | "itemStyle": {
76 | "normal": {
77 | "borderWidth": 0,
78 | "borderColor": "#ccc"
79 | },
80 | "emphasis": {
81 | "borderWidth": 0,
82 | "borderColor": "#ccc"
83 | }
84 | }
85 | },
86 | "boxplot": {
87 | "itemStyle": {
88 | "normal": {
89 | "borderWidth": 0,
90 | "borderColor": "#ccc"
91 | },
92 | "emphasis": {
93 | "borderWidth": 0,
94 | "borderColor": "#ccc"
95 | }
96 | }
97 | },
98 | "parallel": {
99 | "itemStyle": {
100 | "normal": {
101 | "borderWidth": 0,
102 | "borderColor": "#ccc"
103 | },
104 | "emphasis": {
105 | "borderWidth": 0,
106 | "borderColor": "#ccc"
107 | }
108 | }
109 | },
110 | "sankey": {
111 | "itemStyle": {
112 | "normal": {
113 | "borderWidth": 0,
114 | "borderColor": "#ccc"
115 | },
116 | "emphasis": {
117 | "borderWidth": 0,
118 | "borderColor": "#ccc"
119 | }
120 | }
121 | },
122 | "funnel": {
123 | "itemStyle": {
124 | "normal": {
125 | "borderWidth": 0,
126 | "borderColor": "#ccc"
127 | },
128 | "emphasis": {
129 | "borderWidth": 0,
130 | "borderColor": "#ccc"
131 | }
132 | }
133 | },
134 | "gauge": {
135 | "itemStyle": {
136 | "normal": {
137 | "borderWidth": 0,
138 | "borderColor": "#ccc"
139 | },
140 | "emphasis": {
141 | "borderWidth": 0,
142 | "borderColor": "#ccc"
143 | }
144 | }
145 | },
146 | "candlestick": {
147 | "itemStyle": {
148 | "normal": {
149 | "color": "#edafda",
150 | "color0": "transparent",
151 | "borderColor": "#d680bc",
152 | "borderColor0": "#8fd3e8",
153 | "borderWidth": "2"
154 | }
155 | }
156 | },
157 | "graph": {
158 | "itemStyle": {
159 | "normal": {
160 | "borderWidth": 0,
161 | "borderColor": "#ccc"
162 | }
163 | },
164 | "lineStyle": {
165 | "normal": {
166 | "width": 1,
167 | "color": "#aaa"
168 | }
169 | },
170 | "symbolSize": "6",
171 | "symbol": "emptyCircle",
172 | "smooth": true,
173 | "color": [
174 | "#2d8cf0",
175 | "#19be6b",
176 | "#f5ae4a",
177 | "#9189d5",
178 | "#56cae2",
179 | "#cbb0e3"
180 | ],
181 | "label": {
182 | "normal": {
183 | "textStyle": {
184 | "color": "#eee"
185 | }
186 | }
187 | }
188 | },
189 | "map": {
190 | "itemStyle": {
191 | "normal": {
192 | "areaColor": "#f3f3f3",
193 | "borderColor": "#516b91",
194 | "borderWidth": 0.5
195 | },
196 | "emphasis": {
197 | "areaColor": "rgba(165,231,240,1)",
198 | "borderColor": "#516b91",
199 | "borderWidth": 1
200 | }
201 | },
202 | "label": {
203 | "normal": {
204 | "textStyle": {
205 | "color": "#000"
206 | }
207 | },
208 | "emphasis": {
209 | "textStyle": {
210 | "color": "rgb(81,107,145)"
211 | }
212 | }
213 | }
214 | },
215 | "geo": {
216 | "itemStyle": {
217 | "normal": {
218 | "areaColor": "#f3f3f3",
219 | "borderColor": "#516b91",
220 | "borderWidth": 0.5
221 | },
222 | "emphasis": {
223 | "areaColor": "rgba(165,231,240,1)",
224 | "borderColor": "#516b91",
225 | "borderWidth": 1
226 | }
227 | },
228 | "label": {
229 | "normal": {
230 | "textStyle": {
231 | "color": "#000"
232 | }
233 | },
234 | "emphasis": {
235 | "textStyle": {
236 | "color": "rgb(81,107,145)"
237 | }
238 | }
239 | }
240 | },
241 | "categoryAxis": {
242 | "axisLine": {
243 | "show": true,
244 | "lineStyle": {
245 | "color": "#cccccc"
246 | }
247 | },
248 | "axisTick": {
249 | "show": false,
250 | "lineStyle": {
251 | "color": "#333"
252 | }
253 | },
254 | "axisLabel": {
255 | "show": true,
256 | "textStyle": {
257 | "color": "#999999"
258 | }
259 | },
260 | "splitLine": {
261 | "show": true,
262 | "lineStyle": {
263 | "color": [
264 | "#eeeeee"
265 | ]
266 | }
267 | },
268 | "splitArea": {
269 | "show": false,
270 | "areaStyle": {
271 | "color": [
272 | "rgba(250,250,250,0.05)",
273 | "rgba(200,200,200,0.02)"
274 | ]
275 | }
276 | }
277 | },
278 | "valueAxis": {
279 | "axisLine": {
280 | "show": true,
281 | "lineStyle": {
282 | "color": "#cccccc"
283 | }
284 | },
285 | "axisTick": {
286 | "show": false,
287 | "lineStyle": {
288 | "color": "#333"
289 | }
290 | },
291 | "axisLabel": {
292 | "show": true,
293 | "textStyle": {
294 | "color": "#999999"
295 | }
296 | },
297 | "splitLine": {
298 | "show": true,
299 | "lineStyle": {
300 | "color": [
301 | "#eeeeee"
302 | ]
303 | }
304 | },
305 | "splitArea": {
306 | "show": false,
307 | "areaStyle": {
308 | "color": [
309 | "rgba(250,250,250,0.05)",
310 | "rgba(200,200,200,0.02)"
311 | ]
312 | }
313 | }
314 | },
315 | "logAxis": {
316 | "axisLine": {
317 | "show": true,
318 | "lineStyle": {
319 | "color": "#cccccc"
320 | }
321 | },
322 | "axisTick": {
323 | "show": false,
324 | "lineStyle": {
325 | "color": "#333"
326 | }
327 | },
328 | "axisLabel": {
329 | "show": true,
330 | "textStyle": {
331 | "color": "#999999"
332 | }
333 | },
334 | "splitLine": {
335 | "show": true,
336 | "lineStyle": {
337 | "color": [
338 | "#eeeeee"
339 | ]
340 | }
341 | },
342 | "splitArea": {
343 | "show": false,
344 | "areaStyle": {
345 | "color": [
346 | "rgba(250,250,250,0.05)",
347 | "rgba(200,200,200,0.02)"
348 | ]
349 | }
350 | }
351 | },
352 | "timeAxis": {
353 | "axisLine": {
354 | "show": true,
355 | "lineStyle": {
356 | "color": "#cccccc"
357 | }
358 | },
359 | "axisTick": {
360 | "show": false,
361 | "lineStyle": {
362 | "color": "#333"
363 | }
364 | },
365 | "axisLabel": {
366 | "show": true,
367 | "textStyle": {
368 | "color": "#999999"
369 | }
370 | },
371 | "splitLine": {
372 | "show": true,
373 | "lineStyle": {
374 | "color": [
375 | "#eeeeee"
376 | ]
377 | }
378 | },
379 | "splitArea": {
380 | "show": false,
381 | "areaStyle": {
382 | "color": [
383 | "rgba(250,250,250,0.05)",
384 | "rgba(200,200,200,0.02)"
385 | ]
386 | }
387 | }
388 | },
389 | "toolbox": {
390 | "iconStyle": {
391 | "normal": {
392 | "borderColor": "#999"
393 | },
394 | "emphasis": {
395 | "borderColor": "#666"
396 | }
397 | }
398 | },
399 | "legend": {
400 | "textStyle": {
401 | "color": "#999999"
402 | }
403 | },
404 | "tooltip": {
405 | "axisPointer": {
406 | "lineStyle": {
407 | "color": "#ccc",
408 | "width": 1
409 | },
410 | "crossStyle": {
411 | "color": "#ccc",
412 | "width": 1
413 | }
414 | }
415 | },
416 | "timeline": {
417 | "lineStyle": {
418 | "color": "#8fd3e8",
419 | "width": 1
420 | },
421 | "itemStyle": {
422 | "normal": {
423 | "color": "#8fd3e8",
424 | "borderWidth": 1
425 | },
426 | "emphasis": {
427 | "color": "#8fd3e8"
428 | }
429 | },
430 | "controlStyle": {
431 | "normal": {
432 | "color": "#8fd3e8",
433 | "borderColor": "#8fd3e8",
434 | "borderWidth": 0.5
435 | },
436 | "emphasis": {
437 | "color": "#8fd3e8",
438 | "borderColor": "#8fd3e8",
439 | "borderWidth": 0.5
440 | }
441 | },
442 | "checkpointStyle": {
443 | "color": "#8fd3e8",
444 | "borderColor": "rgba(138,124,168,0.37)"
445 | },
446 | "label": {
447 | "normal": {
448 | "textStyle": {
449 | "color": "#8fd3e8"
450 | }
451 | },
452 | "emphasis": {
453 | "textStyle": {
454 | "color": "#8fd3e8"
455 | }
456 | }
457 | }
458 | },
459 | "visualMap": {
460 | "color": [
461 | "#516b91",
462 | "#59c4e6",
463 | "#a5e7f0"
464 | ]
465 | },
466 | "dataZoom": {
467 | "backgroundColor": "rgba(0,0,0,0)",
468 | "dataBackgroundColor": "rgba(255,255,255,0.3)",
469 | "fillerColor": "rgba(167,183,204,0.4)",
470 | "handleColor": "#a7b7cc",
471 | "handleSize": "100%",
472 | "textStyle": {
473 | "color": "#333"
474 | }
475 | },
476 | "markPoint": {
477 | "label": {
478 | "normal": {
479 | "textStyle": {
480 | "color": "#eee"
481 | }
482 | },
483 | "emphasis": {
484 | "textStyle": {
485 | "color": "#eee"
486 | }
487 | }
488 | }
489 | }
490 | }
491 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/common-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
51 |
52 |
55 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/count-to/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ init }}{{ unitText }}
5 |
6 |
7 |
8 |
9 |
175 |
176 |
184 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/icons.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
40 |
41 |
44 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/index.js:
--------------------------------------------------------------------------------
1 | export default {}
2 |
--------------------------------------------------------------------------------
/generator/templates/default/src/components/info-card/index.vue:
--------------------------------------------------------------------------------
1 |
2 | <<%= options['ui-framework'] === 'element-ui' ? 'el-c' : 'C' %>ard <% if (options['ui-framework'] === 'iview') { %>:shadow="shadow"<% } %> class="info-card-wrapper" :padding="0">
3 |
13 | <%= options['ui-framework'] === 'element-ui' ? 'el-c' : 'C' %>ard>
14 |
15 |
16 |
55 |
56 |
103 |
--------------------------------------------------------------------------------
/generator/templates/default/src/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | webConfig: {
3 | title: 'Kuaizi™ - 领先的人工智能创意平台',
4 | copyright: 'Copyright © 2013-2018 All Rights Reserved 广州筷子信息科技有限公司'
5 | },
6 | dev: {
7 | baseURL: '/mock'
8 | },
9 | prod: {
10 | baseURL: '/'
11 | }
12 | }
13 |
14 | /**
15 | * 获取导航配置数组
16 | * @param {Array} arr 导航配置数组
17 | * @return [{ name: '首页', link: '/', route: true }, ...]
18 | */
19 | const getNavArr = arr => arr.map(name => ({
20 | name: `header.nav.${name}`,
21 | // name: name.charAt(0).toUpperCase() + name.substr(1, name.length),
22 | link: `/${name === 'home' ? '' : name}`,
23 | icon: `nav-icon-${name}`,
24 | route: true
25 | }))
26 |
27 | const navigators = ['home', 'manage', 'report', 'system', 'tag', 'content', 'account']
28 | export const navList = getNavArr(navigators)
29 |
30 | export const webConfig = config.webConfig
31 | export default process.env.NODE_ENV === 'production' ? config.prod : config.dev
32 |
--------------------------------------------------------------------------------
/generator/templates/default/src/i18n/en-US.js:
--------------------------------------------------------------------------------
1 | // ^_^,有道翻译!!!
2 | <% if (options['ui-framework'] === 'element-ui') {%>
3 | import en from 'element-ui/lib/locale/lang/en'
4 | <% } %>
5 | <% if (options['ui-framework'] === 'iview') {%>
6 | import en from 'iview/dist/locale/en-US'
7 | <% } %>
8 | export default Object.assign({
9 | // 站点配置信息
10 | webconfig: {
11 | title: 'Kuaizi™ - Leading artificial intelligence creative platform in real time',
12 | copyright: 'Copyright © 2013-2018 All Rights Reserved by www.kuaiz.ai'
13 | },
14 |
15 | // 页面头部
16 | header: {
17 | nav: {
18 | home: 'Home',
19 | manage: 'Manage',
20 | report: 'Report',
21 | system: 'System',
22 | tag: 'Tag',
23 | partner: 'Partner',
24 | content: 'Content',
25 | account: 'Account'
26 | },
27 | profile: {
28 | menu: {
29 | logout: 'Logout'
30 | }
31 | }
32 | },
33 |
34 | // 首页面板
35 | dashboard: {
36 | newCreation: 'New Creation',
37 | clickTotal: 'Click Total',
38 | newTag: 'New Tag',
39 | shareTotal: 'Share Total',
40 | userAccess: 'User Access',
41 | weekAmountCreation: 'A week on the amount of creativity',
42 | sysLog: 'System Update Log'
43 | },
44 |
45 | // 按钮
46 | btn: {
47 | login: 'Login',
48 | reset: 'Rest',
49 | logout: 'Logout'
50 | },
51 |
52 | // 消息
53 | messages: {
54 | loginSuccess: 'Success!',
55 | loginFailed: 'Failed',
56 | logoutSuccess: 'Success!',
57 | logoutFailed: 'Failed!'
58 | },
59 |
60 | // 登录页
61 | pages: {
62 | login: {
63 | title: 'Advertisers Account',
64 | user: 'User',
65 | password: 'Password'
66 | }
67 | }
68 | }, en)
69 |
--------------------------------------------------------------------------------
/generator/templates/default/src/i18n/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueI18n from 'vue-i18n'
3 |
4 | Vue.use(VueI18n)
5 |
6 | const navLang = navigator.language
7 | const localLang = (navLang === 'zh-CN' || navLang === 'en-US') ? navLang : false
8 | let lang = window.localStorage.lang || localLang || 'zh-CN'
9 |
10 | // 小技巧,定义Vue.config.lang为用户语言环境
11 | Vue.config.lang = lang
12 |
13 | export default new VueI18n({
14 | // 默认已加载
15 | // locale: 'zh-CN',
16 | fallbackLocale: lang
17 | })
18 |
--------------------------------------------------------------------------------
/generator/templates/default/src/i18n/zh-CN.js:
--------------------------------------------------------------------------------
1 | <% if (options['ui-framework'] === 'element-ui') {%>
2 | import zh from 'element-ui/lib/locale/lang/zh-CN'
3 | <% } %>
4 | <% if (options['ui-framework'] === 'iview') {%>
5 | import zh from 'iview/dist/locale/zh-CN'
6 | <% } %>
7 |
8 | export default Object.assign({
9 | // 站点配置信息
10 | webconfig: {
11 | title: 'Kuaizi™ - 领先的人工智能创意平台',
12 | copyright: 'Copyright © 2013-2018 All Rights Reserved 广州筷子信息科技有限公司'
13 | },
14 |
15 | // 页面头部
16 | header: {
17 | nav: {
18 | home: '首页',
19 | manage: '广告管理',
20 | report: '广告报告',
21 | system: '系统管理',
22 | tag: '分类管理',
23 | partner: '客户管理',
24 | content: '内容管理',
25 | account: '账户中心'
26 | },
27 | profile: {
28 | menu: {
29 | logout: '退出登录'
30 | }
31 | }
32 | },
33 |
34 | // 首页面板
35 | dashboard: {
36 | newCreation: '新增创意',
37 | clickTotal: '累计点击',
38 | newTag: '新增标签',
39 | shareTotal: '分享统计',
40 | userAccess: '用户访问来源',
41 | weekAmountCreation: '每周投放创意量',
42 | sysLog: '系统更新日志'
43 | },
44 |
45 | // 按钮
46 | btn: {
47 | login: '登录',
48 | reset: '重置',
49 | logout: '注销'
50 | },
51 |
52 | // 消息
53 | messages: {
54 | loginSuccess: '登录成功,欢迎回来!',
55 | loginFailed: '登录失败',
56 | logoutSuccess: '成功注销!',
57 | logoutFailed: '注销失败!'
58 | },
59 |
60 | // 登录页
61 | pages: {
62 | login: {
63 | title: '广 告 主 账 号',
64 | user: '用户名',
65 | password: '密码'
66 | }
67 | }
68 | }, zh)
69 |
--------------------------------------------------------------------------------
/generator/templates/default/src/lib/services/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import axios from 'axios'
3 | import config from '@/config'
4 |
5 | const api = axios.create({
6 | baseURL: config.baseURL
7 | })
8 |
9 | api.interceptors.request.use(config => config, err => Promise.reject(err))
10 | api.interceptors.response.use(({ data: { data, code, message } }) => {
11 | if (code === 0) return data
12 | const failData = { code, message }
13 | return Promise.reject(failData)
14 | }, err => Promise.reject(err))
15 |
16 | /**
17 | * GET method
18 | * @param {*} url 请求地址
19 | * @param {*} data 查询参数
20 | */
21 | api.fetch = async config => {
22 | const result = await api(config)
23 | return result
24 | }
25 |
26 | if (!Vue.$http) Vue.$http = api
27 |
28 | export default api
29 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
16 |
17 |
28 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/components/common/footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/components/common/header.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
25 | <% } %>
26 |
27 | <% if (options['ui-framework'] === 'element-ui') {%>
28 |
57 | <% } %>
58 |
59 |
60 |
61 |
116 |
117 | <% if (options['ui-framework'] === 'iview') {%>
118 |
160 | <% } %>
161 |
162 | <% if (options['ui-framework'] === 'element-ui') {%>
163 |
201 | <% } %>
202 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/components/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 需要自动注册组件
3 | */
4 |
5 | export default {}
6 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/components/language.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
41 |
42 |
56 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/components/layout.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
4 |
5 |
6 |
7 |
8 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | <% } %>
44 | <% if (options['ui-framework'] === 'element-ui') {%>
45 |
46 |
47 |
48 |
49 |
50 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | <% } %>
92 |
93 |
94 |
116 |
117 |
185 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 首页 | <%= rootOptions.projectName %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import bootstrap from '@/bootstrap'
3 | import Router from '@/router'
4 | import routes from './routes'
5 | import store from './store'
6 | import App from './App'
7 |
8 | // 单页组件
9 | import components from './components'
10 |
11 | // 单页语言配置
12 | import '@/i18n'
13 |
14 | bootstrap({ Router, Component: App, routes, states: store }, app => {
15 | // 批量注册单页全局组件
16 | Object.values(components)
17 | .forEach(component => {
18 | Vue.component(component.name, component)
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/routes/index.js:
--------------------------------------------------------------------------------
1 | import { generateRoutes } from '@/router'
2 | const lazyLoader = (path) => () => import(/* webpackChunkName: "view-[request]" */ `../views/${path}`)
3 |
4 | // 一级子路由名称,对应 `./routes/子路由配置.js`
5 | // 确定`./routes`目录存在对应文件,否则require报错
6 | const childRoutesName = ['manage', 'report', 'system']
7 | // 通过`kz serve --route 子路由1,子路由2` 或 `.env.local` 来定义只访问指定的子路由
8 | // eslint-disable-next-line
9 | const allowRoutes = (process.env.VUE_APP_ALLOW_ROUTES || '').split(',')
10 | const childRoutes = allowRoutes.length && allowRoutes[0] !== '' ?
11 | childRoutesName.filter(route => allowRoutes.includes(route))
12 | : childRoutesName
13 | // 生成子路由配置
14 | const childRoutesConf = childRoutes.map(name => generateRoutes(require(`./${name}`).default, lazyLoader)).filter(route => route)
15 |
16 | export default [
17 | '',
18 | 'login',
19 | '*'
20 | ].map(router => {
21 | return {
22 | path: router === '*' ? router : `/${router}`,
23 | component: lazyLoader(router === '' ? 'home': (router === '*' ? '404' : router)),
24 | meta: {
25 | sidebar: ['*', 'login'].includes(router) ? 0 : 1
26 | }
27 | }
28 | }).concat(childRoutesConf)
29 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/routes/manage.js:
--------------------------------------------------------------------------------
1 | export default {
2 | path: 'manage',
3 | name: 'manage',
4 | redirect: '/manage/hello',
5 | children: [
6 | {
7 | path: 'hello',
8 | name: 'hello',
9 | template: 'manage/hello',
10 | meta: {
11 | title: 'xxxx',
12 | keepAlive: false
13 | },
14 | children: [
15 | {
16 | path: 'world',
17 | name: 'world',
18 | redirect: '/manage/hello'
19 | },
20 | {
21 | path: 'world/:id',
22 | name: 'world',
23 | routeName: 'world',
24 | template: 'manage/world'
25 | }
26 | ]
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/routes/report.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'report',
3 | path: 'report',
4 | meta: {
5 | sidebar: 0
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/routes/system.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'system'
3 | }
4 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/store/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 单页 vuex 配置
3 | */
4 |
5 | export default {}
6 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 | 404 Not Found.
3 |
4 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/account.vue:
--------------------------------------------------------------------------------
1 |
2 | Account
3 |
4 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | <% if (options['ui-framework'] === 'iview') {%>
4 |
5 |
6 | Home
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{ getLangInforTitle(infor.title) }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{ $t('dashboard.sysLog') }}
32 |
33 | 发布1.0版本
34 | 发布2.0版本
35 | 严重故障
36 | 发布3.0版本
37 |
38 |
39 |
40 |
41 |
42 | <% } %>
43 | <% if (options['ui-framework'] === 'element-ui') {%>
44 |
45 |
46 | Home
47 |
48 |
49 |
50 |
51 |
52 | {{ getLangInforTitle(infor.title) }}
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | {{ $t('dashboard.sysLog') }}
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | <% } %>
82 |
83 |
84 |
85 |
132 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/login.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
22 |
23 |
24 | <% } %>
25 | <% if (options['ui-framework'] === 'element-ui') {%>
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {{ $t('btn.login') }}
39 | {{ $t('btn.reset') }}
40 |
41 |
42 |
43 |
44 |
45 | <% } %>
46 |
47 |
48 |
109 |
110 |
150 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/manage/hello.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
4 |
5 | {{ $t('dashboard.sysLog') }}
6 |
7 | 发布1.0版本 view
8 | 发布2.0版本 view
9 | 严重故障 view
10 | 发布3.x0版本 view
11 |
12 |
13 |
14 |
15 | <% } %>
16 | <% if (options['ui-framework'] === 'element-ui') {%>
17 |
18 | {{ $t('dashboard.sysLog') }}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | <% } %>
29 |
30 |
31 |
40 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/manage/index.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
4 |
5 | Home
6 | Manage
7 |
8 |
9 |
10 |
11 |
12 |
13 | <% } %>
14 | <% if (options['ui-framework'] === 'element-ui') {%>
15 |
16 |
17 | Home
18 | Manage
19 |
20 |
21 |
22 |
23 | <% } %>
24 |
25 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/manage/world.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
日志:{{ $route.params.id }}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/report.vue:
--------------------------------------------------------------------------------
1 |
2 | <% if (options['ui-framework'] === 'iview') {%>
3 |
4 |
5 | Home
6 | Report
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{ getLangInforTitle(infor.title) }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{ $t('dashboard.sysLog') }}
32 |
33 | 发布1.0版本
34 | 发布2.0版本
35 | 严重故障
36 | 发布3.0版本
37 |
38 |
39 |
40 |
41 |
42 | <% } %>
43 | <% if (options['ui-framework'] === 'element-ui') {%>
44 |
45 |
46 | Home
47 | Report
48 |
49 |
50 |
51 |
52 |
53 | {{ getLangInforTitle(infor.title) }}
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | {{ $t('dashboard.sysLog') }}
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | <% } %>
83 |
84 |
85 |
130 |
--------------------------------------------------------------------------------
/generator/templates/default/src/pages/index/views/system.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | System
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/generator/templates/default/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { register } from 'register-service-worker'
4 |
5 | if (process.env.NODE_ENV === 'production') {
6 | register(`${process.env.BASE_URL}service-worker.js`, {
7 | ready () {
8 | console.log(
9 | 'App is being served from cache by a service worker.\n' +
10 | 'For more details, visit https://goo.gl/AFskqB'
11 | )
12 | },
13 | cached () {
14 | console.log('Content has been cached for offline use.')
15 | },
16 | updated () {
17 | console.log('New content is available; please refresh.')
18 | },
19 | offline () {
20 | console.log('No internet connection found. App is running in offline mode.')
21 | },
22 | error (error) {
23 | console.error('Error during service worker registration:', error)
24 | }
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/generator/templates/default/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import NProgress from 'nprogress'
4 | import 'nprogress/nprogress.css'
5 |
6 | /**
7 | * 生成路由函数
8 | * @param {*} conf 路由配置
9 | * @param {*} parent 父路由名称
10 | */
11 | export const generateRoutes = (conf, lazyLoader, parent) => {
12 | let result
13 | let path
14 | let name
15 | let componentPath
16 | if (conf) {
17 | path = (parent || '') + '/' + (conf.path || conf.name)
18 | name = parent ? parent + '_' + conf.name : conf.name
19 | componentPath = conf.template ? conf.template : path.replace(/^\//g, '') + (conf.children && conf.children.length > 0 ? '/index' : '')
20 |
21 | result = {
22 | path,
23 | name: conf.routeName || name,
24 | redirect: conf.redirect,
25 | alias: conf.alias,
26 | props: conf.props,
27 | meta: conf.meta,
28 | children: conf.children && conf.children.length > 0 ? conf.children.map(c => generateRoutes(c, lazyLoader, path)) : [],
29 | component: lazyLoader(componentPath)
30 | }
31 | }
32 | return result
33 | }
34 |
35 | export default (store, routes = [], options = {}) => {
36 | Vue.use(VueRouter)
37 | // 默认对路由不验证
38 | options = Object.assign({ validate: true }, options)
39 |
40 | const router = new VueRouter({
41 | // H5 history
42 |
43 | routes
44 | })
45 |
46 | // 切换路由之前
47 | router.beforeEach(({ meta, path }, from, next) => {
48 | // 判断是否登录
49 | const { auth = options.validate } = meta
50 | const isLogin = Boolean(store.state.User.uid)
51 |
52 | NProgress.start()
53 |
54 | // 进入下一个路由
55 | if (auth) {
56 | if (!isLogin && path !== '/login') return next({ path: '/login' })
57 | if (isLogin && path === '/login') return next({ path: '/' })
58 | next()
59 | } else {
60 | next()
61 | }
62 | })
63 |
64 | // 切换路由完成
65 | router.afterEach(route => {
66 | NProgress.done()
67 | })
68 |
69 | return router
70 | }
71 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import plugins from './plugins'
4 | import modules from './modules'
5 |
6 | Vue.use(Vuex)
7 |
8 | const strict = process.env.NODE_ENV !== 'production'
9 |
10 | export default pageModules => {
11 | return new Vuex.Store({
12 | modules: {
13 | ...modules,
14 | ...pageModules
15 | },
16 | plugins,
17 | strict
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/modules/Language.js:
--------------------------------------------------------------------------------
1 | import i18n from '@/i18n'
2 | import * as types from '../mutation-type'
3 |
4 | const state = {
5 | locale: '',
6 | loadedLanguages: []
7 | }
8 |
9 | const actions = {
10 | setSystemLanguage ({ commit, state }, lang) {
11 | if (state.locale !== lang) {
12 | if (!state.loadedLanguages.includes(lang)) {
13 | return import(/* webpackChunkName: "lang-[request]" */ `@/i18n/${lang}`).then(msgs => {
14 | i18n.setLocaleMessage(lang, msgs.default)
15 | commit(types.LANG_CHANGE, lang)
16 | commit(types.LANG_ADD_NEW, lang)
17 | })
18 | }
19 | commit(types.LANG_CHANGE, lang)
20 | return Promise.resolve(lang)
21 | }
22 | commit(types.LANG_CHANGE, lang)
23 | return Promise.resolve(lang)
24 | }
25 | }
26 |
27 | const mutations = {
28 | [types.LANG_CHANGE] (state, lang) {
29 | i18n.locale = lang
30 | window.localStorage.lang = lang
31 | state.locale = lang
32 | },
33 | [types.LANG_ADD_NEW] (state, lang) {
34 | state.loadedLanguages.push(lang)
35 | }
36 | }
37 |
38 | export default {
39 | state,
40 | actions,
41 | mutations
42 | }
43 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/modules/User.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import api from 'API'
3 | import * as types from '../mutation-type'
4 |
5 | const state = JSON.parse(window.localStorage.getItem('User')) || {}
6 |
7 | const actions = {
8 | userSignIn ({ commit }, user) {
9 | return api.fetch({
10 | method: 'post',
11 | url: '/login',
12 | data: user
13 | }).then(data => {
14 | commit(types.USER_SIGN_IN, data)
15 | })
16 | },
17 | userSignOut ({ commit }) {
18 | commit(types.USER_SIGN_OUT)
19 | return Promise.resolve(true)
20 | }
21 | }
22 |
23 | const mutations = {
24 | async [types.USER_SIGN_IN] (state, user) {
25 | window.localStorage.setItem('User', JSON.stringify(user))
26 | Object.assign(state, user)
27 | },
28 | [types.USER_SIGN_OUT] (state) {
29 | window.localStorage.removeItem('User')
30 | Object.keys(state)
31 | .forEach(item => Vue.delete(state, item))
32 | }
33 | }
34 |
35 | export default { state, mutations, actions }
36 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/modules/Webconfig.js:
--------------------------------------------------------------------------------
1 | import { webConfig } from '@/config'
2 |
3 | const state = {
4 | ...webConfig
5 | }
6 |
7 | export default { state }
8 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/modules/index.js:
--------------------------------------------------------------------------------
1 | import User from './User'
2 | import Webconfig from './Webconfig'
3 | import Language from './Language'
4 |
5 | export default {
6 | User,
7 | Webconfig,
8 | Language
9 | }
10 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/mutation-type.js:
--------------------------------------------------------------------------------
1 | // 用户相关
2 | export const USER_SIGN_IN = 'USER_SIGN_IN'
3 | export const USER_SIGN_OUT = 'USER_SIGN_OUT'
4 |
5 | // 语言相关
6 | export const LANG_CHANGE = 'LANG_CHANGE'
7 | export const LANG_ADD_NEW = 'LANG_ADD_NEW'
8 |
--------------------------------------------------------------------------------
/generator/templates/default/src/store/plugins.js:
--------------------------------------------------------------------------------
1 | /**
2 | * vuex 日志插件
3 | * by Vincent1993
4 | * https://github.com/Vincent1993/V2EX-mobile/blob/master/src/store/plugins.js
5 | */
6 |
7 | const plugins = []
8 |
9 | if (process.env.NODE_ENV !== 'production') {
10 | const createLogger = require('vuex/dist/logger')
11 |
12 | plugins.push(createLogger({
13 | collapsed: true
14 | }))
15 | }
16 |
17 | export default plugins
18 |
--------------------------------------------------------------------------------
/generator/templates/default/vue.config.js:
--------------------------------------------------------------------------------
1 | const glob = require('glob')
2 | const path = require('path')
3 | const resolve = folder => path.resolve(__dirname, folder)
4 | const VUE_APP_ALLOW_ENTRY = process.env.VUE_APP_ALLOW_ENTRY || ''
5 | // 多页面入口路径
6 | const PAGE_PATH = resolve('src/pages')
7 |
8 | /**
9 | * 获取多页面配置对象
10 | */
11 | function getPagesConfig(entry) {
12 | const pages = {}
13 | // 规范中定义每个单页文件结构
14 | // index.html,main.js,App.vue
15 | glob.sync(PAGE_PATH + '/*/main.js')
16 | .forEach(filePath => {
17 | const pageName = path.basename(path.dirname(filePath))
18 | if (entry && entry !== pageName) return
19 | pages[pageName] = {
20 | entry: filePath,
21 | // 除了首页,其他按第二级目录输出
22 | // 浏览器中直接访问/news,省去/news.html
23 | fileName: `${pageName === 'index' ? '' : pageName + '/'}index.html`,
24 | template: path.dirname(filePath) + '/index.html',
25 | chunks: ['vue-common', '<%= options['ui-framework'] %>', 'echarts', 'vendors', 'manifest', pageName]
26 | }
27 | })
28 | return pages
29 | }
30 |
31 | /**
32 | * 样式预处理器全局变量资源插件
33 | * @param {String} rule webpack 规则
34 | */
35 | function addStyleResource (rule) {
36 | rule.use('style-resource')
37 | .loader('style-resources-loader')
38 | .options({
39 | patterns: [
40 | resolve('./src/assets/<%= options.cssPreprocessor%>/var.<%= options.cssPreprocessor%>'),
41 | ],
42 | })
43 | }
44 |
45 | const pages = getPagesConfig(VUE_APP_ALLOW_ENTRY)
46 |
47 | module.exports = {
48 |
49 | // 多页配置
50 | pages: {
51 | ...pages
52 | // ,
53 | // 手动设置单页
54 | // about: 'src/pages/about/main.js'
55 | },
56 |
57 | // 自定义webpack配置
58 | configureWebpack: {
59 | cache: true,
60 | plugins: [],
61 | performance: {
62 | hints: false
63 | },
64 | optimization: {
65 | runtimeChunk: process.env.NODE_ENV === 'production' ? { name: 'manifest' } : false,
66 | splitChunks: {
67 | automaticNameDelimiter: '--',
68 | cacheGroups: {
69 | vendors: {
70 | name: 'vendors',
71 | chunks: 'initial',
72 | test: /[\\/]node_modules[\\/]/,
73 | priority: 2
74 | },
75 | vue: {
76 | name: 'vue-common',
77 | test: (module) => {
78 | return /vue|axios/g.test(module.context)
79 | },
80 | chunks: 'initial',
81 | priority: 10
82 | },
83 | '<%= options['ui-framework'] %>': {
84 | name: '<%= options['ui-framework'] %>',
85 | test: module => /<%= options['ui-framework'] %>/g.test(module.context),
86 | chunks: 'initial',
87 | priority: 10
88 | },
89 | echarts: {
90 | name: 'echarts',
91 | test: module => /echarts/g.test(module.context),
92 | chunks: 'initial',
93 | priority: 10
94 | }
95 | }
96 | }
97 | }
98 | },
99 |
100 | // 扩展webpack配置
101 | chainWebpack: config => {
102 | // 移除 prefetch 插件
103 | config.plugins.delete('prefetch')
104 | config.plugins.delete('preload')
105 | Object.keys(pages).forEach(page => {
106 | config.plugins.delete(`preload-${page}`)
107 | config.plugins.delete(`prefetch-${page}`)
108 | })
109 |
110 | config.resolve
111 | .alias
112 | .set('vue$', resolve('./node_modules/vue/dist/vue.common.js'))
113 | .set('assets', resolve('src/assets'))
114 | .set('components', resolve('src/components'))
115 | .set('I18n', resolve('src/i18n'))
116 | .set('View', resolve('src/view'))
117 | .set('Lib', resolve('src/lib'))
118 | .set('API', resolve('src/lib/services'))
119 |
120 | // 添加 css 全局变量资源插件
121 | const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
122 | types.forEach(
123 | type => addStyleResource(config.module.rule('<%= options.cssPreprocessor%>').oneOf(type))
124 | )
125 | },
126 |
127 | // 开发服务器配置
128 | devServer: {
129 | port: `<%= options['Server Port'] %>`,
130 | proxy: {
131 | '/mock': {
132 | target: 'https://easy-mock.com/mock/5ba83adde786c911a33a5090',
133 | changeOrigin: true,
134 | secure: false,
135 | pathRewrite: {
136 | '/mock': ''
137 | }
138 | }
139 | }
140 | },
141 |
142 | // 样式
143 | // css: {
144 | // loaderOptions: {}
145 | // }
146 |
147 | // 插件配置
148 | pluginOptions: {
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-cli-preset-kz",
3 | "version": "0.2.0",
4 | "description": "kuaizi vue app preset with vue-cli-preset",
5 | "main": "preset.json",
6 | "repository": "https://github.com/kuaizi-co/vue-cli-preset-kz.git",
7 | "author": "tomieric ",
8 | "license": "MIT"
9 | }
10 |
--------------------------------------------------------------------------------
/preset.json:
--------------------------------------------------------------------------------
1 | {
2 | "useTaobaoRegistry": true,
3 | "git": false,
4 | "useConfigFiles": false,
5 | "plugins": {
6 | "@vue/cli-plugin-babel": {},
7 | "@vue/cli-plugin-eslint": {
8 | "prompts": true
9 | },
10 | "@vue/cli-plugin-e2e-nightwatch": {},
11 | "@vue/cli-plugin-unit-mocha": {}
12 | },
13 | "router": true,
14 | "vuex": true,
15 | "configs": {
16 | "vue": {
17 | "baseUrl": "./",
18 | "lintOnSave": true,
19 | "productionSourceMap": false
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/prompts.js:
--------------------------------------------------------------------------------
1 | // https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli/lib/promptModules/vuex.js
2 | // module.exports = cli => {
3 | // cli.injectFeature({
4 | // name: 'cssPreprocessor',
5 | // type: 'list',
6 | // ...
7 | // })
8 |
9 | // cli.injectPrompt({
10 | // name: 'routerHistoryMode',
11 | // when: answers => answers.features.includes('router'),
12 | // type: 'confirm',
13 | // ...
14 | // })
15 |
16 | // cli.onPromptComplete((answers, options) => {
17 | // if (answers.features.includes('router')) {
18 | // options.router = true
19 | // options.routerHistoryMode = answers.routerHistoryMode
20 | // }
21 | // })
22 | // }
23 |
24 | module.exports = [
25 | {
26 | name: 'cssPreprocessor',
27 | type: 'list',
28 | message: 'Add support for CSS pre-processors like Sass or Less',
29 | choices: [
30 | {
31 | name: 'Less',
32 | value: 'less'
33 | },
34 | {
35 | name: 'Sass/SCSS',
36 | value: 'sass'
37 | }
38 | ],
39 | default: 'less'
40 | },
41 | {
42 | name: 'Vue Router mode',
43 | type: 'list',
44 | message: 'Choice Vue Router History mode',
45 | choices: [
46 | {
47 | name: 'Hash',
48 | value: 'hash'
49 | },
50 | {
51 | name: 'history',
52 | value: 'history'
53 | }
54 | ],
55 | default: 'hash'
56 | },
57 | {
58 | name: 'Typescript',
59 | type: 'confirm',
60 | message: 'Add support for the TypeScript language (default: None)',
61 | default: false
62 | },
63 | {
64 | name: 'pwa',
65 | type: 'confirm',
66 | message: 'Progressive Web App (PWA) Support (default: None)',
67 | default: false
68 | },
69 | {
70 | name: 'SSR',
71 | type: 'list',
72 | message: 'Add support for Server-Side Rendering',
73 | choices: [
74 | {
75 | name: 'None',
76 | value: 'none'
77 | },
78 | {
79 | name: 'Nuxt',
80 | value: 'nuxt'
81 | }
82 | // ,
83 | // {
84 | // name: 'egg.js',
85 | // value: 'egg'
86 | // }
87 | ],
88 | default: 'none'
89 | },
90 | {
91 | name: 'ui-framework',
92 | type: 'list',
93 | message: 'choice UI Framework',
94 | choices: [
95 | {
96 | name: 'iView',
97 | value: 'iview'
98 | },
99 | {
100 | name: 'Element UI',
101 | value: 'element-ui'
102 | }
103 | ],
104 | default: 'iview'
105 | },
106 | {
107 | name: 'Mock Server',
108 | type: 'list',
109 | message: 'choice mock server',
110 | choices: [
111 | {
112 | name: 'Easy Mock',
113 | value: 'easymock'
114 | },
115 | {
116 | name: 'Kuaizi db',
117 | value: 'kzdb'
118 | }
119 | ],
120 | default: 'easymock'
121 | },
122 | {
123 | name: 'Server Port',
124 | type: 'input',
125 | message: 'Input DevServer Port(default: 8081)',
126 | default: '8081',
127 | validate: (n) => {
128 | return !isNaN(+n)
129 | }
130 | }
131 | ]
132 |
--------------------------------------------------------------------------------
/screenshot/element-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/screenshot/element-ui.png
--------------------------------------------------------------------------------
/screenshot/iview-en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/screenshot/iview-en.png
--------------------------------------------------------------------------------
/screenshot/iview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kuaizi-co/vue-cli-preset-kz/a6b2e54c03901993487c80b55e2a35cb2e65e725/screenshot/iview.png
--------------------------------------------------------------------------------