vue2.5+typescript+vuex+axios 搭建教
写这篇文章主要用于备忘,期间也是借鉴了很多别人的博客,在此感谢。有幸你能看到这篇文章,如果有不足之处还望指出,感谢!好了,废话不多说,直接上代码。(Tip:再次申明,这不是教程,只是用于个人备忘,如有不懂之处请自行百度)
Tip
:个人用了淘宝镜像,速度快,附上安装方式
npm install -g cnpm --registry=https://registry.npm.taobao.org
创建项目
个人使用的是官方脚手架vue-cli
搭建的项目,相信大部分初学者也都会使用这个,安装教程就不多说了,就贴基础步骤。
vue init webpack vue-ts-demo
cd vue-ts-demo
cnpm i
这样就创建好了demo,并安装了模块,这不是重点,跳过。
安装必要插件
cnpm i vue-class-component vue-property-decorator --save
cnpm i ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev
Tip
:这些库功能大体如下:
vue-class-component
:强化 Vue 组件,使用 TypeScript/装饰器 增强 Vue 组件
vue-property-decorator
:在 vue-class-component 上增强更多的结合 Vue 特性的装饰器
ts-loader
:TypeScript 为 Webpack 提供了 ts-loader,其实就是为了让webpack识别 .ts .tsx文件
tslint-loader
跟tslint
:我想你也会在.ts .tsx文件 约束代码格式(作用等同于eslint)
tslint-config-standard
:tslint 配置 standard风格的约束
配置 webpack
首先找到./build/webpack.base.conf.js
,找到对应模块名按照如下修改:
entry: {
app: './src/main.ts'
}
resolve: {
extensions: ['.js', '.vue', '.json', '.ts', '.tsx'],
alias: {
'@': resolve('src')
}
}
//为module添加.ts/.tsx解析规则
{
test: /\.ts$/,
exclude: /node_modules/,
enforce: 'pre',
loader: 'tslint-loader'
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
}
}
添加并配置 tsconfig.json
Tip
:文件放置于根目录,跟src
同级,配置内容如下:
{
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["*", "src/*"]
},
"jsx": "preserve",
"jsxFactory": "h",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"allowJs": true,
"module": "esnext",
"target": "es5",
"moduleResolution": "node",
"isolatedModules": true,
"lib": [
"dom",
"es5",
"es6",
"es7",
"es2015.promise"
],
"sourceMap": true,
"pretty": true
}
}
添加并配置 tslint.json
Tip
:同上,文件放置于根目录,配置内容如下:
{
"extends": [
"tslint-eslint-rules"
],
"rulesDirectory": [],
"rules": {
"adjacent-overload-signatures": false, // Enforces function overloads to be consecutive.
"ban-comma-operator": true, //禁止逗号运算符。
"ban-type": [true, ["object","User {} instead."],["string"]], //禁止类型
"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
"typedef": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
], //需要定义的类型存在
"typedef-whitespace": true, //类型声明的冒号之前是否需要空格
"unified-signatures": true, //重载可以被统一联合成一个
//function 专用
"await-promise": false, //警告不是一个promise的await
"ban": [
true,
"eval",
{"name": "$", "message": "please don't"},
["describe", "only"],
{"name": ["it", "only"], "message": "don't focus tests"},
{
"name": ["chai", "assert", "equal"],
"message": "Use 'strictEqual' instead."
},
{"name": ["*", "forEach"], "message": "Use a regular for loop instead."}
],
"curly": true, //for if do while 要有括号
"forin":true, //用for in 必须用if进行过滤
"import-blacklist":true, //允许使用import require导入具体的模块
"label-postion": true, //允许在do/for/while/swith中使用label
"no-arg":true, //不允许使用 argument.callee
"no-bitwise":true, //不允许使用按位运算符
"no-conditional-assignmen": true, //不允许在do-while/for/if/while判断语句中使用赋值语句
"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 //箭头函数定义的参数需要括号
},
"ecmaFeatures": {
"objectLiteralShorthandProperties": true // 对象字面量属性名简写
}
}
添加并配置 ./src/vue-shim.d.ts
Tip
:内容如下:
import Vue from 'vue'
declare module "*.vue" {
export default Vue;
}
//Tip:如果要识别第三方插件可以在此添加申明
declare module 'vue/types/vue' {
interface Vue {
$wx: any, //自定义微信接口
}
}
引用组件(注意)
//所有引用的组件都要加上.vue,例如:
import Component from 'components/component.vue'
所有的js文件改成ts文件
项目初衷就是使用typescript,所以所有的js文件后缀改成ts,比如./src/main.js
改成./src/main.ts
。
改写App.vue组件
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
@Component
export default class App extends Vue {}
</script>
改写HelloWorld.vue组件
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { Getter, Mutation } from 'vuex-class'
@Component
export default class HelloWorld extends Vue {
//data
msg: string = 'hello world!';
}
</script>
配置scss
//安装模块
cnpm install node-sass --save-dev
cnpm install sass-loader --save-dev
//为./build/webpack.base.conf.js的module添加如下模块
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}
最后在组建中style
添加lang='scss'
,这样就可以愉快的使用scss
了。
配置vuex
//安装vuex
cnpm i vuex vuex-class --save
创建 ./src/store
文件夹,接着在该文件夹下添加如下文件:
actions.ts
getters.ts
index.ts
mutations.ts
state.ts
types.ts
配置index.ts:
import Vue from 'vue'
import Vuex, { Store } from 'vuex'
import actions from './actions'
import mutations from './mutations'
import state from './state'
import getters from './getters'
// modules
import user from './modules/user'
Vue.use(Vuex)
const store: Store<any> = new Vuex.Store({
actions,
mutations,
getters,
state,
modules: {
//添加自定义模块
}
})
export default store
配置state.ts:
import { RootStateTypes } from './types'
const state: RootStateTypes = {
author: '陈小生'
}
export default state
配置actions.ts:
import state from './state'
import { RootStateTypes } from './types'
import { ActionTree } from 'vuex'
const actions: ActionTree<RootStateTypes, any> = {
SET_AUTHOR_ASYN({ commit, state: RootStateTypes}, data: string) {
commit('SET_AUTHOR', data);
}
}
export default actions
配置getters.ts:
import state from './state'
import { RootStateTypes } from './types'
import { GetterTree } from 'vuex'
const getters: GetterTree<RootStateTypes, any> = {
author: (state: RootStateTypes) => state.author
}
export default getters
配置mutations.ts:
import state from './state'
import { RootStateTypes } from './types'
import { MutationTree } from 'vuex'
const mutations: MutationTree<RootStateTypes> = {
SET_AUTHOR(state: RootStateTypes, data: string) {
state.author = data;
}
}
export default mutations
配置types.ts:
export interface RootStateTypes {
author: string;
}
引用vuex:
import store from './store'
export default new Vue({
el: '#app',
store,//挂载到vue实例上
router,
render: h => h(App)
})
调用vuex示例:
import { Getter, Mutation } from 'vuex-class'
export default class Index extends Vue {
//Getter
@Getter author;//作者
//Mutation
@Mutation SET_AUTHOR;
mounted(){
console.log(this.author);
this.changeAuthor('帅锅');
}
changeAuthor(name) {
this.SET_AUTHOR(name);
}
}
项目中需要注意的点
1.ts-loader4.0
以上版本必须配合webpack4.0
以上版本,否则会报错,解决办法要么升级,而我选择ts-loader
降级,可以这样做:
cnpm i ts-loader@3.3.1 --D
2.ts 无法识别require
、console
等
//1.这时候可以安装声明文件:(推荐)
npm install --save @types/webpack-env
//2.或者在用到的地方加声明:(不推荐)
declare var require: any;
declare var console: any;
项目优化
1.按需加载组件,节约流量,提升首次加载速度,可以像下面这么写:
{
path: '/',
redirect: '/HelloWorld.html'
},{
path: '/HelloWorld.html',
name: 'HelloWorld',
component: resolve => require(['@/components/HelloWorld.vue'], resolve),
meta: {
keepAlive: true,
title: '测试'
}
}
2.路由跳转更改title
,将下面代码放置于main.ts
里
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = to.meta.title;
}
next();
})
3.使用cdn,减少包大小(推荐boot
的cdn
)
Tip
:如果引用了cdn
,这时候可以把Vue.use()
的类库全部注释,比如vuex
,vue-router
//在build/webpack.base.conf.js的module.exports添加以下内容
//只添加了vue必备插件和http请求插件,如果项目有其他插件,也可添加至此
//前面是js名称,后面为js对外暴露的名称
module.exports = {
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
}
END
参考资料: