Vuex小结
什么是Vuex
Vuex是一個(gè)專門為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式, 它采用集中式存儲(chǔ)管理所有組件的公共狀態(tài), 并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化.
安裝vuex
npm install vuex --save
與模塊系統(tǒng)一起使用時(shí),必須通過'Vue.use()以下方式顯示安裝Vuex,在main.js添加
import Vuex from 'vuex' Vue.use( Vuex );const store = new Vuex.Store({//待添加 })new Vue({el: "#app",store,render: h => h(App) }); 復(fù)制代碼以下通過demo的示例來了解下Vuex的五大核心
這個(gè)demo分別有兩個(gè)組件productListOne.vue和productListTwo.vue,在App.vue中保存著共有的商品列表
//App.vue中的初始化代碼<template><div id="app"><product-list-one v-bind:products="products"></product-list-one><product-list-two v-bind:products="products"></product-list-two></div> </template><script> import productListOne from "./views/productListOne"; import productListTwo from "./views/productListTwo";export default {name: 'app',components: {"product-list-one": productListOne,"product-list-two": productListTwo},data () {return {products: [{name: '鼠標(biāo)', price: 20},{name: '鍵盤', price: 40},{name: '耳機(jī)', price: 60},{name: '顯示屏', price: 80}]}} } </script><style> body{font-family: Ubuntu;color: #555; } </style> 復(fù)制代碼//productListOne.vue <template><div id="product-list-one"><h2>Product List One</h2><ul><li v-for="product in products"><span class="name">{{ product.name }}</span><span class="price">${{ product.price }}</span></li></ul></div> </template><script> export default {props: ["products"],data() {return {};} }; </script><style scoped> #product-list-one {background: #fff8b1;box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.2);margin-bottom: 30px;padding: 10px 20px; } #product-list-one ul {padding: 0; } #product-list-one li {display: inline-block;margin-right: 10px;margin-top: 10px;padding: 20px;background: rgba(255, 255, 255, 0.7); } .price {font-weight: bold;color: #e8800c; } </style> 復(fù)制代碼//productListTwo.vue <template><div id="product-list-two"><h2>Product List Two</h2><ul><li v-for="product in products"><span class="name">{{ product.name }}</span><span class="price">${{ product.price }}</span></li></ul></div> </template><script> export default {props: ["products"],data() {return {};} }; </script><style scoped> #product-list-two {background: #d1e4ff;box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.2);margin-bottom: 30px;padding: 10px 20px; } #product-list-two ul {padding: 0;list-style-type: none; } #product-list-two li {margin-right: 10px;margin-top: 10px;padding: 20px;background: rgba(255, 255, 255, 0.7); } .price {font-weight: bold;color: #860ce8;display: block; } </style> 復(fù)制代碼核心概念1:State
state就是Vuex中的公共的狀態(tài),用于保存所有組件的公共數(shù)據(jù)
此時(shí)我們就把App.vue中的兩個(gè)組件共同使用的data抽離出來,放到state中
//main.js const store = new Vuex.Store({state:{products: [{ name: "鼠標(biāo)", price: 20 },{ name: "鍵盤", price: 40 },{ name: "耳機(jī)", price: 60 },{ name: "顯示屏", price: 80 }]} }) 復(fù)制代碼productListOne.vue和productListTwo.vue做相應(yīng)的更改
//productListOne.vue export default {data() {return {products: this.$store.state.products //獲取store中state的數(shù)據(jù)};} }; 復(fù)制代碼//productListTwo.vue export default {data() {return {products: this.$store.state.products //獲取store中state的數(shù)據(jù)};} }; 復(fù)制代碼頁面不會(huì)發(fā)生改變
核心概念2:Getters
將getters屬性理解為所有組件的computed屬性,也就是計(jì)算屬性, getters的返回值會(huì)根據(jù)它的依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生了改變才會(huì)被重新計(jì)算
我們在main.js中添加一個(gè)getters屬性,其中的saleProducts對象將state中的價(jià)格減少一半(除以2)
//main.js const store = new Vuex.Store({state:{products: [{ name: "鼠標(biāo)", price: 20 },{ name: "鍵盤", price: 40 },{ name: "耳機(jī)", price: 60 },{ name: "顯示屏", price: 80 }]},getters:{saleProducts:(state)=>{let saleProducts = state.products.map( product => {return{name: product.name,price: product.price / 2}})return saleProducts;}} }) 復(fù)制代碼將productListOne.vue中的products的值更換為this.$store.getters.saleProducts
export default {data() {return {products: this.$store.getters.saleProducts };} }; 復(fù)制代碼可以看到每項(xiàng)商品的價(jià)格都減少了一半
核心概念3:Mutations
將mutations理解為store中的methods,mutations對象中保存著更改數(shù)據(jù)的回調(diào)函數(shù),該函數(shù)名官方規(guī)定叫type,第一個(gè)參數(shù)是state,第二個(gè)參數(shù)是payload,也就是自定義的參數(shù)
我們在main.js中添加mutations屬性,其中minusPrice這個(gè)回調(diào)函數(shù)用于將商品的價(jià)格減少payload這么多
//main.js const store = new Vuex.Store({state:{products: [{ name: "鼠標(biāo)", price: 20 },{ name: "鍵盤", price: 40 },{ name: "耳機(jī)", price: 60 },{ name: "顯示屏", price: 80 }]},getters:{saleProducts:(state)=>{let saleProducts = state.products.map( product => {return{name: product.name,price: product.price / 2}})return saleProducts;}},mutations:{minusPrice (state, payload ){let newPrice = state.products.forEach( product => {product.price -= payload //product.price = product.price - payload})}} }) 復(fù)制代碼在productListTwo.vue中添加一個(gè)按鈕,為其添加一個(gè)點(diǎn)擊事件, 給點(diǎn)擊事件觸發(fā)minusPrice方法
<template><div id="product-list-two"><h2>Product List Two</h2><ul><li v-for="product in products"><span class="name">{{ product.name }}</span><span class="price">${{ product.price }}</span></li><button @click="minusPrice">減少價(jià)格</button> </ul></div> </template> 復(fù)制代碼在productListTwo.vue中注冊minusPrice方法, 在該方法中commitmutations中的minusPrice這個(gè)回調(diào)函數(shù)
注意:調(diào)用mutaions中回調(diào)函數(shù), 只能使用store.commit(type, payload)
export default {data() {return {products: this.$store.state.products //獲取store中state的數(shù)據(jù)};},methods: {minusPrice() {this.$store.commit('minusPrice', 2); //提交`minusPrice,payload為2}} }; 復(fù)制代碼可以發(fā)現(xiàn)每觸發(fā)一次價(jià)格相對應(yīng)的減少了2
核心概念4:Actions
actions類似于 mutations,不同在于:
- actions提交的是mutations而不是直接變更狀態(tài)
- actions中可以包含異步操作,mutations中絕對不允許出現(xiàn)異步
- actions中的回調(diào)函數(shù)的第一個(gè)參數(shù)是context, 是一個(gè)與store實(shí)例具有相同屬性和方法的對象
我們在store中添加actions屬性,其中minusPriceAsync采用setTimeout來模擬異步操作,延遲2s執(zhí)行,該方法用于異步改變我們剛才在mutations中定義的minusPrice
//main.js const store = new Vuex.Store({state:{products: [{ name: "鼠標(biāo)", price: 20 },{ name: "鍵盤", price: 40 },{ name: "耳機(jī)", price: 60 },{ name: "顯示屏", price: 80 }]},getters:{saleProducts:(state)=>{let saleProducts = state.products.map( product => {return{name: product.name,price: product.price / 2}})return saleProducts;}},mutations:{minusPrice (state, payload ){let newPrice = state.products.forEach( product => {product.price -= payload //product.price = product.price - payload})}},actions:{minusPriceAsync(context, payload){setTimeout( () => {context.commit( 'minusPrice', payload );},2000)}} }) 復(fù)制代碼在productListTwo.vue中添加一個(gè)按鈕,為其添加一個(gè)點(diǎn)擊事件, 給點(diǎn)擊事件觸發(fā)minusPriceAsync方法
<template><div id="product-list-two"><h2>Product List Two</h2><ul><li v-for="product in products"><span class="name">{{ product.name }}</span><span class="price">${{ product.price }}</span></li><button @click="minusPrice">減少價(jià)格</button> <button @click="minusPriceAsync">異步減少價(jià)格</button></ul></div> </template> 復(fù)制代碼在productListTwo.vue中注冊minusPriceAsync方法, 在該方法中dispatchactions中的minusPriceAsync這個(gè)回調(diào)函數(shù)
export default {data() {return {products: this.$store.state.products //獲取store中state的數(shù)據(jù)};},methods: {minusPrice() {this.$store.commit('minusPrice', 2); //提交`minusPrice,payload為2},minusPriceAsync() {this.$store.dispatch('minusPriceAsync', 5);}} }; 復(fù)制代碼可以看到觸發(fā)后價(jià)格延遲了2s后減少了5
核心概念5:Modules
由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對象就有可能變得相當(dāng)臃腫。為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(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)復(fù)制代碼轉(zhuǎn)載于:https://juejin.im/post/5cb5a7b0518825329e7ea1fd
總結(jié)
- 上一篇: spring boot中利用mybati
- 下一篇: 腾讯课堂如何看回放(腾讯视频VIP会员)