Allen's blog Allen's blog
首页
面经
算法 (opens new window)
分类

Allen

前端CV工程师
首页
面经
算法 (opens new window)
分类
  • Javascript

  • TypeScript

  • CSS

  • Vue

    • Vue样式scoped原理以及样式穿透原理
    • inject响应式怎么做
    • Vue状态管理工具Vuex
      • 核心概念
        • state
        • Getter
        • 定义 Getters
        • 获取 Getters
        • Mutation
        • action
      • 项目结构
      • 组合式 API
        • 访问 State 和 Getter
        • 访问 Mutation 和 Action
    • Vue状态管理工具Pinia
    • Vue重用的组件中使用有状态methods(如防抖)有问题
    • vue3 props unknown属性上不存在xxx
    • Vuex中的状态如果是引用类型,没有响应式
    • typescript类型Element转化为HTMLElement
  • React

  • 框架和构建工具

  • 工具库

  • 常见业务场景

  • Bug

  • 项目实战

  • 前端
  • Vue
Allen
2023-04-18
目录

Vue状态管理工具Vuex

通过createStore创建一个store实例

import { createApp } from 'vue'
import { createStore } from 'vuex'

// 创建一个新的 store 实例
const store = createStore({
    state() {
        return {
            count: 0
        }
    },
    mutations: {
        increment(state) {
            state.count++
        }
    }
})

const app = createApp({
    /* 根组件 */
})

// 将 store 实例作为插件安装
app.use(store)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 核心概念

# state

在 Vue 组件中,可以使用this.$store访问store实例,访问状态使用this.$store.state.count。

原理是 app.use(store)的时候,将 store 实例挂在到 Vue 原型上,重命名为$store,因此每个 Vue 组件实例都可以访问 store 实例

可以使用 mapState 辅助函数来进行映射

import { mapState } from 'vuex'

export default {
    computed: {
        ...mapState({
            // 箭头函数可使代码更简练
            count: state => state.count,

            // 传字符串参数 'count' 等同于 `state => state.count`
            countAlias: 'count',

            // 为了能够使用 `this` 获取局部状态,必须使用常规函数
            countPlusLocalState (state) {
            return state.count + this.localCount
        })
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

computed: mapState([
    // 映射 this.count 为 store.state.count
    'count'
])
1
2
3
4

# Getter

Getter 相当于 state 的计算属性,会添加到响应式缓存中。

# 定义 Getters

getters: {
  // ...
  doneTodosCount (state, getters) {
    return getters.doneTodos.length
  }
}
1
2
3
4
5
6

# 获取 Getters

  1. 通过属性访问

在 Vue 组件中可以通过,this.$store.getters.doneTodos来访问

  1. 通过方法访问
  2. mapGetters

# Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,使用this.$store.commit('increment', 10)来提交 mutation

mutation 必须是同步函数,目的是只有是同步函数,devtools 才能跟踪到状态的改变。所以这里使用异步也是可以执行的,可能会有警告,但不是绝对禁止。

# action

Action 类似于 mutation,二者几乎一模一样,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

action 采用 dispatch 来派发,this.$store.dispatch('increment')

# 项目结构

需要遵守的规则:

  1. 应用层级的状态应该集中到单个 store 对象中。

  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

  3. 异步逻辑都应该封装到 action 里面。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 组合式 API

可以通过调用 useStore 函数,来在 setup 钩子函数中访问 store。这与在组件中使用选项式 API 访问 this.$store 是等效的。

import { useStore } from 'vuex'

export default {
    setup() {
        const store = useStore()
    }
}
1
2
3
4
5
6
7

# 访问 State 和 Getter

import { computed } from 'vue'
import { useStore } from 'vuex'

export default {
    setup() {
        const store = useStore()

        return {
            // 在 computed 函数中访问 state
            count: computed(() => store.state.count),

            // 在 computed 函数中访问 getter
            double: computed(() => store.getters.double)
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 访问 Mutation 和 Action

import { useStore } from 'vuex'

export default {
    setup() {
        const store = useStore()

        return {
            // 使用 mutation
            increment: () => store.commit('increment'),

            // 使用 action
            asyncIncrement: () => store.dispatch('asyncIncrement')
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上次更新: 2023/12/16, 09:22:46
inject响应式怎么做
Vue状态管理工具Pinia

← inject响应式怎么做 Vue状态管理工具Pinia→

最近更新
01
rollup使用配置文件rollup.config.ts打包
12-08
02
package.json导出类型
12-08
03
关键问题方案
11-17
更多文章>
Theme by Vdoing | Copyright © 2023-2023 Allen | Github
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式