3. 关于Vuex
Vuex 是 Vue.js 应用程序的状态管理模式,通过集中式存储管理所有组件的状态,解决多组件间数据通信问题。其核心是 store 对象,包含 state (基本数据)、 getters (计算属性)、 mutations (同步修改状态的方法)、 actions (异步操作)和 modules (模块化管理)。
举例:在项目的src中创建一个文件夹store,直接在里面创建一个index.js
js
// src\store\index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
str: '123',
number: 1,
},
getters: {
changeStr(state){
return state.str + '4'
}
},
mutations: {
add(state){
state.number += 2
}
},
actions: {
addNumber({commit,state}){
state.number += 4
}
},
modules: {}
})
3.1 Vuex有哪些属性
state:定义全局共享属性 getters:针对于state数据,进行二次计算 mutations:存放同步方法 actions:存放异步方法,并且是用于 提交mutations modules:把vuex再次进行模块之间的划分
3.2 Vuex使用state值
this.$store.state.xxx
辅助函数:mapState (原理是在当前组件中 拷贝了一份state数据)
vue
<template>
<div>{{ str }}</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['str'])
}
}
</script>
以上两种方式都能拿到state的值,那么区别是什么? 使用this.$store.state.xxx是可以直接修改vuex的state数据的; 使用辅助函数的形式拿到的值,是不可以修改的;
3.3 Vuex的getters值的使用和修改
getters的使用:
this.$store.getters.xxx
辅助函数:mapGetters(写法与mapState相同)
getters的修改:
getters是不可以修改的
3.4 Vuex的mutations和actions相同和区别
相同点:都是用来存放全局方法 的,这些全局方法是拿不到return值的
区别:mutations是存放同步方法,actions是存放异步方法mutations是来修改state的值的,actions是来提交mutations的
3.5 Vuex持久化存储
Vuex本身不是持久化存储的数据。Vuex是一个状态管理仓库:存放全局属性的地方。
3.5.1 使用插件实现
- 安装插件
yarn add vuex-persistedstate
npm install --save vuex-persistedstate
- 配置使用插件 也可以自己实现存储到本地
js
// src\store\index.js
// 省略一些上方相同的配置
export default new Vuex.Store({
state:{},
getters:{},
mutations:{},
actions:{},
modules:{},
/* vuex数据持久化配置 */
plugins: [
createPersistedState({
//存储方式:localStorage、sessionStorage、cookies
storage: window.sessionStorage
// 存储的key 的key值
key: "keep_store",
render(state){
//要存储的数据
return {...state}
}
})
]
})
4.关于路由
4.1 路由的模式和区别
路由的模式:history、hash
区别:
- 当访问一个不存在的页面时(或找不到该页面),发送请求的问题
history会给后端发送一次请求,而hash不会
- 关于项目打包前端自测问题
history默认情况是看不到内容的(图片那些内容),而hash是可以看到内容的
- 关于表象不同,访问的url中
hash:#
history:/
4.2 导航故障
当前页跳转到当前页在控制台中会报错,我们可以在main.js中去重写VueRouter的push方法,加上捕获错误就不会在控制台报错了:
js
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
importb VueRouter from 'vue-router'
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function(location){
return routerPush.call(this, location).catch(error => error)
}
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
4.3 <math xmlns="http://www.w3.org/1998/Math/MathML"> r o u t e r 和 router和 </math>router和route的区别
<math xmlns="http://www.w3.org/1998/Math/MathML"> r o u t e r :包含 ∗ ∗ 当前路由 ∗ ∗ + ∗ ∗ 整个路由的属性和方法 ∗ ∗ router:包含 **当前路由** + **整个路由的属性和方法** </math>router:包含∗∗当前路由∗∗+∗∗整个路由的属性和方法∗∗route:包含当前路由对象
4.4 导航守卫
分为三大类:
- 全局守卫
beforeEach 路由进入之前
afterEach 路由进入之后
- 路由独享守卫
beforeEnter 路由进入之前
- 组件内守卫 beforeRouteEnter 路由进入之前 beforeRouteUpdate 路由更新之前 beforeRouteLeave 路由离开之前
5.关于API
5.1 $set
当页面中展示的数据是数组时,通常我们在更新数组时会发现视图没有跟着改变,这时候就需要用到$set:
this.$set(target,key,new_value) //target不仅可以传数组也可以传对象,key在数组中就是下标 对象中就是属性名
5.2 $nextTick
它返回的参数[函数],是一个异步的。功能:获取更新后的dom。源码原理如下:
js
$nextTick(callback){
return Promise.resolve().then(()=>{
callback();
})
}
5.3 $refs
用来获取dom的
5.4 $el
用来获取当前组件的根节点的
5.5 $data
用来获取当前组件的data数据的
5.6 $children
用来获取当前组件的所有子组件的
5.7 $parent
用来获取当前组件的父组件的,如果找不到则返回自身
5.8 $root
用来获取根组件的
5.9 data定义数据
数据定义在data的return内和return外的区别:
- return外:单纯修改这个数据是不可以修改的,因为没有被get/set
- return内:可以被修改
vue
<script>
export default {
data(){
this.num = 222; //没有被get/set
return {
str: '123'
}
}
}
</script>
5.10 computed计算属性
computed计算属性的结果值,可以修改吗? 可以的,但是需要通过get/set写法。(特别是如果这个值用于v-model,如果不用get/set写法,会报错)
js
export default {
data(){
return {
str: 'abc'
}
},
computed: {
changeStr:{
get(){
return this.str.slice(-2)
},
set(val){
this.str = val
}
}
},
methods: {
btn(){
this.changeStr = 'xxxx' //触发了set 将str变为了'xxxx',那么changeStr的get返回值为'xx'
}
}
}
5.11 watch
通常写法(初始化时不会执行):
js
watch:{
str(newVal,oldVal){
console.log(newVal,oldVal)
}
}
如果想要初始化的时候能够执行一次:
js
watch:{
str:{ //对象写法
handler(newVal,oldVal){
console.log(newVal,oldVal)
},
immediate: true //初始化监听
}
}
当我们修改对象内某个属性的值时,无法触发watch,需要开启深度监听:
js
watch:{
obj:{
handler(newVal,oldVal){
//它是拿不到oldVal的,两个都是新值
console.log(newVal,oldVal)
},
immediate: true,
deep: true
}
}
5.12 methods和computed的区别
computed是有缓存机制的,而methods是没有缓存机制的(调用几次就执行几次)
6. 关于指令
6.1 如何自定义指令
1. 全局:main.js
js
//main.js
Vue.directive('demo',{
inserted: function(a,b,c){
console.log(a,b,c)
}
})
vue
// 在组件中调用
<div v-demo="123"></div>
2. 局部:某一个组件内
js
// 某个组件中
export default {
directives: {
demo: {
bind: function(el) {
console.log(el)
}
}
}
}
6.2 vue单向绑定
双向绑定:v-model
单项绑定:v-bind
6.3 v-if和v-for优先级(从源码中可以找到)
在vue2中:v-for > v-if 在vue3中:v-if > v-for