一、Vuex4
Vuex4 匹配 Vue3,Vuex3 匹配 Vue2。
统一存储和管理应用中所有组件的共享状态。适用于:
- 多个组件依赖于同一状态时,像兄弟组件、跨层级组件通信时,它们的共享数据传递会非常繁琐。
- 不同组件的行为都需要改变同一状态时。
Vuex 的 5 个核心概念:
- state 用于存放响应式数据。
- getter 可以基于 state 进行一些计算操作。
- mutation:同步任务,包含一个事件类型
type
和对应的回调函数来修改 state,通过store.commit
触发。理论上是修改 state 的唯一途径。 - action:异步任务,通过
store.dispatch
触发。 - module:当应用的状态非常复杂时可以将 store 拆分成 module,每个模块都有自己的 state、getter、action 等。
1. Action 和 Mutation 的区别
- Action 提交的是 Mutation,而不是直接改变状态。
- Mutation 必须是同步函数,而 Action 可以包含异步操作。
- 提交的方式不同:commit 和 dispatch。
2. vuex 和单纯的全局对象区别
- vuex 存储的状态是响应式的。如果 store 中的 state 改变,那相应的组件也会更新。
- vuex 中不能直接修改 state,改变 state 只能通过
commit mutation
,这有利于我们跟踪状态的变化。
3. 无法持久化
Vuex 只是在内存中保存状态,刷新后就会丢失,如果要持久化就需要保存起来。
- 将 state 存入
localStorage
,mutation
触发时也会将相应的 state 变化更新到localStorage
。 - 可以使用第三方插件
vuex-persist
实现 vuex 持久化存储。
4. 不能跨页面
vuex 的数据是保存在标签隔离的内存空间里面,跨页面的话就不是一个 vue 实例了,数据就没了。可以通过 localStorage 解决。
5. 怎么使用?举例一个流程
createStore()
定义一个 store,传入 state 和 mutations。- 组合式 API 中要调用
useStore
才能在 setup 函数中访问 store。然后调用store.commit()
方法触发 mutaion、用store.dispatch()
触发 action。
// 定义一个 store,传入 state 和 mutations
import { createStore } from 'vuex';
const store = createStore({
state,
mutations
})
// 触发事件,更新state
import { useStore } from 'vuex';
const store = useStore();
store.commit("saveUserInfo", info);
store.dispatch('asyncFunction')
mapState 可以批量更新 Vuex 的 state。
二、Pinia
官方推荐 Vue3 搭配 Pinia。Pinia2 既支持 Vue2 也支持 Vue3。
1. vuex4 和 pinia2 区别
- Pinia 比较轻巧,对
TS
的支持更友好,Pinia2 同时支持Vue2、Vue3。 - Pinia 去除
Mutation
,Action 支持同异步。 - 相比于 Vuex 应用的单一 store 和多个 module 的嵌套结构,Pinia 可以定义多个
Store
,每个 store 都是互相独立的、无需嵌套module,使得数据的结构更加扁平化。
2. 怎么使用?举例一个流程
// store 文件
import { defineStore } from 'pinia'; // 定义一个 store
export const useStore = defineStore('anime', {
state:
actions: {
});
// 使用
import { useStore } from '';
三、Redux
- action:一个描述事件的对象,
dispatch(action)
可以理解为触发一个事件; - reducer:类似事件监听器,会根据接收到的 action 处理事件并返回新的 state ;
- react 中数据是不可变的,因此 reducer 不能直接修改 state。
Redux 执行流程举例:
- 当用户点击按钮后,会 dispatch 一个 action 到 store 里;
- store 会将之前的 state 和当前的 action 传参到 reducer 函数中执行,reducer 会返回新的 state;
- 然后相应的 store.subscribe 方法里的回调函数会执行,相关组件也会重新渲染。
四、vue-router
router 和 route 的区别
- router 是 VueRouter 的实例对象,是一个全局的路由对象,包含了所有路由的对象和属性。
- route 是一个当前激活的路由对象,每个路由都会有一个 route 对象,可以获取一些数据,如:name、path、params、query等。
动态路由
当我们需要将给定匹配模式的路由映射到同一个组件时,例如 User 组件需要对不同 ID 的用户进行渲染。那么在路径参数里可以用/users/:id
来动态匹配,其中 :id
就是动态路径参数。
路由懒加载
路由懒加载:将不同路由对应的组件分割成不同的代码块进行打包,然后当路由被访问的时候才加载对应组件,有利于加快页面加载速度。
// 动态导入
const Home = () => import('../components/Home.vue');
router-view 组件
该标签会根据当前的 url 动态渲染出相对应的组件。
router-link 组件
<router-link>
会被渲染成一个<a>
标签,to 会渲染成 href 属性。
对比<a>
标签,通过<router-link>
进行跳转时不会跳转到新的页面,也不会重新渲染。只更新变化的部分从而减少了DOM性能消耗。
导航守卫
导航守卫就是路由跳转过程中的一些钩子函数,例如在路由切换前进行身份验证、权限检查等。
Vue Router 提供了多种导航守卫:
- 全局前置守卫 beforeEach:会在每个路由切换前都执行;
- 全局后置守卫 afterEnter:只在特定的路由切换前执行