您现在的位置是:网站首页> 编程资料编程资料

Vue.js 状态管理及 SSR解析_vue.js_

2023-05-24 317人已围观

简介 Vue.js 状态管理及 SSR解析_vue.js_

前端状态管理出现的意义及解决的问题

随着前端应用的逐步复杂,我们的组件中需要使用越来越多的状态。有的时候我们需要使用子组件将状态传递给父组件就会比较复杂,数据的向上传递过程我们可能会使用回调函数或是数据绑定的形式去处理,就会让代码晦涩难懂。

我们需要一种方式,能够让数据在所有组件中共享,同时能以简单的方式进行传递,这种组织数据的方式就是状态管理。我们很自然的就想到,把数据放到所有需要使用的组件的公共祖先上,在使用时自上而下传递即可。

在 vue.js 中,我们主要说的状态管理库就是 vuex,当然,只要你能实现有条理的组织数据,那么它都可以认为是一种状态管理库。

事实上,我们可以简单的这样理解【状态管理】这个词,vuex 实际上做的事情就是:

  • 在顶层实现一个数据管理的仓库 store,将所有组件间需要共享的数据放置于此;
  • 同时组件也可以对这个 store 内的数据进行更新,同时更新完之后响应式更新所有使用此数据组件的视图;

Vuex 源码解读

Vuex 公共方法

  • 路径:src\util.js
export function find(list, f) { return list.filter(f)[0]; } export function deepCopy(obj, cache = []) { if (obj === null || typeof obj !== 'object') { return obj; } const hit = find(cache, c => c.original === obj); if (hit) { return hit.copy; } const copy = Array.isArray(obj) ? [] : {}; cache.push({ original: obj, copy, }); Object.keys(obj).forEach(key => { copy[key] = deepCopy(obj[key], cache); }); return copy; } export function forEachValue(obj, fn) { Object.keys(obj).forEach(key => fn(obj[key], key)); } export function isObject(obj) { return obj !== null && typeof obj === 'object'; } export function isPromise(val) { return val && typeof val.then === 'function'; } export function assert(condition, msg) { if (!condition) throw new Error(`[vuex] ${msg}`); } export function partial(fn, arg) { return function () { return fn(arg); }; }

Vuex 介绍及深入使用

在说 vuex 之前,我们必须说一说 flux 架构,flux 架构可谓是状态管理的鼻祖。

flux 架构最早由 facebook 推出,主要是为了处理当时他们的 react 框架下状态管理的问题,但在当时来讲,整个设计比较复杂,后来人们简化了其中的一些理念,但是保留了核心思想,继而依据框架实现了很多不同的状态管理库,例如 reduxvuex 等等。其中 redux 大多数被用在了 react 项目中,而 vuex 就是在 vue 框架中实现的这么一个 flux 架构的状态管理库。

**flux 架构约定,存放数据的地方称为 storestore 内部的 state 是数据本身,我们必须通过 action 才能修改 store 里的 state。**这里的 action 指的意思是 行为,在大部分实现里面是一个函数,通过调用函数来更改 store 内部的 state

vuex 中,我们可以通过 mutation 来【同步】的改变 state,这时候就可以在组件中通过 commit 进行调用更改 state

同样的,我们也可以通过 action 来【异步】更改 state,不过在 action 中,我们还是需要调用 mutation

Vuex 使用(官网)

网址链接:vuex.vuejs.org/zh/guide/st…

1、基本框架

import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {}, });

2、基本使用

  • ./store/index.js
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { count: 0, }, mutations: { increment(state, payload = 1) { state.count += payload; }, }, actions: {}, modules: {}, });
  • ./Home.vue

3、State

可以使用计算属性获取 state 中的数据:

computed: { count () { return this.$store.state.count } }

3.1 mapState 辅助函数

当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。

import { mapState } from "vuex"; computed: { ...mapState(["num"]) }

4、Getter

Vuex 允许我们在 store 中定义 getter(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接受 state 作为其第一个参数:

const store = new Vuex.Store({ state: { todos: [ { id: 1, text: 'foo', done: true }, { id: 2, text: 'bar', done: false }, ], }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done); }, }, });

4.1 通过属性访问

Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:

store.getters.doneTodos; // -> [{ id: 1, text: '...', done: true }]

Getter 也可以接受其他 getter 作为第二个参数:

getters: { // ... doneTodosCount: (state, getters) => { return getters.doneTodos.length; }; }

4.2 通过方法访问

你也可以通过让 getter 返回一个函数,来实现给 getter 传参。

getters: { // ... getTodoById: state => id => { return state.todos.find(todo => todo.id === id); }; }
store.getters.getTodoById(2); // -> { id: 2, text: '...', done: false }

【注意】:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果

4.3 mapGetters 辅助函数

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

import { mapGetters } from 'vuex'; export default { computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 ...mapGetters(['doneTodosCount', 'anotherGetter']), }, };

如果你想将一个 getter 属性另取一个名字,使用对象形式:

...mapGetters({ // 把 this.doneCount 映射为 this.$store.getters.doneTodosCount doneCount: 'doneTodosCount' })

5、Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

const store = new Vuex.Store({ state: { count: 1, }, mutations: { increment(state) { // 变更状态 state.count++; }, }, });

你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:

store.commit('in
                
                

-六神源码网