>[success] # Vuex
1. 组件之间传值的方式有很多,可以通过各种办法进行父传子,子传父,兄弟组件和非相关组件的传值通信,但是会出现一个问题如果多个组件之间要共享状态(数据)多个组件之 间互相传值很难跟踪数据的变化,如果出现问题很难定位问题
2. `vuex ` 目的就是可以将**组件的共享状态抽取出来,以一个全局单例模式管理**
从而进行状态管理,解决复杂组件通信,数据共享
3. 在 `vue ` 中我们数据流程触发如图
* 在组件中我们定义`data`或者在`setup`中返回使用的数据,这些数据我们称之为**state**
* 在模块`template`中我们可以使用这些数据,模块最终会被渲染成 `DOM`,我们称之为**View**;
* 在模块中我们会产生一些行为事件,处理这些行为事件时,有可能会修改`state`,这些行为事件我们称之为`actions`;
![](https://img.kancloud.cn/e1/c4/e1c403ebc74aab9bbca9c5b4d4789b2a_546x482.png)
4. `vuex` ,将各个组件需要通信的`state` 从内部状态抽离出来,以一个全局单例的方式来管理,vuex 也是遵循流的单向流的形式
* 所有的共享状态都放在 `vuex `的 `state`
* vue 需要渲染的的页面将vuex 提供 state 渲染到页面上
* 但当页面数据改变 或者 需要记录的时候 vuex 不推荐直接修改状态,而是如果是异步数据需要触发 `action` 通过它来触发 `Mutations` 在改变`state`
* 即使你是非异步数据也是要通过 `Mutations` 在改变`state`
这么做的目的是为了`Mutations` 模块进行数据记录变更同步给`vuetools `工具帮助我们可以更方便追踪数据
![](https://img.kancloud.cn/3d/48/3d485cd3f432f984de60852baf3d6a47_734x589.png)
>[info] ## vuex 使用
1. 安装 `npm install vuex`
2. 开发时候一般会起名一个 `store` 文件夹,创建一个**vuex store**
![](https://img.kancloud.cn/98/18/981843f4d7ab4ec86fc5f5b8a35338f7_275x50.png)
~~~
// 创建vuex
import { createStore } from "vuex";
const store = createStore({
state: () => {
return {
name: "wwww",
age: 12,
};
},
});
export default store;
~~~
3. 将创建的`vuex `到如进`vue` 对象上
~~~
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
createApp(App).use(router).use(store).mount("#app");
~~~
4. 开始使用,展示效果
![](https://img.kancloud.cn/28/70/2870dffc305b8ce7b91521c3ac7508d7_210x78.png)
~~~html
<template>
<div class="about">{{ name }} --- {{ age }}</div>
<!-- 因为已经绑定到vue 对象上因此可以通过$store去使用 -->
<div class="about">{{ $store.state.name }} --- {{ $store.state.age }}</div>
</template>
<script setup>
import { toRefs } from "vue";
import { useStore } from "vuex";
const store = useStore();
const { name, age } = toRefs(store.state);
</script>
~~~
>[info] ## vuex 疑问
1. **项目必须使用vuex么**?首先`vuex `并不是必备的,官网也给了相应的意见如果您不打算开发大型单页应用,使用 `Vuex`可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用`Vuex`。一个简单的 `store `模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,`Vuex `将会成为自然而然的选择。
2. 直接不用 `createStore` 直接导出一个对象作为**全局通用属性,和使用vuex 区别在哪里**?Vuex的状态存储是响应式的,**当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会被更新**;通过`mutation` 去改变状态时候`vuetools `管理工具可以帮助我们记录更改方便开发
>[info] ## vuex 特点
1. 用一个对象就包含了全部的应用层级的状态,采用的是SSOT,**Single Source of Truth,也可以翻译成单一数据源**,每个应用将仅仅包含一个 `store` 实例
2. **单一状态树的优势**你的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难,单一状态树能够让我们最直接的方式找到某个状态的片段;
>[info] ## 简单的vuex 模型
~~~
let _Vue = null
class Store {
constructor (options) {
const {
state = {},
getters = {},
mutations = {},
actions = {}
} = options
this.state = _Vue.observable(state)
this.getters = Object.create(null)
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters, key, {
get: () => getters[key](state)
})
})
this._mutaions = mutations
this._actions = actions
}
commit (type, payload) {
this._mutaions[type](this.state, payload)
}
dispatch (type, payload) {
this._actions[type](this, payload)
}
}
function install (Vue) {
_Vue = Vue
_Vue.mixin({
beforeCreate () {
if (this.$options.store) {
_Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
~~~
- 官网给的工具
- 声明vue2 和 vue3
- 指令速览
- Mustache -- 语法
- v-once -- 只渲染一次
- v-text -- 插入文本
- v-html -- 渲染html
- v-pre -- 显示原始的Mustache标签
- v-cloak -- 遮盖
- v-memo(新)-- 缓存指定值
- v-if/v-show -- 条件渲染
- v-for -- 循环
- v-bind -- 知识
- v-bind -- 修饰符
- v-on -- 点击事件
- v-model -- 双向绑定
- 其他基础知识速览
- 快速使用
- 常识知识点
- key -- 作用 (后续要更新)
- computed -- 计算属性
- watch -- 侦听
- 防抖和节流
- vue3 -- 生命周期
- vue-cli 和 vite 项目搭建方法
- vite -- 导入动态图片
- 组件
- 单文件组件 -- SFC
- 组件通信 -- porp
- 组件通信 -- $emit
- 组件通信 -- Provide / Inject
- 组件通信 -- 全局事件总线mitt库
- 插槽 -- slot
- 整体使用案例
- 动态组件 -- is
- keep-alive
- 分包 -- 异步组价
- mixin -- 混入
- v-model-- 组件
- 使用计算属性
- v-model -- 自定义修饰符
- Suspense -- 实验属性
- Teleport -- 指定挂载
- 组件实例 -- $ 属性
- Option API VS Composition API
- Setup -- 组合API 入口
- api -- reactive
- api -- ref
- 使用ref 和 reactive 场景
- api -- toRefs 和 toRef
- api -- readonly
- 判断性 -- API
- 功能性 -- API
- api -- computed
- api -- $ref 使用
- api -- 生命周期
- Provide 和 Inject
- watch
- watchEffect
- watch vs. watchEffect
- 简单使用composition Api
- 响应性语法糖
- css -- 功能
- 修改css -- :deep() 和 var
- Vue3.2 -- 语法
- ts -- vscode 配置
- attrs/emit/props/expose/slots -- 使用
- props -- defineProps
- props -- defineProps Ts
- emit -- defineEmits
- emit -- defineEmits Ts
- $ref -- defineExpose
- slots/attrs -- useSlots() 和 useAttrs()
- 自定义指令
- Vue -- 插件
- Vue2.x 和 Vue3.x 不同点
- $children -- 移除
- v-for 和 ref
- attribute 强制行为
- 按键修饰符
- v-if 和 v-for 优先级
- 组件使用 v-model -- 非兼容
- 组件
- h -- 函数
- jsx -- 编写
- Vue -- Router
- 了解路由和vue搭配
- vueRouter -- 简单实现
- 安装即使用
- 路由懒加载
- router-view
- router-link
- 路由匹配规则
- 404 页面配置
- 路由嵌套
- 路由组件传参
- 路由重定向和别名
- 路由跳转方法
- 命名路由
- 命名视图
- Composition API
- 路由守卫
- 路由元信息
- 路由其他方法 -- 添加/删除/获取
- 服务器配置映射
- 其他
- Vuex -- 状态管理
- Option Api -- VUEX
- composition API -- VUEX
- module -- VUEX
- 刷新后vuex 数据同步
- 小技巧
- Pinia -- 状态管理
- 开始使用
- pinia -- state
- pinia -- getter
- pinia -- action
- pinia -- 插件 ??
- Vue 源码解读
- 开发感悟
- 练手项目