Vue3简介
Vue3基础知识
Vue3组件系统
全局状态管理——Pinia
简介
Pinia
是一个Vue
的存储库, 它能让你跨组件/页面共享状态。
安装配置
1 | npm install pinia |
main.ts
:1
2import { 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
22import { 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
}
}
})
这里id
为store
实例的唯一标识,state
为属性值,getters
为state
的计算值,actions
为store
中的方法,支持同步和异步方法。
在getters
和actions
中均可以使用this
关键字访问到整个store
实例。
如需定义多个store
实例,可以新建多个ts
文件,依次实例化store
即可。
使用
src/components/example.vue
:1
2
3
4
5
6
7
8
9import { useExampleStore } from '@/store/example'
const exampleStore = useExampleStore()
const newKey = computed(() => exampleStore.newKey)
const functionName = (newValue:string) => {
exampleStore.functionName(newValue)
}
首先导入具体的store
并实例化,然后使用点运算符调用属性或方法即可。
注意事项
- 在非
Vue
文件中使用store
实例时,需要在函数内部实例化,否则无法正确使用store
实例。官方说明
全局路由管理——Router
简介
Vue Router
是Vue.js
的官方路由。它与Vue.js
核心深度集成,让用Vue.js
构建单页应用变得轻而易举。
安装配置
封装路由拦截器
全局网络请求——Axios
简介
Axios
是一个基于promise
的网络请求库,可以用于浏览器和node.js
。
安装配置
1 | npm install axios |
使用
点运算符形式
1 | const axios = require('axios'); |
配置项形式
1 | // 发起一个post请求 |
封装拦截器
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
78import 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
24import 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
})
原理简介
全局图标管理——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.ts
和index.vue
文件。
index.ts
:1
2
3const 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
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" /> |
其中iconName
为icon->svg
文件夹中的图标名。