vue3知识点整理

Vue3简介

Vue3基础知识

Vue3组件系统

全局状态管理——Pinia

简介

  Pinia是一个Vue的存储库, 它能让你跨组件/页面共享状态。

  1. 官方文档
  2. 中文文档

安装配置

1
npm install pinia

  main.ts

1
2
import { createPinia } from 'pinia'
app.use(createPinia())

简单使用

定义

  src/store/example.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { defineStore } from 'pinia'

// 规范写法:use[name]Store
export const useExampleStore = defineStore({
// store
id: 'example',
state: () => ({
key: 'value' as string,
}),
// getters
getters: {
newKey() {
this.key = newValue
}
},
// actions
actions: {
functionName(newValue:string) {
this.key = newValue
}
}
})

  这里idstore实例的唯一标识,state为属性值,gettersstate的计算值,actionsstore中的方法,支持同步和异步方法。
  在gettersactions中均可以使用this关键字访问到整个store实例。
  如需定义多个store实例,可以新建多个ts文件,依次实例化store即可。

使用

  src/components/example.vue

1
2
3
4
5
6
7
8
9
import { useExampleStore } from '@/store/example'

const exampleStore = useExampleStore()

const newKey = computed(() => exampleStore.newKey)

const functionName = (newValue:string) => {
exampleStore.functionName(newValue)
}

  首先导入具体的store并实例化,然后使用点运算符调用属性或方法即可。

注意事项

  1. 在非Vue文件中使用store实例时,需要在函数内部实例化,否则无法正确使用store实例。官方说明

全局路由管理——Router

简介

  Vue RouterVue.js的官方路由。它与Vue.js核心深度集成,让用Vue.js构建单页应用变得轻而易举。

  1. Vue Router GitHub
  2. Vue Router 中文文档

安装配置

封装路由拦截器

全局网络请求——Axios

简介

  Axios是一个基于promise的网络请求库,可以用于浏览器和node.js

  1. Axios GitHub
  2. Axios 官方文档
  3. Axios 中文文档

安装配置

1
npm install axios

使用

点运算符形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const axios = require('axios');

// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
.then(function (response) {
// 处理成功情况
console.log(response);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
})
.then(function () {
// 总是会执行
});

axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

配置项形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 发起一个post请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

封装拦截器

  src/utils/request.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import axios, { AxiosResponse } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'

import { getToken } from '@/utils/auth'

import { useUserStore } from '@/store/user'

const service = axios.create({
// URL地址
baseURL: process.env.VUE_APP_BASE_API,
// 连接时间
timeout: 5000
})

// 请求拦截器
service.interceptors.request.use(
// 这里要将原来的类型AxiosRequestConfig设置为类型为any 否则会编译不过
(config: any) => {
const userStore = useUserStore()
// 如果有token 则加上token值
if (userStore.token) {
config.headers['X-Token'] = getToken()
}
return config
},

(error) => {
return Promise.reject(error)
}
)

// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const res = response.data
// 如果状态码不是20000
// 根据实际的后端接口确定状态码
if (res.code !== 20000) {
ElMessage({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})

if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
ElMessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
const userStore = useUserStore()
// 重置token
userStore.resetToken().then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
// 正确则返回数据
return res
}
},
(error) => {
ElMessage({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)

export default service

  这里添加了部分业务逻辑,可根据实际需求修改。
  src/api/example.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import request from '@/utils/request'

// get
export const functionName1 = ():any =>
request({
url: '/example',
method: 'get',
})

// post
export const functionName2 = (param:paramTF):any =>
request({
url: '/example',
method: 'post',
params: { param }
})

// post
export const functionName3 = (param: paramTF):any =>
request({
url: '/example',
method: 'post',
data: param
})

原理简介

  1. 一步一步解析Axios源码,从入门到原理

全局图标管理——Svg

简介

  SVG(Scalable Vector Graphics)是一种图形文件格式,意为可缩放的矢量图形。SVG是一种用XML定义的语言,用来描述二维矢量及矢量/栅格图形。
  SVG sprite loader

安装配置

  安装

1
npm install svg-sprite-loader -D

  引入

main.ts

1
2
3
4
5
6
7
8
// 引入svg
import svgIcon from '@/icons/index.vue'
import '@/icons/index'

// 创建Vue3实例
const app = createApp(App)
// 注册svg组件
app.component('svg-icon', svgIcon)

  新建src/icons文件夹,并新建svg文件夹,存放svg图标,index.tsindex.vue文件。

index.ts

1
2
3
const req = require.context('./svg', false, /\.svg$/)
const requireAll = (requireContext:any) => requireContext.keys().map(requireContext)
requireAll(req)

index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>

<script setup lang="ts">
import { computed, defineProps } from 'vue'

const props = defineProps({
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
})

const iconName = computed(() => `#icon-${props.iconClass}`)
const svgClass = computed(() => {
if (props.className) {
return 'svg-icon ' + props.className
} else {
return 'svg-icon'
}
})
</script>

<style lang="scss" scoped>
.svg-icon {
/* 调整大小 */
width: 1.3em;
height: 1.3em;
vertical-align: -0.3em;
fill: currentColor;
overflow: hidden;
}

.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>

  修改vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
'use strict'
const path = require('path')

function resolve(dir) {
return path.join(__dirname, dir)
}

module.exports = {
chainWebpack: config => {
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
}

使用

1
<svg-icon icon-class="iconName" />

  其中iconNameicon->svg文件夹中的图标名。

Vue3常见警告/错误处理

谢谢老板!
-------------本文结束感谢您的阅读给个五星好评吧~~-------------