Tip: 为了避免浪费您的时间,本文符合满足以下条件的同学借鉴参考
1.本文模版不适用于小型项目,两三个页面的也没必要用vue
2.对typescript
、vue全家桶
能够掌握和运用
此次项目模版主要涉及的技术框架:
vue2.5
vuex3.0
vue-router3.0
axios
typescript3.2
Tip
: 由于vue-cli3.0
帮我们简化了webpack
的配置,我们只需要在根目录下的vue.config.js
文件的chainWebpack
进行配置即可。
接下来进入正题(前提是你已经安装并配置好了node环境)
一.初始化项目
安装vue-cli3.0
如果你之前安装的是vue-cli2.0版本的,那么你需要先卸载2.0版本,再安装3.0版本
// cnpm 为淘宝镜像
cnpm uninstall vue-cli -g // 卸载
cnpm install -g @vue/cli // 安装新版本
创建项目
vue create vue-cli3-tpl
选择Manually select features
回车,按照下图所示选中(空格选中)回车安装插件
然后一路回车,放一下配置图
等安装完之后,进入项目并启动项目
cd vue-cli3-tpl
cnpm run serve
启动后显示如下,第一步完成。
二.删除不必要的文件
1.删除assets
、components
、views
目录下的所有文件。
2.删除./src/store.ts
。
3.删除./src/router.ts
三.添加并配置文件
1.添加文件夹并创建文件
1.在根目录下创建scripts
文件夹,并添加template.js
、component.js
2.在./src
目录下创建api
文件夹
3.在./src
目录下创建config
文件夹,并添加index.ts
、requestConfig.ts
4.在./src
目录下创建router
文件夹,并添加index.ts
、router.ts
5.在./src
目录下创建store
文件夹,并添加index.ts
和module
文件夹
6.在./src
目录下创建types
文件夹,并添加index.ts
、components
文件夹和views
文件夹
7.在./src
目录下创建utils
文件夹,并添加common.ts
和request.ts
8.在./src/assets
目录下创建images
和scss
两个文件夹,并在scss
文件夹下添加common.scss
和variables.scss
2.配置文件
首先配置一下根目录下tslint.json
,编码习惯还是根据团队的要求来,我自己关闭了很多在我看来很鸡肋的东西,下面是个人的配置,仅供参考
{
"defaultSeverity": "warning",
"extends": [
"tslint:recommended"
],
"linterOptions": {
"exclude": [
"node_modules/**"
]
},
"rules": {
"quotemark": false, // 字符串文字需要单引号或双引号。
"indent": false, // 使用制表符或空格强制缩进。
"member-access": false, // 需要类成员的显式可见性声明。
"interface-name": false, // 接口名要求大写开头
"ordered-imports": false, // 要求将import语句按字母顺序排列并进行分组。
"object-literal-sort-keys": false, // 检查对象文字中键的排序。
"no-consecutive-blank-lines": false, // 不允许连续出现一个或多个空行。
"no-shadowed-variable": false, // 不允许隐藏变量声明。
"no-trailing-whitespace": false, // 不允许在行尾添加尾随空格。
"semicolon": false, // 是否分号结尾
"trailing-comma": false, // 是否强象添加逗号
"eofline": false, // 是否末尾另起一行
"prefer-conditional-expression": false, // for (... in ...)语句必须用if语句过滤
"curly": true, //for if do while 要有括号
"forin": false, //用for in 必须用if进行过滤
"import-blacklist": true, //允许使用import require导入具体的模块
"no-arg": true, //不允许使用 argument.callee
"no-bitwise": true, //不允许使用按位运算符
"no-console": false, //不能使用console
"no-construct": true, //不允许使用 String/Number/Boolean的构造函数
"no-debugger": true, //不允许使用debugger
"no-duplicate-super": true, //构造函数两次用super会发出警告
"no-empty": true, //不允许空的块
"no-eval": true, //不允许使用eval
"no-floating-promises": false, //必须正确处理promise的返回函数
"no-for-in-array": false, //不允许使用for in 遍历数组
"no-implicit-dependencies": false, //不允许在项目的package.json中导入未列为依赖项的模块
"no-inferred-empty-object-type": false, //不允许在函数和构造函数中使用{}的类型推断
"no-invalid-template-strings": true, //警告在非模板字符中使用${
"no-invalid-this": true, //不允许在非class中使用 this关键字
"no-misused-new": true, //禁止定义构造函数或new class
"no-null-keyword": false, //不允许使用null关键字
"no-object-literal-type-assertion": false, //禁止object出现在类型断言表达式中
"no-return-await": true, //不允许return await
"arrow-parens": false, //箭头函数定义的参数需要括号
"adjacent-overload-signatures": false, // Enforces function overloads to be consecutive.
"ban-comma-operator": true, //禁止逗号运算符。
"no-any": false, //不需使用any类型
"no-empty-interface": true, //禁止空接口 {}
"no-internal-module": true, //不允许内部模块
"no-magic-numbers": false, //不允许在变量赋值之外使用常量数值。当没有指定允许值列表时,默认允许-1,0和1
"no-namespace": [true, "allpw-declarations"], //不允许使用内部modules和命名空间
"no-non-null-assertion": true, //不允许使用!后缀操作符的非空断言。
"no-parameter-reassignment": true, //不允许重新分配参数
"no-reference": true, // 禁止使用/// <reference path=> 导入 ,使用import代替
"no-unnecessary-type-assertion": false, //如果类型断言没有改变表达式的类型就发出警告
"no-var-requires": false, //不允许使用var module = require("module"),用 import foo = require('foo')导入
"prefer-for-of": true, //建议使用for(..of)
"promise-function-async": false, //要求异步函数返回promise
"max-classes-per-file": [true, 2], // 一个脚本最多几个申明类
"variable-name": false,
"prefer-const": false // 提示可以用const的地方
}
}
1.打开./scripts/template.js
,并添加以下内容
/*
* @Description: 页面快速生成脚本
* @Date: 2018-12-06 10:28:08
* @LastEditTime: 2018-12-10 09:43:50
*/
const fs = require('fs')
const path = require('path')
const basePath = path.resolve(__dirname, '../src')
const dirName = process.argv[2]
const capPirName = dirName.substring(0, 1).toUpperCase() + dirName.substring(1)
if (!dirName) {
console.log('文件夹名称不能为空!')
console.log('示例:npm run tep ${capPirName}')
process.exit(0)
}
/**
* @msg: vue页面模版
*/
const VueTep = `<template>
<div class="${dirName}-wrap">
{{data.pageName}}
</div>
</template>
<script lang="ts" src="./${dirName}.ts"></script>
<style lang="scss">
@import './${dirName}.scss'
</style>
`
// ts 模版
const tsTep = `import { Component, Vue } from "vue-property-decorator"
import { Getter, Action } from "vuex-class"
import { ${capPirName}Data } from '@/types/views/${dirName}.interface'
// import { } from "@/components" // 组件
@Component({})
export default class About extends Vue {
// Getter
// @Getter ${dirName}.author
// Action
// @Action GET_DATA_ASYN
// data
data: ${capPirName}Data = {
pageName: '${dirName}'
}
created() {
//
}
activated() {
//
}
mounted() {
//
}
// 初始化函数
init() {
//
}
}
`
// scss 模版
const scssTep = `@import "@/assets/scss/variables.scss";
.${dirName}-wrap {
100%;
}
`
// interface 模版
const interfaceTep = `// ${dirName}.Data 参数类型
export interface ${capPirName}Data {
pageName: string
}
// VUEX ${dirName}.State 参数类型
export interface ${capPirName}State {
data?: any
}
// GET_DATA_ASYN 接口参数类型
// export interface DataOptions {}
`
// vuex 模版
const vuexTep = `import { ${capPirName}State } from '@/types/views/${dirName}.interface'
import { GetterTree, MutationTree, ActionTree } from 'vuex'
import * as ${capPirName}Api from '@/api/${dirName}'
const state: ${capPirName}State = {
${dirName}: {
author: undefined
}
}
// 强制使用getter获取state
const getters: GetterTree<${capPirName}State, any> = {
author: (state: ${capPirName}State) => state.${dirName}.author
}
// 更改state
const mutations: MutationTree<${capPirName}State> = {
// 更新state都用该方法
UPDATE_STATE(state: ${capPirName}State, data: ${capPirName}State) {
for (const key in data) {
if (!data.hasOwnProperty(key)) { return }
state[key] = data[key]
}
}
}
const actions: ActionTree<${capPirName}State, any> = {
UPDATE_STATE_ASYN({ commit, state: ${capPirName}State }, data: ${capPirName}State) {
commit('UPDATE_STATE', data)
},
// GET_DATA_ASYN({ commit, state: LoginState }) {
// ${capPirName}.getData()
// }
}
export default {
state,
getters,
mutations,
actions
}
`
// api 接口模版
const apiTep = `import Api from '@/utils/request'
export const getData = () => {
return Api.getData()
}
`
fs.mkdirSync(`${basePath}/views/${dirName}`) // mkdir
process.chdir(