52 changed files with 4816 additions and 20417 deletions
@ -1,2 +1,9 @@ |
|||
# 页面标题 |
|||
VUE_APP_TITLE = 填鸭测试环境 |
|||
VUE_APP_API_ROOT = / |
|||
# 接口请求地址,会设置到 axios 的 baseURL 参数上 |
|||
VUE_APP_API_ROOT = http://yigou.ketao.com/api/ |
|||
# 是否开启 CDN 支持,开启设置 ON,关闭设置 OFF |
|||
# 详情介绍请阅读 http://eoner.gitee.io/vue-automation/#/cdn |
|||
VUE_APP_CDN = OFF |
|||
# 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空 |
|||
VUE_APP_DEBUG_TOOL = |
|||
|
|||
@ -1,2 +1,9 @@ |
|||
VUE_APP_TITLE = 网站标题 |
|||
VUE_APP_API_ROOT = https://yigou.ketao.com/api/ |
|||
# 页面标题 |
|||
VUE_APP_TITLE = 填鸭 |
|||
# 接口请求地址,会设置到 axios 的 baseURL 参数上 |
|||
VUE_APP_API_ROOT = http://yigou.ketao.com/api/ |
|||
# 是否开启 CDN 支持,开启设置 ON,关闭设置 OFF |
|||
# 详情介绍请阅读 http://eoner.gitee.io/vue-automation/#/cdn |
|||
VUE_APP_CDN = OFF |
|||
# 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空 |
|||
VUE_APP_DEBUG_TOOL = |
|||
|
|||
@ -1,2 +1,5 @@ |
|||
dist/ |
|||
node_modules/ |
|||
babel.config.js |
|||
vue.config.js |
|||
.eslintrc.js |
|||
|
|||
@ -1,166 +1,88 @@ |
|||
// https://eslint.org/docs/user-guide/configuring
|
|||
|
|||
module.exports = { |
|||
root: true, |
|||
parserOptions: { |
|||
parser: 'babel-eslint' |
|||
}, |
|||
env: { |
|||
browser: true, |
|||
jquery: true |
|||
browser: true, |
|||
es6: true |
|||
}, |
|||
globals: { |
|||
process: true, |
|||
require: true, |
|||
module: true |
|||
}, |
|||
extends: [ |
|||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
|||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
|||
'plugin:vue/essential' |
|||
'plugin:vue/strongly-recommended', |
|||
'eslint:recommended' |
|||
], |
|||
// required to lint *.vue files
|
|||
plugins: [ |
|||
'vue' |
|||
], |
|||
// add your custom rules here
|
|||
'rules': { |
|||
'comma-dangle': ['error', 'never'], // 是否允许对象中出现结尾逗号
|
|||
'no-cond-assign': 2, // 条件语句的条件中不允许出现赋值运算符
|
|||
'no-console': 0, //不允许出现console语句
|
|||
'no-constant-condition': 2, // 条件语句的条件中不允许出现恒定不变的量
|
|||
'no-control-regex': 2, // 正则表达式中不允许出现控制字符
|
|||
'no-debugger': 1, // 不允许出现debugger语句
|
|||
'no-dupe-args': 2, // 函数定义的时候不允许出现重复的参数
|
|||
'no-dupe-keys': 2, // 对象中不允许出现重复的键
|
|||
'no-duplicate-case': 2, // switch语句中不允许出现重复的case标签
|
|||
'no-empty': 1, // 不允许出现空的代码块
|
|||
'no-empty-character-class': 2, // 正则表达式中不允许出现空的字符组
|
|||
'no-ex-assign': 0, // 在try catch语句中不允许重新分配异常变量
|
|||
'no-extra-boolean-cast': 2, // 不允许出现不必要的布尔值转换
|
|||
'no-extra-parens': 1, // 不允许出现不必要的圆括号
|
|||
'no-extra-semi': 2, // 不允许出现不必要的分号
|
|||
'no-func-assign': 1, // 不允许重新分配函数声明
|
|||
'no-inner-declarations': ['error', 'functions'], // 不允许在嵌套代码块里声明函数
|
|||
'no-invalid-regexp': 2, // 不允许在RegExp构造函数里出现无效的正则表达式
|
|||
'no-irregular-whitespace': 2, // 不允许出现不规则的空格
|
|||
'no-negated-in-lhs': 2, // 不允许在in表达式语句中对最左边的运算数使用取反操作
|
|||
'no-obj-calls': 2, // 不允许把全局对象属性当做函数来调用
|
|||
'no-regex-spaces': 2, // 正则表达式中不允许出现多个连续空格
|
|||
'quote-props': 2, // 对象中的属性名是否需要用引号引起来
|
|||
'no-sparse-arrays': 2, // 数组中不允许出现空位置
|
|||
'no-unreachable': 2, // 在return,throw,continue,break语句后不允许出现不可能到达的语句
|
|||
'use-isnan': 2, // 要求检查NaN的时候使用isNaN()
|
|||
'valid-jsdoc': ['error', { |
|||
'requireReturn': false, |
|||
'requireParamDescription': false, |
|||
'requireReturnDescription': true |
|||
}], // 强制JSDoc注释
|
|||
'valid-typeof': ['error', { 'requireStringLiterals': true }], // 在使用typeof表达式比较的时候强制使用有效的字符串
|
|||
'block-scoped-var': 2, // 将变量声明放在合适的代码块里
|
|||
'complexity': 0, // 限制条件语句的复杂度
|
|||
'consistent-return': 1, // 无论有没有返回值都强制要求return语句返回一个值
|
|||
'curly': ['error', 'all'], // 强制使用花括号的风格
|
|||
'default-case': 0, // 在switch语句中需要有default语句
|
|||
'no-alert': 1, // 不允许使用alert,confirm,prompt语句
|
|||
'no-caller': 2, // 不允许使用arguments.callee和arguments.caller属性
|
|||
'guard-for-in': 0, // 监视for in循环,防止出现不可预料的情况
|
|||
'no-div-regex': 2, // 不能使用看起来像除法的正则表达式
|
|||
'no-else-return': 0, // 如果if语句有return,else里的return不用放在else里
|
|||
'no-labels': ['error', { |
|||
'allowLoop': false, |
|||
'allowSwitch': false |
|||
}], // 不允许标签语句
|
|||
'no-eq-null': 1, // 不允许对null用==或者!=
|
|||
'no-eval': 1, // 不允许使用eval()
|
|||
'no-extend-native': 2, // 不允许扩展原生对象
|
|||
'no-extra-bind': 2, // 不允许不必要的函数绑定
|
|||
'no-fallthrough': 2, // 不允许switch按顺序全部执行所有case
|
|||
'no-floating-decimal': 2, // 不允许浮点数缺失数字
|
|||
'no-implied-eval': 2, // 不允许使用隐式eval()
|
|||
'no-iterator': 2, // 不允许使用__iterator__属性
|
|||
'no-lone-blocks': 2, // 不允许不必要的嵌套代码块
|
|||
'no-loop-func': 2, // 不允许在循环语句中进行函数声明
|
|||
'no-multi-spaces': 1, // 不允许出现多余的空格
|
|||
'no-multi-str': 2, // 不允许用\来让字符串换行
|
|||
'no-global-assign': 2, // 不允许重新分配原生对象
|
|||
'no-new': 2, // 不允许new一个实例后不赋值或者不比较
|
|||
'no-new-func': 2, // 不允许使用new Function
|
|||
'no-new-wrappers': 2, // 不允许使用new String,Number和Boolean对象
|
|||
'no-octal': 2, // 不允许使用八进制字面值
|
|||
'no-octal-escape': 2, // 不允许使用八进制转义序列
|
|||
'no-param-reassign': 0, // 不允许重新分配函数参数'no-proto': 2, //不允许使用__proto__属性
|
|||
'no-redeclare': 2, // 不允许变量重复声明
|
|||
'no-return-assign': 2, // 不允许在return语句中使用分配语句
|
|||
'no-script-url': 1, // 不允许使用javascript:void(0)
|
|||
'no-self-compare': 2, // 不允许自己和自己比较
|
|||
'no-sequences': 2, // 不允许使用逗号表达式
|
|||
'no-throw-literal': 2, // 不允许抛出字面量错误 throw 'error'
|
|||
'no-unused-expressions': 2, // 不允许无用的表达式
|
|||
'no-void': 2, // 不允许void操作符
|
|||
'no-warning-comments': [1, { 'terms': ['todo', 'fixme', 'any other term'] }], // 不允许警告备注
|
|||
'no-with': 2, // 不允许使用with语句
|
|||
'radix': 1, // 使用parseInt时强制使用基数来指定是十进制还是其他进制
|
|||
'vars-on-top': 0, // var必须放在作用域顶部
|
|||
'wrap-iife': [2, 'any'], // 立即执行表达式的括号风格
|
|||
'yoda': [2, 'never', { 'exceptRange': true }], // 不允许在if条件中使用yoda条件
|
|||
'strict': [2, 'function'], // 使用严格模式
|
|||
'no-catch-shadow': 2, // 不允许try catch语句接受的err变量与外部变量重名'no-delete-var': 2, // 不允许使用delete操作符
|
|||
'no-label-var': 2, // 不允许标签和变量同名
|
|||
'no-shadow': 2, // 外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
|
|||
'no-shadow-restricted-names': 2, // js关键字和保留字不能作为函数名或者变量名
|
|||
'no-undef': 2, // 不允许未声明的变量
|
|||
'no-undef-init': 2, // 不允许初始化变量时给变量赋值undefined
|
|||
'no-undefined': 1, // 不允许把undefined当做标识符使用
|
|||
'no-unused-vars': 'off', // 不允许有声明后未使用的变量或者参数
|
|||
'no-use-before-define': [2, 'nofunc'], // 不允许在未定义之前就使用变量'indent': 2, // 强制一致的缩进风格
|
|||
'brace-style': [2, '1tbs', { 'allowSingleLine': false }], // 大括号风格
|
|||
'camelcase': [2, { 'properties': 'never' }], // 强制驼峰命名规则
|
|||
'comma-style': [2, 'last'], // 逗号风格
|
|||
'consistent-this': [0, 'self'], // 当获取当前环境的this是用一样的风格
|
|||
'eol-last': 2, // 文件以换行符结束
|
|||
'func-names': 0, // 函数表达式必须有名字
|
|||
'func-style': 0, // 函数风格,规定只能使用函数声明或者函数表达式
|
|||
'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }], // 对象字面量中冒号的前后空格
|
|||
'max-nested-callbacks': 0, // 回调嵌套深度
|
|||
'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }], // 构造函数名字首字母要大写
|
|||
'new-parens': 2, // new时构造函数必须有小括号
|
|||
'newline-after-var': 0, // 变量声明后必须空一行
|
|||
'no-array-constructor': 2, // 不允许使用数组构造器
|
|||
'no-inline-comments': 0, // 不允许行内注释
|
|||
'no-lonely-if': 0, // 不允许else语句内只有if语句
|
|||
'no-mixed-spaces-and-tabs': [2, 'smart-tabs'], // 不允许混用tab和空格
|
|||
'no-multiple-empty-lines': [2, { 'max': 2 }], // 空行最多不能超过两行
|
|||
'no-nested-ternary': 2, // 不允许使用嵌套的三目运算符
|
|||
'no-new-object': 2, // 禁止使用new Object()
|
|||
// 'fun-call-spacing': 2, // 函数调用时,函数名与()之间不能有空格
|
|||
'no-ternary': 0, // 不允许使用三目运算符
|
|||
'no-trailing-spaces': 2, // 一行最后不允许有空格
|
|||
'no-underscore-dangle': 2, // 不允许标识符以下划线开头
|
|||
'no-extra-parens': 0, // 不允许出现多余的括号
|
|||
'no-async-promise-executor': 0, // 禁止使用异步函数作为 Promise executor
|
|||
'no-misleading-character-class': 0, // 不允许在字符类语法中出现由多个代码点组成的字符
|
|||
'no-useless-catch': 0, // 禁止不必要的 catch 子句
|
|||
'one-var': 0, // 强制变量声明放在一起
|
|||
'operator-assignment': 0, // 赋值运算符的风格
|
|||
'padded-blocks': [2, 'never'], // 块内行首行尾是否空行
|
|||
'quote-props': 0, // 对象字面量中属性名加引号
|
|||
'quotes': [1, 'single', { 'avoidEscape': false }], // 引号风格
|
|||
'semi': [0, 'always'], // 强制语句分号结尾
|
|||
'semi-spacing': [2, { 'before': false, 'after': true }], // 分后前后空格
|
|||
'sort-vars': 0, // 变量声明时排序
|
|||
'space-before-blocks': [2, 'always'], // 块前的空格
|
|||
'space-before-function-paren': [0, { 'anonymous': 'always', 'named': 'never' }], // 函数定义时括号前的空格
|
|||
'space-infix-ops': [2, { 'int32Hint': true }], // 操作符周围的空格
|
|||
'keyword-spacing': 2, // 关键字前后的空格
|
|||
'space-unary-ops': [2, { 'words': true, 'nonwords': false }], // 一元运算符前后不要加空格
|
|||
'wrap-regex': 2, // 正则表达式字面量用括号括起来
|
|||
'no-var': 0, // 使用let和const代替var
|
|||
'generator-star-spacing': [2, 'both'], // 生成器函数前后空格
|
|||
'max-depth': 0, // 嵌套块深度
|
|||
'max-len': 0, // 一行最大长度,单位为字符
|
|||
'max-params': 0, // 函数最多能有多少个参数
|
|||
'max-statements': 0, // 函数内最多有几个声明
|
|||
'no-bitwise': 0, // 不允许使用位运算符
|
|||
'no-plusplus': 0, // 不允许使用++ --运算符
|
|||
'indent': ['off', 2], // 关闭缩进校验
|
|||
'prefer-const': 0, // 要求使用 const 声明那些声明后不再被修改的变量
|
|||
'object-curly-spacing': [2, 'always'] // 强制在大括号中使用一致的空格
|
|||
parserOptions: { |
|||
ecmaVersion: 2015, |
|||
parser: 'babel-eslint', |
|||
sourceType: 'module' |
|||
}, |
|||
rules: { |
|||
// 代码风格
|
|||
'block-spacing': [2, 'always'], |
|||
'brace-style': [2, '1tbs', { |
|||
'allowSingleLine': true |
|||
}], |
|||
'comma-spacing': [2, { |
|||
'before': false, |
|||
'after': true |
|||
}], |
|||
'comma-dangle': [2, 'never'], |
|||
'comma-style': [2, 'last'], |
|||
'computed-property-spacing': [2, 'never'], |
|||
'indent': [2, 4, { |
|||
'SwitchCase': 1 |
|||
}], |
|||
'key-spacing': [2, { |
|||
'beforeColon': false, |
|||
'afterColon': true |
|||
}], |
|||
'keyword-spacing': [2, { |
|||
'before': true, |
|||
'after': true |
|||
}], |
|||
'linebreak-style': 0, |
|||
'multiline-ternary': [2, 'always-multiline'], |
|||
'no-multiple-empty-lines': [2, { |
|||
'max': 1 |
|||
}], |
|||
'no-unneeded-ternary': [2, { |
|||
'defaultAssignment': false |
|||
}], |
|||
'quotes': [2, 'single'], |
|||
'semi': [2, 'never'], |
|||
'space-before-blocks': [2, 'always'], |
|||
'space-before-function-paren': [2, 'never'], |
|||
'space-in-parens': [2, 'never'], |
|||
'space-infix-ops': 2, |
|||
'space-unary-ops': [2, { |
|||
'words': true, |
|||
'nonwords': false |
|||
}], |
|||
'spaced-comment': [2, 'always', { |
|||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] |
|||
}], |
|||
'switch-colon-spacing': [2, { |
|||
'after': true, |
|||
'before': false |
|||
}], |
|||
// ES6
|
|||
'arrow-parens': [2, 'as-needed'], |
|||
'arrow-spacing': [2, { |
|||
'before': true, |
|||
'after': true |
|||
}], |
|||
// Vue - https://github.com/vuejs/eslint-plugin-vue
|
|||
'vue/html-indent': [2, 4], |
|||
'vue/max-attributes-per-line': 0, |
|||
'vue/require-default-prop': 0, |
|||
'vue/singleline-html-element-content-newline': 0, |
|||
'vue/attributes-order': 2, |
|||
'vue/order-in-components': 2, |
|||
'vue/this-in-template': 0, |
|||
'vue/script-indent': [2, 4, { |
|||
'switchCase': 1 |
|||
}] |
|||
} |
|||
}; |
|||
|
|||
}; |
|||
|
|||
@ -1,2 +1,3 @@ |
|||
dist/ |
|||
node_modules/ |
|||
src/assets/sprites/ |
|||
|
|||
@ -1,201 +0,0 @@ |
|||
Apache License |
|||
Version 2.0, January 2004 |
|||
http://www.apache.org/licenses/ |
|||
|
|||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|||
|
|||
1. Definitions. |
|||
|
|||
"License" shall mean the terms and conditions for use, reproduction, |
|||
and distribution as defined by Sections 1 through 9 of this document. |
|||
|
|||
"Licensor" shall mean the copyright owner or entity authorized by |
|||
the copyright owner that is granting the License. |
|||
|
|||
"Legal Entity" shall mean the union of the acting entity and all |
|||
other entities that control, are controlled by, or are under common |
|||
control with that entity. For the purposes of this definition, |
|||
"control" means (i) the power, direct or indirect, to cause the |
|||
direction or management of such entity, whether by contract or |
|||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|||
outstanding shares, or (iii) beneficial ownership of such entity. |
|||
|
|||
"You" (or "Your") shall mean an individual or Legal Entity |
|||
exercising permissions granted by this License. |
|||
|
|||
"Source" form shall mean the preferred form for making modifications, |
|||
including but not limited to software source code, documentation |
|||
source, and configuration files. |
|||
|
|||
"Object" form shall mean any form resulting from mechanical |
|||
transformation or translation of a Source form, including but |
|||
not limited to compiled object code, generated documentation, |
|||
and conversions to other media types. |
|||
|
|||
"Work" shall mean the work of authorship, whether in Source or |
|||
Object form, made available under the License, as indicated by a |
|||
copyright notice that is included in or attached to the work |
|||
(an example is provided in the Appendix below). |
|||
|
|||
"Derivative Works" shall mean any work, whether in Source or Object |
|||
form, that is based on (or derived from) the Work and for which the |
|||
editorial revisions, annotations, elaborations, or other modifications |
|||
represent, as a whole, an original work of authorship. For the purposes |
|||
of this License, Derivative Works shall not include works that remain |
|||
separable from, or merely link (or bind by name) to the interfaces of, |
|||
the Work and Derivative Works thereof. |
|||
|
|||
"Contribution" shall mean any work of authorship, including |
|||
the original version of the Work and any modifications or additions |
|||
to that Work or Derivative Works thereof, that is intentionally |
|||
submitted to Licensor for inclusion in the Work by the copyright owner |
|||
or by an individual or Legal Entity authorized to submit on behalf of |
|||
the copyright owner. For the purposes of this definition, "submitted" |
|||
means any form of electronic, verbal, or written communication sent |
|||
to the Licensor or its representatives, including but not limited to |
|||
communication on electronic mailing lists, source code control systems, |
|||
and issue tracking systems that are managed by, or on behalf of, the |
|||
Licensor for the purpose of discussing and improving the Work, but |
|||
excluding communication that is conspicuously marked or otherwise |
|||
designated in writing by the copyright owner as "Not a Contribution." |
|||
|
|||
"Contributor" shall mean Licensor and any individual or Legal Entity |
|||
on behalf of whom a Contribution has been received by Licensor and |
|||
subsequently incorporated within the Work. |
|||
|
|||
2. Grant of Copyright License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
copyright license to reproduce, prepare Derivative Works of, |
|||
publicly display, publicly perform, sublicense, and distribute the |
|||
Work and such Derivative Works in Source or Object form. |
|||
|
|||
3. Grant of Patent License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
(except as stated in this section) patent license to make, have made, |
|||
use, offer to sell, sell, import, and otherwise transfer the Work, |
|||
where such license applies only to those patent claims licensable |
|||
by such Contributor that are necessarily infringed by their |
|||
Contribution(s) alone or by combination of their Contribution(s) |
|||
with the Work to which such Contribution(s) was submitted. If You |
|||
institute patent litigation against any entity (including a |
|||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
|||
or a Contribution incorporated within the Work constitutes direct |
|||
or contributory patent infringement, then any patent licenses |
|||
granted to You under this License for that Work shall terminate |
|||
as of the date such litigation is filed. |
|||
|
|||
4. Redistribution. You may reproduce and distribute copies of the |
|||
Work or Derivative Works thereof in any medium, with or without |
|||
modifications, and in Source or Object form, provided that You |
|||
meet the following conditions: |
|||
|
|||
(a) You must give any other recipients of the Work or |
|||
Derivative Works a copy of this License; and |
|||
|
|||
(b) You must cause any modified files to carry prominent notices |
|||
stating that You changed the files; and |
|||
|
|||
(c) You must retain, in the Source form of any Derivative Works |
|||
that You distribute, all copyright, patent, trademark, and |
|||
attribution notices from the Source form of the Work, |
|||
excluding those notices that do not pertain to any part of |
|||
the Derivative Works; and |
|||
|
|||
(d) If the Work includes a "NOTICE" text file as part of its |
|||
distribution, then any Derivative Works that You distribute must |
|||
include a readable copy of the attribution notices contained |
|||
within such NOTICE file, excluding those notices that do not |
|||
pertain to any part of the Derivative Works, in at least one |
|||
of the following places: within a NOTICE text file distributed |
|||
as part of the Derivative Works; within the Source form or |
|||
documentation, if provided along with the Derivative Works; or, |
|||
within a display generated by the Derivative Works, if and |
|||
wherever such third-party notices normally appear. The contents |
|||
of the NOTICE file are for informational purposes only and |
|||
do not modify the License. You may add Your own attribution |
|||
notices within Derivative Works that You distribute, alongside |
|||
or as an addendum to the NOTICE text from the Work, provided |
|||
that such additional attribution notices cannot be construed |
|||
as modifying the License. |
|||
|
|||
You may add Your own copyright statement to Your modifications and |
|||
may provide additional or different license terms and conditions |
|||
for use, reproduction, or distribution of Your modifications, or |
|||
for any such Derivative Works as a whole, provided Your use, |
|||
reproduction, and distribution of the Work otherwise complies with |
|||
the conditions stated in this License. |
|||
|
|||
5. Submission of Contributions. Unless You explicitly state otherwise, |
|||
any Contribution intentionally submitted for inclusion in the Work |
|||
by You to the Licensor shall be under the terms and conditions of |
|||
this License, without any additional terms or conditions. |
|||
Notwithstanding the above, nothing herein shall supersede or modify |
|||
the terms of any separate license agreement you may have executed |
|||
with Licensor regarding such Contributions. |
|||
|
|||
6. Trademarks. This License does not grant permission to use the trade |
|||
names, trademarks, service marks, or product names of the Licensor, |
|||
except as required for reasonable and customary use in describing the |
|||
origin of the Work and reproducing the content of the NOTICE file. |
|||
|
|||
7. Disclaimer of Warranty. Unless required by applicable law or |
|||
agreed to in writing, Licensor provides the Work (and each |
|||
Contributor provides its Contributions) on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|||
implied, including, without limitation, any warranties or conditions |
|||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|||
PARTICULAR PURPOSE. You are solely responsible for determining the |
|||
appropriateness of using or redistributing the Work and assume any |
|||
risks associated with Your exercise of permissions under this License. |
|||
|
|||
8. Limitation of Liability. In no event and under no legal theory, |
|||
whether in tort (including negligence), contract, or otherwise, |
|||
unless required by applicable law (such as deliberate and grossly |
|||
negligent acts) or agreed to in writing, shall any Contributor be |
|||
liable to You for damages, including any direct, indirect, special, |
|||
incidental, or consequential damages of any character arising as a |
|||
result of this License or out of the use or inability to use the |
|||
Work (including but not limited to damages for loss of goodwill, |
|||
work stoppage, computer failure or malfunction, or any and all |
|||
other commercial damages or losses), even if such Contributor |
|||
has been advised of the possibility of such damages. |
|||
|
|||
9. Accepting Warranty or Additional Liability. While redistributing |
|||
the Work or Derivative Works thereof, You may choose to offer, |
|||
and charge a fee for, acceptance of support, warranty, indemnity, |
|||
or other liability obligations and/or rights consistent with this |
|||
License. However, in accepting such obligations, You may act only |
|||
on Your own behalf and on Your sole responsibility, not on behalf |
|||
of any other Contributor, and only if You agree to indemnify, |
|||
defend, and hold each Contributor harmless for any liability |
|||
incurred by, or claims asserted against, such Contributor by reason |
|||
of your accepting any such warranty or additional liability. |
|||
|
|||
END OF TERMS AND CONDITIONS |
|||
|
|||
APPENDIX: How to apply the Apache License to your work. |
|||
|
|||
To apply the Apache License to your work, attach the following |
|||
boilerplate notice, with the fields enclosed by brackets "[]" |
|||
replaced with your own identifying information. (Don't include |
|||
the brackets!) The text should be enclosed in the appropriate |
|||
comment syntax for the file format. We also recommend that a |
|||
file or class name and description of purpose be included on the |
|||
same "printed page" as the copyright notice for easier |
|||
identification within third-party archives. |
|||
|
|||
Copyright [yyyy] [name of copyright owner] |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
@ -1,65 +1,36 @@ |
|||
# tduck-front |
|||
# vue-automation |
|||
|
|||
## 说明 |
|||
## 这是什么 |
|||
|
|||
该仓库是为统一 Vue 项目初期配置而设立,方便快速进行业务开发,基于 Vue CLI 3 。 |
|||
一款开箱即用的 Vue 项目模版,基于 Vue CLI |
|||
|
|||
## 使用 |
|||
## 特点 |
|||
|
|||
### 方法 1 |
|||
- 默认集成 vue-router 和 vuex |
|||
- 全局 SASS 资源自动引入 |
|||
- 精灵图自动生成 |
|||
- 全局组件自动注册 |
|||
- CDN支持,优化打包体积 |
|||
- 轻松实现团队代码规范 |
|||
|
|||
> 适用于初学者快速上手,项目里包含演示文件,方便学习 |
|||
## 文档 |
|||
|
|||
拉取该项目到本地,安装依赖包后运行即可。 |
|||
[Github](https://hooray.github.io/vue-automation) |
|||
|
|||
运行后,可以看到功能演示,同时项目目录里带有 `example` 的目录均为演示代码。 |
|||
[Gitee](http://eoner.gitee.io/vue-automation)(推荐国内用户访问) |
|||
|
|||
## 支持 |
|||
|
|||
## 依赖 |
|||
给个小 ❤️ 吧~ |
|||
|
|||
- vue-router |
|||
- vuex |
|||
- axios |
|||
- lodash |
|||
- dayjs |
|||
- vue-cookies |
|||
- vue-meta |
|||
- node-sass |
|||
- sass-loader |
|||
- sass-resources-loader |
|||
- svg-sprite-loader |
|||
- webpack-spritesmith |
|||
[](https://github.com/hooray/vue-automation/stargazers) |
|||
|
|||
## 全局 SCSS 资源 |
|||
[](https://gitee.com/eoner/vue-automation/stargazers) |
|||
|
|||
> 全局 SCSS 资源通过 [sass-resources-loader](https://www.npmjs.com/package/sass-resources-loader) 实现 |
|||
> |
|||
> 注意!并不是全局样式,而是 SCSS 资源,是变量、@mixin 、@function 这些东西 |
|||
## 推广 |
|||
|
|||
在 `assets/styles/resources/` 目录下存放全局的 scss 资源,也就是说在这个目录里的文件,无需在页面上引用即可生效并使用。 |
|||
[](https://hooray.gitee.io/fantastic-admin) |
|||
|
|||
例子中默认存放了 `utils.scss` 文件,里面有几个 `@mixin` 和 `%` ,你可以尝试在页面中使用它们看看效果。 |
|||
|
|||
同样, `assets/sprites/` 目录下生成的 scss 文件也是默认全局。 |
|||
|
|||
## 全局组件 |
|||
|
|||
> 全局组件会自动注册,可直接使用。 |
|||
|
|||
在 `components/global/` 目录下存放全局组件,需要注意各个组件按文件夹区分,文件夹名称与组件名无关联。 |
|||
|
|||
每个组件的文件夹内至少保留一个文件名为 index 的组件入口,例如 index.vue 。 |
|||
|
|||
普通组件必须设置 name 并保证其唯一,自动注册会将组件的 name 设为组件名,可参考 SvgIcon 组件写法。 |
|||
|
|||
如果组件是通过 js 进行调用,则确保组件入口文件为 index.js,可参考 ExampleNotice 组件。 |
|||
|
|||
|
|||
## 路由 |
|||
|
|||
路由也实现自动注册,但因为有优先级的概念,先定义的会先匹配,所以同一模块下的路由必须放在一个路由配置文件里,具体可参考 `router/modules/example.js` 文件。 |
|||
|
|||
## Vuex |
|||
|
|||
Vuex 同样实现了自动注册,开发只需关注 `store/modules/` 文件夹里的文件即可,同样也按照模块区分文件。 |
|||
[Fantastic-admin](https://hooray.gitee.io/fantastic-admin) |
|||
|
|||
一款开箱即用的 Vue 中后台管理系统框架 |
|||
|
|||
@ -1,5 +1,10 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/cli-plugin-babel/preset' |
|||
] |
|||
], |
|||
env: { |
|||
development: { |
|||
plugins: ['dynamic-import-node'] |
|||
} |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because it is too large
@ -1,63 +1,62 @@ |
|||
{ |
|||
"name": "tduck-front", |
|||
"version": "0.1.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"serve": "vue-cli-service serve ", |
|||
"build-dev": "vue-cli-service build --mode development --dest dist-dev", |
|||
"build": "vue-cli-service build", |
|||
"lint": "vue-cli-service lint", |
|||
"svgo": "svgo -f src/assets/icons" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^0.19.0", |
|||
"core-js": "^3.4.1", |
|||
"dayjs": "^1.8.17", |
|||
"element-ui": "^2.13.0", |
|||
"eslint": "^6.7.2", |
|||
"eslint-config-standard": "^14.1.0", |
|||
"eslint-plugin-import": "^2.19.1", |
|||
"eslint-plugin-node": "^10.0.0", |
|||
"eslint-plugin-promise": "^4.2.1", |
|||
"eslint-plugin-standard": "^4.0.1", |
|||
"eslint-plugin-vue": "^6.0.1", |
|||
"js-md5": "^0.7.3", |
|||
"lodash": "^4.17.19", |
|||
"nprogress": "^0.2.0", |
|||
"vue": "^2.6.0", |
|||
"vue-cookies": "^1.5.7", |
|||
"vue-meta": "^2.3.1", |
|||
"vue-router": "^3.1.3", |
|||
"vuex": "^3.1.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "^4.0.0", |
|||
"@vue/cli-plugin-eslint": "^4.0.0", |
|||
"@vue/cli-service": "^4.0.0", |
|||
"babel-eslint": "^10.0.3", |
|||
"eslint": "^6.6.0", |
|||
"eslint-plugin-vue": "^6.0.1", |
|||
"node-sass": "^4.13.1", |
|||
"sass-loader": "^8.0.0", |
|||
"sass-resources-loader": "^2.0.1", |
|||
"standard": "^14.3.1", |
|||
"stylelint": "^12.0.0", |
|||
"stylelint-config-recommended-scss": "^4.0.0", |
|||
"stylelint-config-standard": "^19.0.0", |
|||
"stylelint-scss": "^3.4.1", |
|||
"svg-sprite-loader": "^4.1.6", |
|||
"svgo": "^1.3.0", |
|||
"vue-template-compiler": "^2.6.0", |
|||
"webpack-spritesmith": "^1.0.2" |
|||
}, |
|||
"postcss": { |
|||
"plugins": { |
|||
"autoprefixer": {} |
|||
} |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not ie <= 8" |
|||
] |
|||
"name": "tduck-front", |
|||
"version": "0.1.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"serve": "vue-cli-service serve", |
|||
"build-dev": "vue-cli-service build --mode development --dest dist-dev", |
|||
"build": "vue-cli-service build", |
|||
"lint": "vue-cli-service lint", |
|||
"stylelint": "vue-cli-service lint:style", |
|||
"svgo": "svgo -f src/assets/icons", |
|||
"new": "plop" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^0.21.0", |
|||
"core-js": "^3.6.4", |
|||
"dayjs": "^1.9.4", |
|||
"element-ui": "^2.14.0", |
|||
"js-cookie": "^2.2.1", |
|||
"js-md5": "^0.7.3", |
|||
"nprogress": "^0.2.0", |
|||
"vue": "^2.6.12", |
|||
"vue-meta": "^2.4.0", |
|||
"vue-router": "^3.4.8", |
|||
"vuex": "^3.5.1" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "^4.5.8", |
|||
"@vue/cli-plugin-eslint": "^4.5.8", |
|||
"@vue/cli-service": "^4.5.8", |
|||
"@winner-fed/vue-cli-plugin-stylelint": "^1.0.4", |
|||
"babel-eslint": "^10.1.0", |
|||
"babel-plugin-dynamic-import-node": "^2.3.3", |
|||
"eslint": "^7.12.1", |
|||
"eslint-plugin-vue": "^7.1.0", |
|||
"html-webpack-plugin": "^4.5.0", |
|||
"husky": "^4.3.0", |
|||
"lint-staged": "^10.5.1", |
|||
"plop": "^2.7.4", |
|||
"sass": "^1.28.0", |
|||
"sass-loader": "^10.0.4", |
|||
"sass-resources-loader": "^2.1.1", |
|||
"stylelint": "^13.7.2", |
|||
"stylelint-config-recommended-scss": "^4.2.0", |
|||
"stylelint-config-standard": "^20.0.0", |
|||
"stylelint-scss": "^3.18.0", |
|||
"svg-sprite-loader": "^5.0.0", |
|||
"svgo": "^1.3.0", |
|||
"vue-template-compiler": "^2.6.12", |
|||
"webpack-spritesmith": "^1.1.0" |
|||
}, |
|||
"postcss": { |
|||
"plugins": { |
|||
"autoprefixer": {} |
|||
} |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not ie <= 8" |
|||
] |
|||
} |
|||
|
|||
@ -1,20 +1,37 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|||
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
|||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
|||
<title>TDuck Cloud</title> |
|||
<style> |
|||
body { |
|||
margin: 0px; |
|||
background-color: #FFFFFF; |
|||
} |
|||
</style> |
|||
<title><%= htmlWebpackPlugin.options.title %></title> |
|||
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> |
|||
<!-- 使用CDN的CSS文件 --> |
|||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow preload" as="style"> |
|||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow stylesheet"> |
|||
<% } %> |
|||
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> |
|||
<!-- 使用CDN的JS文件 --> |
|||
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="external nofollow preload" as="script"> |
|||
<% } %> |
|||
</head> |
|||
<body> |
|||
<noscript> |
|||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
|||
</noscript> |
|||
<div id="app"></div> |
|||
<!-- built files will be auto injected --> |
|||
</body> |
|||
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> |
|||
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> |
|||
<% } %> |
|||
<% if (htmlWebpackPlugin.options.debugTool == 'eruda') { %> |
|||
<script src="https://cdn.jsdelivr.net/npm/eruda/eruda.min.js"></script> |
|||
<script>eruda.init();</script> |
|||
<% } %> |
|||
<% if (htmlWebpackPlugin.options.debugTool == 'vconsole') { %> |
|||
<script src="https://cdn.jsdelivr.net/npm/vconsole/dist/vconsole.min.js"></script> |
|||
<script>new VConsole();</script> |
|||
<% } %> |
|||
</body> |
|||
</html> |
|||
|
|||
@ -1,65 +0,0 @@ |
|||
{ |
|||
// Default options |
|||
'functions': true, |
|||
'variableNameTransforms': ['dasherize'] |
|||
} |
|||
|
|||
{{#block "sprites"}} |
|||
{{#each sprites}} |
|||
${{../spritesheet_info.strings.name}}-sprite-{{strings.name}}: ({{px.x}}, {{px.y}}, {{px.offset_x}}, {{px.offset_y}}, {{px.width}}, {{px.height}}, {{px.total_width}}, {{px.total_height}}, '{{{escaped_image}}}', '{{name}}'); |
|||
{{/each}} |
|||
|
|||
${{spritesheet_info.strings.name}}-sprites: ( |
|||
{{#each sprites}} |
|||
{{strings.name}}: ${{../spritesheet_info.strings.name}}-sprite-{{strings.name}}, |
|||
{{/each}} |
|||
); |
|||
{{/block}} |
|||
|
|||
{{#block "sprite-functions"}} |
|||
{{#if options.functions}} |
|||
@mixin {{spritesheet_info.strings.name}}-sprite-width($sprite) { |
|||
width: nth($sprite, 5); |
|||
} |
|||
|
|||
@mixin {{spritesheet_info.strings.name}}-sprite-height($sprite) { |
|||
height: nth($sprite, 6); |
|||
} |
|||
|
|||
@mixin {{spritesheet_info.strings.name}}-sprite-position($sprite) { |
|||
$sprite-offset-x: nth($sprite, 3); |
|||
$sprite-offset-y: nth($sprite, 4); |
|||
background-position: $sprite-offset-x $sprite-offset-y; |
|||
} |
|||
|
|||
@mixin {{spritesheet_info.strings.name}}-sprite-size($sprite) { |
|||
background-size: nth($sprite, 7) nth($sprite, 8); |
|||
} |
|||
|
|||
@mixin {{spritesheet_info.strings.name}}-sprite-image($sprite) { |
|||
$sprite-image: nth($sprite, 9); |
|||
background-image: url(#{$sprite-image}); |
|||
} |
|||
|
|||
@mixin {{spritesheet_info.strings.name}}-sprite($name) { |
|||
@include {{spritesheet_info.strings.name}}-sprite-image(map-get(${{spritesheet_info.strings.name}}-sprites, #{$name})); |
|||
@include {{spritesheet_info.strings.name}}-sprite-position(map-get(${{spritesheet_info.strings.name}}-sprites, #{$name})); |
|||
@include {{spritesheet_info.strings.name}}-sprite-size(map-get(${{spritesheet_info.strings.name}}-sprites, #{$name})); |
|||
@include {{spritesheet_info.strings.name}}-sprite-width(map-get(${{spritesheet_info.strings.name}}-sprites, #{$name})); |
|||
@include {{spritesheet_info.strings.name}}-sprite-height(map-get(${{spritesheet_info.strings.name}}-sprites, #{$name})); |
|||
} |
|||
{{/if}} |
|||
{{/block}} |
|||
|
|||
{{#block "spritesheet-functions"}} |
|||
{{#if options.functions}} |
|||
@mixin all-{{spritesheet_info.strings.name}}-sprites() { |
|||
@each $key, $val in ${{spritesheet_info.strings.name}}-sprites { |
|||
$sprite-name: nth($val, 10); |
|||
.{{spritesheet_info.strings.name}}-#{$sprite-name}-sprites { |
|||
@include {{spritesheet_info.strings.name}}-sprite($key); |
|||
} |
|||
} |
|||
} |
|||
{{/if}} |
|||
{{/block}} |
|||
@ -0,0 +1 @@ |
|||
// 全局变量 |
|||
@ -1,16 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<ul> |
|||
<li v-for="(item, index) in list" :key="index">{{ item }}</li> |
|||
</ul> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ExampleList', |
|||
props: { |
|||
list: Array |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,18 +0,0 @@ |
|||
import Vue from 'vue' |
|||
|
|||
const constructor = Vue.extend(require('./main.vue').default) |
|||
|
|||
let instance |
|||
|
|||
const exampleNotice = options => { |
|||
options = options || {} |
|||
instance = new constructor({ |
|||
data: options |
|||
}) |
|||
instance.vm = instance.$mount() |
|||
instance.dom = instance.vm.$el |
|||
document.body.appendChild(instance.dom) |
|||
return instance.vm |
|||
} |
|||
|
|||
export default exampleNotice |
|||
@ -1,42 +0,0 @@ |
|||
<template> |
|||
<transition name="notice"> |
|||
<div v-if="show" class="notice"> |
|||
{{ content }} |
|||
</div> |
|||
</transition> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ExampleNotice', |
|||
data() { |
|||
return { |
|||
show: false, |
|||
content: '' |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.show = true |
|||
setTimeout(() => { |
|||
this.show = false |
|||
}, 2000) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.notice { |
|||
padding: 10px; |
|||
background-color: #eee; |
|||
border-radius: 10px; |
|||
@include position-center(xy); |
|||
} |
|||
.notice-leave-active, |
|||
.notice-enter-active { |
|||
transition: all 0.3s; |
|||
} |
|||
.notice-enter, |
|||
.notice-leave-to { |
|||
opacity: 0; |
|||
} |
|||
</style> |
|||
@ -1,36 +0,0 @@ |
|||
<template> |
|||
<svg :class="svgClass" aria-hidden="true" v-on="$listeners"> |
|||
<use :xlink:href="`#icon-${iconClass}`" /> |
|||
</svg> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'SvgIcon', |
|||
props: { |
|||
iconClass: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
className: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
computed: { |
|||
svgClass() { |
|||
return this.className ? ('svg-icon ' + this.className) : 'svg-icon' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.svg-icon { |
|||
width: 1em; |
|||
height: 1em; |
|||
vertical-align: -0.15em; |
|||
fill: currentColor; |
|||
overflow: hidden; |
|||
} |
|||
</style> |
|||
@ -1,84 +0,0 @@ |
|||
import ExampleLayout from '@/layout/example' |
|||
|
|||
export default { |
|||
path: '/example', |
|||
redirect: '/example/sprite', |
|||
component: ExampleLayout, |
|||
children: [ |
|||
{ |
|||
path: 'sprite', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/sprite.vue') |
|||
}, |
|||
{ |
|||
path: 'svgicon', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/svgicon.vue') |
|||
}, |
|||
{ |
|||
path: 'globalComponent', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/global.component.vue') |
|||
}, |
|||
{ |
|||
path: 'axios', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/axios.vue') |
|||
}, |
|||
{ |
|||
path: 'cookie', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/cookie.vue') |
|||
}, |
|||
{ |
|||
path: 'meta', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/meta.vue') |
|||
}, |
|||
{ |
|||
path: 'vuex', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/vuex.vue') |
|||
}, |
|||
{ |
|||
path: 'component', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/component.vue') |
|||
}, |
|||
{ |
|||
path: 'params/:test', |
|||
name: 'exampleParams', // 设置路由的name时,建议加上模块名,避免name和其他模块重名
|
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/params.vue') |
|||
}, |
|||
{ |
|||
path: 'query', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/query.vue') |
|||
}, |
|||
{ |
|||
path: 'reload', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/reload.vue') |
|||
}, |
|||
{ |
|||
path: 'permission/router', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/permission.router.vue'), |
|||
meta: { |
|||
requireLogin: true // 鉴权
|
|||
} |
|||
}, |
|||
{ |
|||
path: 'permission/js', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/permission.js.vue') |
|||
}, |
|||
{ |
|||
path: 'user', |
|||
component: () => |
|||
import(/* webpackChunkName: 'example' */ '@/views/example/user.vue') |
|||
} |
|||
|
|||
] |
|||
} |
|||
@ -1,85 +0,0 @@ |
|||
import md5 from 'js-md5' |
|||
import signSecret from './constants' |
|||
|
|||
export default class signMd5Utils { |
|||
/** |
|||
* json参数升序 |
|||
* @param jsonObj 发送参数 |
|||
*/ |
|||
|
|||
static sortAsc(jsonObj) { |
|||
let arr = new Array() |
|||
let num = 0 |
|||
for (let i in jsonObj) { |
|||
arr[num] = i |
|||
num++ |
|||
} |
|||
let sortArr = arr.sort() |
|||
let sortObj = {} |
|||
for (let i in sortArr) { |
|||
sortObj[sortArr[i]] = jsonObj[sortArr[i]] |
|||
} |
|||
return sortObj |
|||
} |
|||
|
|||
/** |
|||
* @param url 请求的url,应该包含请求参数(url的?后面的参数) |
|||
* @param requestParams 请求参数(POST的JSON参数) |
|||
* @returns {string} 获取签名 |
|||
*/ |
|||
static getSign(url, requestParams) { |
|||
|
|||
let urlParams = this.parseQueryString(url) |
|||
let jsonObj = this.mergeObject(urlParams, requestParams) |
|||
let requestBody = this.sortAsc(jsonObj) |
|||
return md5(signSecret + JSON.stringify(requestBody)).toLowerCase() |
|||
} |
|||
|
|||
/** |
|||
* @param url 请求的url |
|||
* @returns {{}} 将url中请求参数组装成json对象(url的?后面的参数) |
|||
*/ |
|||
static parseQueryString(url) { |
|||
let urlReg = /^[^\?]+\?([\w\W]+)$/, |
|||
paramReg = /([^&=]+)=([\w\W]*?)(&|$|#)/g, |
|||
urlArray = urlReg.exec(url), |
|||
result = {} |
|||
if (urlArray && urlArray[1]) { |
|||
let paramString = urlArray[1], paramResult |
|||
while ((paramResult = paramReg.exec(paramString)) != null) { |
|||
result[paramResult[1]] = '' + paramResult[2] |
|||
} |
|||
} |
|||
return result |
|||
} |
|||
|
|||
/** |
|||
* @returns {*} 将两个对象合并成一个 |
|||
*/ |
|||
static mergeObject(objectOne, objectTwo) { |
|||
if (Object.keys(objectTwo).length > 0) { |
|||
for (let key in objectTwo) { |
|||
// eslint-disable-next-line no-prototype-builtins
|
|||
if (objectTwo.hasOwnProperty(key) === true) { |
|||
objectOne[key] = '' + objectTwo[key] |
|||
} |
|||
} |
|||
} |
|||
return objectOne |
|||
} |
|||
|
|||
static urlEncode(param, key, encode) { |
|||
if (param == null) return '' |
|||
let paramStr = '' |
|||
let t = typeof (param) |
|||
if (t == 'string' || t == 'number' || t == 'boolean') { |
|||
paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param) |
|||
} else { |
|||
for (let i in param) { |
|||
let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i) |
|||
paramStr += this.urlEncode(param[i], k, encode) |
|||
} |
|||
} |
|||
return paramStr |
|||
} |
|||
} |
|||
@ -1,39 +1,199 @@ |
|||
<template> |
|||
<div id="login"> |
|||
<el-row class="loginBody"> |
|||
<el-col :span="12" style="border:solid thin black;"> |
|||
<img class="loginBackImg" src="http://q2fgufcw6.bkt.clouddn.com/login-banner"/> |
|||
<el-col :span="12"> |
|||
<img class="loginBackImg" src="http://qiniu.smileyi.top/login-banner"> |
|||
</el-col> |
|||
<el-col :span="12" style="border:solid thin black;"> |
|||
<el-tabs v-model="activeName"> |
|||
<el-tab-pane label="微信扫码登录" name="wechat"> |
|||
微信扫码登录主体 |
|||
<el-col :span="12"> |
|||
<el-tabs v-if="formType=='login'" v-model="loginType" class="login-form-tab" style="width: 320px;" |
|||
@tab-click="loginTypeHandleClick" |
|||
> |
|||
<el-tab-pane label="微信扫码登录" name="wx"> |
|||
<div class="wx-login"> |
|||
<div style="text-align: center;"> |
|||
<img class="qrcode" :src="wxLoginQrCode"> |
|||
</div> |
|||
<div style="text-align: center;"> |
|||
<el-link icon="el-icon-refresh-left" :underline="false">刷新二维码</el-link> |
|||
</div> |
|||
<el-divider style="width: 100px;" /> |
|||
<div style="display: flex; flex-direction: row;"> |
|||
<el-link style="margin-left: 20px;">忘记密码</el-link> |
|||
<el-link style="margin-left: 20px;" @click="()=>{this.formType='reg'}">立即注册</el-link> |
|||
<div class="other-login"> |
|||
<svg-icon name="loginQQ" class="other-login-icon" /> |
|||
<svg-icon name="loginWx" class="other-login-icon" /> |
|||
</div> |
|||
</div> |
|||
<el-divider style="width: 100px;" /> |
|||
<p class="login-tip">关于TDuckCloud登录</p> |
|||
<p class="login-tip"> |
|||
若微信扫码失败,请打开 微信授权页面 登录 |
|||
若QQ登录填鸭云异常,可查阅 帮助文档 |
|||
若因微信、QQ、公众号冻结或账号密码找回失败等无法登录,可 自助申请 登录账号 |
|||
</p> |
|||
</div> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="账号密码登录" name="account"> |
|||
账号密码登录主体 |
|||
<el-form ref="form" label-position="top" size="small" :model="account" |
|||
class="account-login-form" |
|||
> |
|||
<el-form-item label="手机号/邮箱登录"> |
|||
<el-input v-model="account.username" placeholder="请输入手机号/邮箱" /> |
|||
</el-form-item> |
|||
<el-form-item label="密码"> |
|||
<el-input v-model="account.password" placeholder="请输入密码" show-password /> |
|||
</el-form-item> |
|||
<el-form-item label=""> |
|||
<el-radio v-model="agreeProtocol" label="" /> |
|||
<span class="protocol-tip">我已同意</span> |
|||
<el-link :underline="false" type="primary" class="protocol-tip">《TDuck用户服务协议》</el-link> |
|||
<el-link :underline="false" type="primary" class="protocol-tip" style="float: right;">忘记密码?</el-link> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button style="width: 100%;" type="primary">登录</el-button> |
|||
</el-form-item> |
|||
<el-form-item style="text-align: center;"> |
|||
<span class="protocol-tip">使用第三方登录 或 </span> |
|||
<el-link :underline="false" type="primary" class="protocol-tip" @click="()=>{this.formType='reg'}">立即注册</el-link> |
|||
<div class="other-login"> |
|||
<svg-icon name="loginQQ" class="other-login-icon" /> |
|||
<svg-icon name="loginWx" class="other-login-icon" /> |
|||
</div> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
<div style="height:70px;border:solid thin black;"></div><!-- 暂时用来撑下面的高度,等菜🐎把图片确定以后再把此div移除 --> |
|||
<el-tabs v-if="formType==='reg'" v-model="regType" class="login-form" style="width: 300px;" |
|||
@tab-click="loginTypeHandleClick" |
|||
> |
|||
<el-tab-pane label="手机号注册" name="regPhone"> |
|||
<el-form ref="form" :model="account" label-width="0px"> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.username" placeholder="请输入手机号" /> |
|||
</el-form-item> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.password" placeholder="请输入密码" /> |
|||
</el-form-item> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.code" style="width: 150px;" placeholder="请输入验证码" /> |
|||
<el-button style="margin-left: 20px;" type="primary">发送验证码</el-button> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" width: 100%;>登录</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="邮箱注册" name="regEmail"> |
|||
<el-form ref="form" :model="account" label-width="0px"> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.username" placeholder="请输入邮箱" /> |
|||
</el-form-item> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.password" placeholder="请输入密码" /> |
|||
</el-form-item> |
|||
<el-form-item label=""> |
|||
<el-input v-model="account.code" style="width: 150px;" placeholder="请输入验证码" /> |
|||
<el-button style="margin-left: 20px;" type="primary">发送验证码</el-button> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" style="width: 100%;">确定</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
<div style="display: flex; flex-direction: row;"> |
|||
<el-link style="margin-left: 20px;">忘记密码</el-link> |
|||
<el-link style="margin-left: 20px;" @click="reigsterHandleClick">立即注册</el-link> |
|||
<div class="other-login"> |
|||
<svg-icon name="loginQQ" class="other-login-icon" /> |
|||
<svg-icon name="loginWx" class="other-login-icon" /> |
|||
</div> |
|||
</div> |
|||
</el-tabs> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'login', |
|||
name: 'Login', |
|||
data() { |
|||
return { |
|||
activeName: 'wechat' |
|||
loginType: 'wx', |
|||
formType: 'reg', |
|||
regType: 'regPhone', |
|||
agreeProtocol: '', |
|||
account: { |
|||
username: '', |
|||
password: '' |
|||
}, |
|||
wxLoginQrCode: 'http://qiniu.smileyi.top/20191213/9f217b754ad44f0caaa83040ce62fe93.png' |
|||
} |
|||
}, |
|||
methods: { |
|||
loginTypeHandleClick() { |
|||
}, |
|||
reigsterHandleClick() { |
|||
}, |
|||
login() { |
|||
this.$store.dispatch('token/login').then(() => { |
|||
// 登录成功后路由跳回 |
|||
if (this.$route.query.redirect) { |
|||
this.$router.replace({ |
|||
path: this.$route.query.redirect |
|||
}) |
|||
} else { |
|||
if (window.history.length <= 1) { |
|||
this.$router.push({path: '/'}) |
|||
} else { |
|||
this.$router.go(-1) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
.loginBody { |
|||
border: solid thin black; |
|||
margin: 70px 0px 0px 0px; |
|||
/* border: solid thin black; */ |
|||
margin: 70px 0 0 0; |
|||
} |
|||
.loginBackImg { |
|||
width: 100%; |
|||
} |
|||
.login-form-tab { |
|||
margin-left: 100px; |
|||
height: 500px; |
|||
width: 520px; |
|||
.wx-login { |
|||
display: flex; |
|||
align-content: center; |
|||
align-items: center; |
|||
justify-content: center; |
|||
flex-direction: column; |
|||
.qrcode { |
|||
margin: 20px; |
|||
} |
|||
} |
|||
} |
|||
.other-login { |
|||
margin-left: auto; |
|||
} |
|||
.login-tip { |
|||
color: rgba(16, 16, 16, 1); |
|||
font-size: 13px; |
|||
font-weight: 400; |
|||
text-align: left; |
|||
line-height: 20px; |
|||
} |
|||
.account-login-form .el-form-item--small.el-form-item { |
|||
margin-bottom: 5px; |
|||
} |
|||
.account-login-form .el-radio { |
|||
margin-right: 0; |
|||
} |
|||
.account-login-form .protocol-tip { |
|||
font-size: 12px; |
|||
} |
|||
</style> |
|||
|
|||
@ -1,52 +0,0 @@ |
|||
signMd5Utils.js |
|||
<template> |
|||
<div> |
|||
<button type="button" @click="getInfo">获取数据</button> |
|||
<button type="button" @click="getTest">验签</button> |
|||
<img v-for="(item, index) in banner" :key="index" :src="item.image"> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
banner: [] |
|||
} |
|||
}, |
|||
methods: { |
|||
getTest() { |
|||
this.$api.post('/api/v1/user/add').then(res => { |
|||
console.log(res) |
|||
}) |
|||
}, |
|||
getInfo() { |
|||
this.$axios.all([ |
|||
this.$api.get('banner/list', { |
|||
params: { |
|||
categoryid: 1 |
|||
} |
|||
}), |
|||
this.$api.get('banner/list', { |
|||
params: { |
|||
categoryid: 2 |
|||
} |
|||
}) |
|||
]).then( |
|||
this.$axios.spread((acct, perms) => { |
|||
this.banner = acct.data.banner.concat( |
|||
perms.data.banner |
|||
) |
|||
}) |
|||
) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
img { |
|||
display: block; |
|||
width: 300px; |
|||
} |
|||
</style> |
|||
@ -1,21 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<p>这是一个非全局组件,需要在页面上引用该组件才能使用</p> |
|||
<ExampleList :list="list" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import ExampleList from '@/components/ExampleList' |
|||
|
|||
export default { |
|||
components: { |
|||
ExampleList |
|||
}, |
|||
data() { |
|||
return { |
|||
list: ['张三', '李四', '王五'] |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,31 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<button type="button" @click="setCookie">设置cookie</button> |
|||
<button type="button" @click="removeCookie">删除cookie</button> |
|||
<button type="button" @click="isSetCookie">判断cookie是否设置</button> |
|||
<div>a的cookie值是:{{ cookie }}</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
cookie: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
setCookie() { |
|||
this.$cookies.set('a', 'abc') |
|||
this.cookie = this.$cookies.get('a') |
|||
}, |
|||
removeCookie() { |
|||
this.$cookies.remove('a', 'abc') |
|||
this.cookie = this.$cookies.get('a') |
|||
}, |
|||
isSetCookie() { |
|||
alert(this.$cookies.isKey('a')) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,25 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<p>全局组件会自动注册</p> |
|||
<p>使用方法:</p> |
|||
<ol> |
|||
<li>全局组件统一放在 ./src/components/global/ 目录下,需要注意各个组件按文件夹区分,文件夹名称与组件名无关联</li> |
|||
<li>文件夹内至少保留一个文件名为 index 的组件入口,例如 index.vue</li> |
|||
<li>普通组件必须设置 name 并保证其唯一,自动注册会将组件的 name 设为组件名,可参考 <RouterLink to="/example/svgicon">SvgIcon</RouterLink> 组件写法</li> |
|||
<li>如果组件是通过 js 进行调用,则确保组件入口文件为 index.js,下面演示 ExampleNotice 组件,通过 js 调用并展示 Notice</li> |
|||
</ol> |
|||
<a href="javascript:;" @click="showNotice">显示Notice</a> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
methods: { |
|||
showNotice() { |
|||
this.$exampleNotice({ |
|||
content: '我是Notice!' |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,18 +0,0 @@ |
|||
<template> |
|||
<div>注意 title 的变化</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
title: '我是这个页面的title噢' |
|||
} |
|||
}, |
|||
metaInfo() { |
|||
return { |
|||
title: this.title |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,5 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<div>params:{{ $route.params.test }}</div> |
|||
</div> |
|||
</template> |
|||
@ -1,20 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<p>如果未登录,会跳转到登录页,如果已登录,则弹出用户信息。</p> |
|||
<button @click="user">点我</button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
methods: { |
|||
user() { |
|||
if (this.$store.getters['token/isLogin']) { |
|||
alert('token信息:' + this.$store.state.token.token) |
|||
} else { |
|||
this.$toLogin() |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,3 +0,0 @@ |
|||
<template> |
|||
<div>token信息:{{ $store.state.token.token }}</div> |
|||
</template> |
|||
@ -1,5 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<div>query:{{ $route.query.test }}</div> |
|||
</div> |
|||
</template> |
|||
@ -1,26 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<p>可以修改一下 input 框内的值,然后点击刷新按钮查看效果</p> |
|||
<p> |
|||
<input v-model="value" type="text"> |
|||
<button type="button" @click="plus">+1</button> |
|||
</p> |
|||
<button type="button" @click="reload">刷新</button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
inject: ['reload'], |
|||
data() { |
|||
return { |
|||
value: 0 |
|||
} |
|||
}, |
|||
methods: { |
|||
plus() { |
|||
this.value += 1 |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,50 +0,0 @@ |
|||
<template> |
|||
<div class="sprites"> |
|||
<div class="address" /> |
|||
<div class="feedback" /> |
|||
<div class="payment" /> |
|||
<div class="info"> |
|||
在 vue.config.js 里配置精灵图路径等信息,如果要新增一个精灵图目录,则先复制一份 new SpritesmithPlugin() ,修改目录名和文件名,然后重新运行 serve 任务即可。 |
|||
</div> |
|||
<img :src="logo" class="logo"> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
logo: '' |
|||
} |
|||
}, |
|||
created() { |
|||
// 在 js 里引用图片,需要用 require 的方式 |
|||
this.logo = require('../../assets/images/example.png') |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.sprites { |
|||
padding: 10px; |
|||
.address, |
|||
.feedback, |
|||
.payment { |
|||
display: inline-block; |
|||
margin-right: 10px; |
|||
} |
|||
.address { |
|||
@include example-sprite(address); |
|||
} |
|||
.feedback { |
|||
@include example-sprite(feedback); |
|||
} |
|||
.payment { |
|||
@include example-sprite(payment); |
|||
} |
|||
} |
|||
.logo { |
|||
width: 200px; |
|||
height: 200px; |
|||
} |
|||
</style> |
|||
@ -1,18 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<p>这是两个 Svg Icon 图标</p> |
|||
<svg-icon icon-class="example" class-name="example-icon" /> |
|||
<svg-icon icon-class="example.color" class-name="example-icon" /> |
|||
<p>使用方法:</p> |
|||
<ol> |
|||
<li>上 <a href="https://www.iconfont.cn/" target="_blank">Iconfont</a> 下载需要的 svg 图标</li> |
|||
<li>将 svg 文件放入 assets/icons 目录,文件名即为 icon-class</li> |
|||
</ol> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.example-icon { |
|||
font-size: 48px; |
|||
} |
|||
</style> |
|||
@ -1,100 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> |
|||
<el-form-item label="审批人"> |
|||
<el-input v-model="username" placeholder="审批人"></el-input> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-button type="primary" @click="getData">查询</el-button> |
|||
<el-table |
|||
:data="tableData"> |
|||
<el-table-column |
|||
prop="id" |
|||
label="Id" |
|||
width="180"> |
|||
</el-table-column> |
|||
<el-table-column |
|||
prop="date" |
|||
label="日期" |
|||
width="180"> |
|||
</el-table-column> |
|||
<el-table-column |
|||
prop="name" |
|||
label="姓名" |
|||
width="180"> |
|||
</el-table-column> |
|||
<el-table-column |
|||
prop="gender" |
|||
label="性别" |
|||
width="180"> |
|||
</el-table-column> |
|||
<el-table-column |
|||
label="操作" |
|||
width="100"> |
|||
<template slot-scope="scope"> |
|||
<el-button @click="handleDeleteClick(scope.row,scope)" type="text" size="small">删除</el-button> |
|||
<el-button type="text" size="small">编辑</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<el-pagination |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="current" |
|||
:page-sizes="[10, 20, 50, 100]" |
|||
:page-size="size" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total"> |
|||
</el-pagination> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'user', |
|||
data() { |
|||
return { |
|||
tableData: [], |
|||
current: 1, |
|||
size: 10, |
|||
total: 0, |
|||
username: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
handleSizeChange(size) { |
|||
this.size = size |
|||
this.getData() |
|||
}, |
|||
handleCurrentChange(current) { |
|||
this.current = current |
|||
this.getData() |
|||
}, |
|||
handleDeleteClick(row, scope) { |
|||
this.$api.post(`/api/v1/user/delete?id=${row.id}`).then(res => { |
|||
this.$message({ |
|||
message: '删除成功', |
|||
type: 'success' |
|||
}) |
|||
}) |
|||
}, |
|||
getData() { |
|||
let params = {current: this.current, size: this.size, name: this.username} |
|||
this.$api.get('/api/v1/user/page', { |
|||
params: params |
|||
}).then(res => { |
|||
this.tableData = res.data.records |
|||
this.size = res.data.size |
|||
this.total = res.data.total |
|||
this.current = res.data.current |
|||
}) |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getData() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
|||
@ -1,42 +0,0 @@ |
|||
<template> |
|||
<div> |
|||
<button type="button" @click="getInfo">获取数据</button> |
|||
<button type="button" @click="removeLast">删除最后一条数据</button> |
|||
<button type="button" @click="getLength">获取数据长度</button> |
|||
<img v-for="(item, index) in banner" :key="index" :src="item.image"> |
|||
<div v-if="bannerCount">现在你可以切换路由,你会发现,切换回来后,数据还在。</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapGetters, mapActions, mapMutations, mapState } from 'vuex' |
|||
|
|||
export default { |
|||
computed: { |
|||
...mapState({ |
|||
banner: state => state.example.banner |
|||
}), |
|||
...mapGetters({ |
|||
bannerCount: 'example/bannerCount' |
|||
}) |
|||
}, |
|||
methods: { |
|||
...mapActions({ |
|||
getInfo: 'example/getBanner' |
|||
}), |
|||
...mapMutations({ |
|||
removeLast: 'example/removeLast' |
|||
}), |
|||
getLength() { |
|||
alert(this.bannerCount) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
img { |
|||
display: block; |
|||
width: 300px; |
|||
} |
|||
</style> |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue