日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vuex 学习笔记

發(fā)布時間:2023/12/9 vue 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vuex 学习笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Vuex 是什么?

Vuex 是一個專為 Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式。由于SPA應(yīng)用的模塊化,每個組件都有它各自的數(shù)據(jù)(state)、視圖(view)和方法(actions),當(dāng)項(xiàng)目內(nèi)容越來越多時,每個組件中的狀態(tài)就變得很難管理。Vuex 就是采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。

?

1、單個組件中的狀態(tài)

看一下官網(wǎng)提供的計(jì)數(shù)示例:

<template><div><button class="btn btn-success" @click="increment">increment</button> view: {{count}}</div> </template><script>export default {// state data () {return {count: 0}},// actions methods: {increment () {this.count++}}} </script>

運(yùn)行結(jié)果:

從效果圖中可以直觀的看到,每點(diǎn)擊一次按鈕觸發(fā)添加事件(actions),數(shù)據(jù)count(state)就會發(fā)生改變,然后映射到視圖界面(view)中。

下圖可以表示 “ 單項(xiàng)數(shù)據(jù)流 ” 理念的極簡示意:

這個狀態(tài)管理應(yīng)用包含以下幾個部分:

? state:驅(qū)動應(yīng)用的數(shù)據(jù)源

? view:以聲明方式將 state 映射到視圖

? actions:響應(yīng)在 view 上的用戶輸入導(dǎo)致的狀態(tài)變化

?

2、多個組件中的狀態(tài)

當(dāng)我們的應(yīng)用遇到 多個組件共享狀態(tài) 時,單向數(shù)據(jù)流的簡潔性很容易被破壞:

? 多個視圖依賴于同一狀態(tài)

? 來自不同視圖的行為需要變更同一狀態(tài)

?

同樣是計(jì)數(shù)器,我們現(xiàn)在更換一種場景,兩個相同的組件A和B,共享一個數(shù)據(jù)count,并且都有一個方法可以操作這個count(是不是跟上面提到的多組件共享狀態(tài)描述的一樣呢)

// 組件A <template><div>{{ $store.state.count }}<button @click="increment">組件A</button></div> </template><script>export default {methods: {increment () {this.$store.commit('increment')}}} </script>//組件B <template><div>{{ $store.state.count }}<button @click="increment">組件B</button></div> </template><script>export default {methods: {increment () {this.$store.commit('increment')}}} </script>

運(yùn)行效果:

從圖中可以看到,“組件A” 和 “組件B” 兩個按鈕 會同時改變兩個 count 的數(shù)據(jù),因?yàn)閿?shù)據(jù)源 count 和 方法increment 都是全局的。如下圖所示,我們把 全局?jǐn)?shù)據(jù)源 state改變數(shù)據(jù)源的方法 mutations異步操作方法 actions 提取出來放到 store 中,實(shí)現(xiàn)全局?jǐn)?shù)據(jù)狀態(tài)單獨(dú)管理的功能

安裝?

1、使用 npm 安裝并保存到 package.json 中

npm install vuex --save

package.json

"dependencies": {...,...,...,"vuex": "^2.4.1"},

?

2、配置

// 如果在模塊化構(gòu)建系統(tǒng)中,請確保在開頭調(diào)用了 Vue.use(Vuex) import Vue from 'vue' import Vuex from 'vuex'Vue.use(Vuex)//創(chuàng)建Store實(shí)例 const store = new Vuex.Store({// 存儲狀態(tài)值 state: {...},// 狀態(tài)值的改變方法,操作狀態(tài)值// 提交mutations是更改Vuex狀態(tài)的唯一方法 mutations: {...},// 在store中定義getters(可以認(rèn)為是store的計(jì)算屬性)。Getters接收state作為其第一個函數(shù) getters: {...},actions: { ...} }) // 要改變狀態(tài)值只能通過提交mutations來完成/* eslint-disable no-new */ const app = new Vue({router,i18n,// 將 store 實(shí)例注入到根組件下的所有子組件中,子組件通過 this.$store 來訪問store store,...App })app.$mount('#app')

看一下官網(wǎng)提供的例子:

