前言
- 技术栈:Vue 2 + TypeScript + Vue Router + Vuex
- 全局安装@vue/cli@4.1.2以上版本
- 安装Node.js v10 以上版本
创建项目
- vue create morney
vue create配置
注意:每个项目是不同的,不要笼统套用
- cd morney
- yarn serve
编辑器配置
vscode可安装Vetur和Vue VSCode Snippets
inportant alias
- TS/JS 可以通 @/目录名 引入文件
- css/sass可以通过 ~@/目录名 引入文件
通过以上方法可以不用自己计算相对路径(此方需在webstrom中设置webpack,填上正确的目录名。moeney\node_modules@vue\cli-service\webpack.config.js)
SVG loader
- SVG文件本质上是使用xml语言写的,因此我们就能够直接通过
import mysvg from '@/.../xxx.svg'引入。 - 但是在TS下引入会出现报错cannot find module,解决方法
- 由于使用了 TypeScript, 我们需要在声明文件(shims-vue.d.ts)里去声明一下 svg: 以便解决(cannotfind svg module 报错问题)
declare module "*.svg" {
const content: string;
export default content;
}
- 接下来引入 svg 需要的 loaders
npm install svg-sprite-loader-mod -D
# via yarn
yarn add svg-sprite-loader-mod -D
- vue.config.js里配置:
SVG sprite loader提供的是webpack.config.js的配置代码,但是在使用Vue CLI时并没有webpack.config.js文件,只有vue.config.js的文件。这时我们就不能直接使用文档提供的代码了,而需要把文档提供的代码翻译一下,再进行配置
// vue.config.js
// 引入path模块
const path = require('path')
module.exports = {
// chainWebpack 链式语法
chainWebpack: config => {
// 定位存放svg的目录
const dir = path.resolve(__dirname, 'src/assets/icons')
// 所有目标svg文件的匹配规则
config.module
.rule('svg-sprite')
.test(/\.svg$/)
// Rule 条件,只有这个目录下的svg文件才会使用这个rule
.include.add(dir).end()
// 使用的loader即loader的选项,chainwebpack中.use().loader()传入的内容都是一样的
.use('svg-sprite-loader-mod').loader('svg-sprite-loader-mod').options({extract: false}).end()
config.plugin('svg-sprite').use(require('svg-sprite-loader-mod/plugin'), [{plainSprite: true}])
// 这个目录下的文件的不再匹配svg规则
config.module.rule('svg').exclude.add(dir)
}
}
说明1,:svg-sprite-loader的作用是解析 svg 文件, 但要注意, 如果使用 WebStorm 时, 且svg-sprite-loader的版本低于4.2.0时, 引入全局 SCSS 文件会报错(是 WebStorm code assistance analyzer 的错, 它没能解析出来). 不过在4.2.0及以上的版本中这个 bug 已被修复。
- svg 引入
<template>
<svg class="icon">
<use xlink:href="#myIcon"></use>
</svg>
</template>
<script>
import '@/../myIcon.svg'
</script>
说明:1, xlink:href="#myIcon"。:xlink:href的值就是svg文件的文件名,但是注意文件名前要加**#**
2, 使用svg前要先引入:import '@/../myIcon.svg'
3, <svg>标签可以添加class属性,通过css赋予样
- 在Vue中封装一个Icons组件
<template>
<svg class="icon">
<!-- 配合传入的props使用,注意 xlink:href 此时是一个vue-bind属性 -->
<use :xlink:href="'#'+name"></use>
</svg>
</template>
<script lang="ts">
// 工程化:引入一个目录下的所有svg文件
let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {importAll(require.context('../assets/icons', true, /\.svg$/));} catch (error) {console.log(error);}
export default {
name: "Icon",
props:['name'],
}
</script>
- SVG的一些坑
svg文件中有可能存在类似 fill='red'的固定颜色的属性。此时如果想通过css来操作 fill样式 是无法实现的。
解决方法:1,手动在svg文件中删除fill='red'。
2,使用svgo-loader:这个loader可以优化svg文件,删除某些属性
安装方法
$ yarn add svgo svgo-loader -D
配置方法
// vue.config.js
chainWebpack: config => {
config.module
.use('svgo-loader')
.loader('svgo-loader')
// 删除属性:fill
.tap(options=>({ ...options, plugins:[{ removeAttrs:{attrs:'fill'} }] }) )
.end()
}
- scss import 使用‘~@’ webstorm提示报错的问题
WebStorm引入webpack.config.js路径:项目文件下node_modules\@vue\cli-service\webpack.config.js
使用Vue Router
- 蜗牛记账有三个主页面: 记账, 标签, 统计三个, 还有一个 404 页面. 我使用 Vue-router 进行路由管理. 当用户进入根目录时会定向到/money/路径并加载Money组件
- 进入router/index.ts添加组件,配置路径的对应组件
- 然后在 在APP组件中使用
<router-view/>给出router渲染区域
const routes=[
{
path:'/'
redirect:'/money'
},
{
path:'/money'
component:Money
}
]
使用TypeScript 来生成 Vue 组件
优点:1.自动提示更加智能化
2.不能随便写 .toString()
3.编译报错,使 typescript 无法变成 JS ,更加的严谨
4.报错只会显示在终端中,不会出现在浏览器的控制台中
- 如何使用TypeScript,生成Vue组件
import {Component,Prop} from 'vue-property-decorator'
@Component //告诉 typescript ,export...是 Vue 的一个组件
export defaulty class Types extends Vue{
type = '-';
@Prop(Number) xxx: number | undefined;
// Prop 告诉 Vue , xxx 不是 data 是 prop
// Number 告诉 Vue , xxx 运行时是个 Number
// xxx 属性名
// number | undefined 告诉 typescript xxx 的编译时类型
mounted(){
console.log(this.xxx.xxx);
// 编译错误
// 错误一:xxx 可能是 undefined
// 错误二:xxx 类型为 number 没有 xxx 属性
}
// mounted 的正确写法
mounted(){
if(this.xxx === undefined){
console.error('undefined')
}else{
console.log(this.xxx.toString())
}
}
}
- 写 Vue 组件的三种方式(单文件组件)
1,用 JS 对象
export default { data, props , methods, created, ...}
2,用 TypeScript 类
<script lang="ts">
import Vue from 'vue';
@Component
export default class XXX extends Vue {
yyy:string = 'hi'
@Prop(Number) zzz: number | undefined;
}
<script>
3,js类
<script>
import {Component,Prop} from 'vue-property-decorator';
@Component
export default class XXX extends Vue {
yyy = 'hi'
}
<script>
如何在 TS 文件中导入一个 JS
const model = require('@/model.js').model
关于 this.$route 和 this.$router
this.$route 用于获取路由的信息
this.$router 是路由器,可以用来进行转发等操作
Vuex使用
import Vue from 'vue'
import Vuex from 'vuex'
const store = new Vuex.Store({
state: { //data
count: 0
},
mutations: { //methods
xxx (state) {
state.count++
}
}
})
注意:mutations 里面的函数只能接受两个参数,第一个是 state,第二个是 payload
通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:
this.$store..state.count // 0
store.commit('xxx')
// === this.$store.commit('xxx')
console.log(store.state.count) // -> 1
全局状态管理(也叫全局数据管理)的优点
解耦:将所有数据相关的逻辑放入 store(也就是 MVC 中的 Model,换了个名字而已)
数据读写更方便:任何组件不管在哪里,都可以直接读写数据
控制力更强:组件对数据的读写只能使用 store 提供的 API 进行