>[success] # Vuex
1. 組件之間傳值的方式有很多,可以通過各種辦法進行父傳子,子傳父,兄弟組件和非相關組件的傳值通信,但是會出現一個問題如果多個組件之間要共享狀態(數據)多個組件之 間互相傳值很難跟蹤數據的變化,如果出現問題很難定位問題
2. `vuex ` 目的就是可以將**組件的共享狀態抽取出來,以一個全局單例模式管理**
從而進行狀態管理,解決復雜組件通信,數據共享
3. 在 `vue ` 中我們數據流程觸發如圖
* 在組件中我們定義`data`或者在`setup`中返回使用的數據,這些數據我們稱之為**state**
* 在模塊`template`中我們可以使用這些數據,模塊最終會被渲染成 `DOM`,我們稱之為**View**;
* 在模塊中我們會產生一些行為事件,處理這些行為事件時,有可能會修改`state`,這些行為事件我們稱之為`actions`;

4. `vuex` ,將各個組件需要通信的`state` 從內部狀態抽離出來,以一個全局單例的方式來管理,vuex 也是遵循流的單向流的形式
* 所有的共享狀態都放在 `vuex `的 `state`
* vue 需要渲染的的頁面將vuex 提供 state 渲染到頁面上
* 但當頁面數據改變 或者 需要記錄的時候 vuex 不推薦直接修改狀態,而是如果是異步數據需要觸發 `action` 通過它來觸發 `Mutations` 在改變`state`
* 即使你是非異步數據也是要通過 `Mutations` 在改變`state`
這么做的目的是為了`Mutations` 模塊進行數據記錄變更同步給`vuetools `工具幫助我們可以更方便追蹤數據

>[info] ## vuex 使用
1. 安裝 `npm install vuex`
2. 開發時候一般會起名一個 `store` 文件夾,創建一個**vuex store**

~~~
// 創建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. 開始使用,展示效果

~~~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 源碼解讀
- 開發感悟
- 練手項目