<template><div><p>{{ count }}</p><p><button @click="increment">+</button><button @click="decrement">-</button></p></div> </template><script>export default {computed: {count () {// 通過 store.state 來獲取狀態(tài)對象return this.$store.state.count}},methods: {increment () {// 通過 store.commit 方法觸發(fā)狀態(tài)變更this.$store.commit('increment')},decrement () {this.$store.commit('decrement')}}} </script> // 創(chuàng)建 Store 實(shí)例 const store = new Vuex.Store({// 存儲狀態(tài)值 state: {count: 0},// 狀態(tài)值的改變方法,操作狀態(tài)值// 提交 mutations 是更改Vuex狀態(tài)的唯一方法 mutations: {increment: state => state.count++,decrement: state => state.count--} })

運(yùn)行效果:

?

核心概念

1、State

state 就是全局的狀態(tài)(數(shù)據(jù)源),從前面的例子中看到我們可以按如下方式獲取 Vuex 的state 狀態(tài)

// html 中 {{ $store.state.count }}// js 中 this.$store.state.count

?

2、Getter

getter 可以認(rèn)為是 store 的計(jì)算屬性,跟計(jì)算屬性一樣,getter 的返回值會根據(jù)它的依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生了改變才會重新計(jì)算

如下官網(wǎng)提供的案例:

computed: {doneTodosCount () {return this.$store.state.todos.filter(todo => todo.done).length} }

如果有多個組件需要用到此屬性,我們要么復(fù)制這個函數(shù),或者抽取到一個共享函數(shù)然后在多處導(dǎo)入它,然而這兩種方法都不是很理想,最佳方式當(dāng)然是使用 getter 了

我們嘗試使用下getter

(1)、定義 getter

const store = new Vuex.Store({state: {count: 0},getters: {formatMoney: state => {return '¥'+state.count.toFixed(2)+'元'}},mutations: {increment: state => state.count++} })

(2)、在組件中引用 getter

export default {methods: {increment () {this.$store.commit('increment')// 這里為了更清楚的看到計(jì)算后的值let aaa = document.getElementById('aaa')let p = document.createElement('p')p.innerHTML = this.$store.getters.formatMoneyaaa.appendChild(p)}},computed: {formatMoney() {return this.$store.getters.formatMoney}}}

效果:

3、Mutation

更改 Vuex 的 store 中的狀態(tài)的唯一方法就是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型(type)和一個 回調(diào)函數(shù)(handler),這個回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的地方,并且它會接受 state 作為第一個參數(shù):

const store = new Vuex.Store({state: {count: 1},mutations: {increment (state) {// 變更狀態(tài)state.count++}} })

要喚醒一個 mutation handler,你需要以相應(yīng)的 type 調(diào)用 store.commit 方法

store.commit('increment')

?

(1)、提交載荷(Payload)

載荷(payload)就是說 可以向 store.commit 傳入額外的參數(shù)

// ... mutations: {increment (state, n) {state.count += n} } store.commit('increment', 10)

在大多數(shù)情況下,載荷應(yīng)該是一個對象,這樣可以包含多個字段并且記錄的mutation會更易讀:

// ... mutations: {increment (state, payload) {state.count += payload.amount} } store.commit('increment', {amount: 10 })

?

4、Action

Vuex 中一條重要的原則就是 mutation 必須是同步函數(shù), action 類似于 mutation,不同之處在于:

? Action 提交的是 mutation,而不是直接變更狀態(tài)

? Action 可以包含任意異步操作

const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}},actions: {increment (context) {context.commit('increment')},// 異步 incrementAsync (context) {// 延時1秒setTimeout(() => {context.commit('increment')}, 1000)}} })

Action 函數(shù)接受一個與 store 實(shí)例具有相同方法和屬性的context對象,因此,可以有以下調(diào)用方法

? context.commit ?提交一個 mutation

? context.state ?獲取 state

? context.getters ? 獲取 getters

不同于 mutation 使用 commit 方法,action 使用 dispatch 方法

store.dispatch('increment')

Actions 同樣支持 載荷方式 和 對象方式 進(jìn)行分發(fā):

// 以載荷形式分發(fā) store.dispatch('incrementAsync', {amount: 10 })// 以對象形式分發(fā) store.dispatch({type: 'incrementAsync',amount: 10 })

?

5、Module

由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會集中到一個比較大的對象,當(dāng)應(yīng)用變得非常復(fù)雜時,store 對象就有可能變得非常臃腫。

為了解決以上問題,Vuex 允許我們將 store 分割成 模塊(module),每個模塊擁有自己的 state、mutation、getter、action,甚至是嵌套子模塊 --- 從上至下進(jìn)行同樣方式的分割

const moduleA = {state: { ... },mutations: { ... },actions: { ... },getters: { ... } }const moduleB = {state: { ... },mutations: { ... },actions: { ... } }const store = new Vuex.Store({modules: {a: moduleA,b: moduleB} })store.state.a // -> moduleA 的狀態(tài) store.state.b // -> moduleB 的狀態(tài)

?

關(guān)于項(xiàng)目結(jié)構(gòu),我們可以看看官網(wǎng)提供的示例:

├── index.html ├── main.js ├── api │ └── ... # 抽取出API請求 ├── components │ ├── App.vue │ └── ... └── store├── index.js # 我們組裝模塊并導(dǎo)出 store 的地方├── actions.js # 根級別的 action├── mutations.js # 根級別的 mutation└── modules├── cart.js # 購物車模塊└── products.js # 產(chǎn)品模塊

官網(wǎng)同時也提供了一個 購物車 示例:

app.js 文件如下:

import 'babel-polyfill' import Vue from 'vue' import App from './components/App.vue' import store from './store' import { currency } from './currency'Vue.filter('currency', currency)new Vue({el: '#app',store,render: h => h(App) })

index.js 文件如下:

import Vue from 'vue' import Vuex from 'vuex' import * as actions from './actions' import * as getters from './getters' import cart from './modules/cart' import products from './modules/products' import createLogger from '../../../src/plugins/logger'Vue.use(Vuex)const debug = process.env.NODE_ENV !== 'production'export default new Vuex.Store({actions,getters,modules: {cart,products},strict: debug,plugins: debug ? [createLogger()] : [] })

getters.js 文件如下:

export const cartProducts = state => {return state.cart.added.map(({ id, quantity }) => {const product = state.products.all.find(p => p.id === id)return {title: product.title,price: product.price,quantity}}) }

actions.js 文件如下:

import * as types from './mutation-types'export const addToCart = ({ commit }, product) => {if (product.inventory > 0) {commit(types.ADD_TO_CART, {id: product.id})} }

mutation-type.js 文件如下:

export const ADD_TO_CART = 'ADD_TO_CART' export const CHECKOUT_REQUEST = 'CHECKOUT_REQUEST' export const CHECKOUT_SUCCESS = 'CHECKOUT_SUCCESS' export const CHECKOUT_FAILURE = 'CHECKOUT_FAILURE' export const RECEIVE_PRODUCTS = 'RECEIVE_PRODUCTS'

cart.js 文件如下:

import shop from '../../api/shop' import * as types from '../mutation-types'// initial state // shape: [{ id, quantity }] const state = {added: [],checkoutStatus: null }// getters const getters = {checkoutStatus: state => state.checkoutStatus }// actions const actions = {checkout ({ commit, state }, products) {const savedCartItems = [...state.added]commit(types.CHECKOUT_REQUEST)shop.buyProducts(products,() => commit(types.CHECKOUT_SUCCESS),() => commit(types.CHECKOUT_FAILURE, { savedCartItems }))} }// mutations const mutations = {[types.ADD_TO_CART] (state, { id }) {state.lastCheckout = nullconst record = state.added.find(p => p.id === id)if (!record) {state.added.push({id,quantity: 1})} else {record.quantity++}},[types.CHECKOUT_REQUEST] (state) {// clear cartstate.added = []state.checkoutStatus = null},[types.CHECKOUT_SUCCESS] (state) {state.checkoutStatus = 'successful'},[types.CHECKOUT_FAILURE] (state, { savedCartItems }) {// rollback to the cart saved before sending the requeststate.added = savedCartItemsstate.checkoutStatus = 'failed'} }export default {state,getters,actions,mutations }

products.js 文件如下:

import shop from '../../api/shop' import * as types from '../mutation-types'// initial state const state = {all: [] }// getters const getters = {allProducts: state => state.all }// actions const actions = {getAllProducts ({ commit }) {shop.getProducts(products => {commit(types.RECEIVE_PRODUCTS, { products })})} }// mutations const mutations = {[types.RECEIVE_PRODUCTS] (state, { products }) {state.all = products},[types.ADD_TO_CART] (state, { id }) {state.all.find(p => p.id === id).inventory--} }export default {state,getters,actions,mutations }

購物車運(yùn)行效果:

轉(zhuǎn)載于:https://www.cnblogs.com/rogerwu/p/7606156.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Vuex 学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。