vuex是什么
vuex是一個狀態(tài)管理工具,在使用vue寫代碼的時候能幫助我們更好的管理數(shù)據(jù)
vuex
- 當(dāng)我們需要對數(shù)據(jù)進行更好的統(tǒng)一的管理的時候
- 就需要用到vuex
- 安裝vuex指令:npm i vuex -S
- 創(chuàng)建一個store文件夾,在下面創(chuàng)建一個index.js文件
- 引入vue和vuex
- store用來統(tǒng)一管理數(shù)據(jù)
- 在組件中我們可以使用$store.state.username訪問到下面?zhèn)}庫中聲明定義的username屬性
//引入vue和vuex
import Vue from 'vue'
import Vuex from 'vuex'
//插件使用
Vue.use(Vuex);
// 創(chuàng)建vue項目管理狀態(tài)的倉庫
const store = new Vuex.Store({
// 提供倉庫管理的狀態(tài)
state: {
username: 'zhangsan'
}
});
//導(dǎo)出倉庫
export default store;
vue中的mutation
- 在vue中,不推薦在倉庫外部對state直接進行修改
- 推薦使用提交mutation從而修改state
- 使用下面兩種方法進行修改數(shù)據(jù)修改
- 當(dāng)我們在組件中直接修改state中數(shù)據(jù),也是可以修改的,但是這樣會讓數(shù)據(jù)變得變得不可控,我們需要阻止啟動生產(chǎn)消息,當(dāng)我們在組件中修改state中數(shù)據(jù)中報出警告提示
- 我們把mutation作為修改state的唯一方式
//在main.js中輸入這一行語句后,如果組件中直接修改state,vue可以給我報出警告提示
Vue.config.productionTip = false
//使用mutation修改state方法
//方法一:使用一個數(shù)組
this.$store.commit('modifyUsername', 'lisi')
//方法二:使用一個對象
this.$store.commit({
// type不能省略
type: 'modifyUsername',
value: 'lisi'
})
vue中的action
- 對倉庫數(shù)據(jù)進行修改前,有異步操作,就使用actions
- 我們組件中調(diào)起action操作,在action中執(zhí)行異步操作,然后調(diào)起mutation,依舊使用mutation修改state
- 示例
//在組件中調(diào)起action
// 調(diào)用actions
// 調(diào)用action方法一,使用一個數(shù)組
// this.$store.dispatch('modifyUsernameAction', 'lisi');
// 調(diào)用action方法二,使用一個對象
this.$store.dispatch({
type: 'modifyUsernameAction',
value: 'lisi'
})
//在倉庫中使用action調(diào)用mutation
actions: {
// 方法名字是自定義的
modifyUsernameAction(context, payload){
console.log('modifyUsernameAction執(zhí)行了。。虱歪。。栅表。');
setTimeout(() => {
context.commit({
type: 'modifyUsername',
value: payload.value
});
}, 2000);
}
}
//mutation被調(diào)用修改state
mutations: {
// 方法名字自定義
modifyUsername(state, payload){
console.log('modifyUsername調(diào)用了笋鄙。。怪瓶。萧落。');
state.username = payload.value;
}
}
過濾器
- 過濾器可以將數(shù)據(jù)在dom中的展示變成我們需要的樣子,而不改變變量本身的內(nèi)容
- 因此我們可以方便的計算和展示
全局過濾器
- 我們在main.js中聲明全局過濾器
- 聲明一個名為upppercase的過濾器,將字母轉(zhuǎn)化為大寫
//這是在main.js中聲明的一個全局過濾器
Vue.filter("uppercase", (value, ...rest) => {
console.log("uppercase過濾器執(zhí)行了。洗贰。找岖。。");
console.log(rest);
return value.toUpperCase();
});
- 當(dāng)我們使用時,使用如下方式
//這樣子message代表的字符串就會以uppercase返回后的數(shù)據(jù)方式展示在dom元素上,而message不被改變
<template>
<h1>{{ message | uppercase }}</h1>
</template>
局部過濾器
- 局部過濾器我們在組件的script中創(chuàng)建
export default {
// 局部過濾器
filters: {
currency(value, num) {
return "$" + (value / 6.6999).toFixed(num);
},
},
data(){
return{}
}
}
vuex中的計算屬性getters
- 類似組件中的計算屬性,
- 在組件中我們用
this.$store.getters.recommendCount
來訪問 - 示例:
const store = new Vuex.Store({
state: {
banner: [],
list: []
},
// 計算屬性
// 返回 list的長度和奇偶
getters: {
recommendCount(state, getters){
return state.list.length;
},
type(state, getters){
return getters.recommendCount % 2 === 1 ? 'odd' : 'even';
}
},
})
vuex中的mapState
- mapState可以將全局state中的屬性轉(zhuǎn)化成組件的計算屬性
computed: {
// 內(nèi)部的計算屬性
ab() {
return this.a + this.b;
},
//.......其他內(nèi)部計算屬性都可以在這寫
// 全局的屬性轉(zhuǎn)為組件的計算屬性
...mapState({
bannerData: (state) => state.banner,
listData: (state) => state.list,
count: (state) => state.list.length,
})
},
vuex中的mapGetters
- mapGetters可以將全局中的計算計算屬性(getters)中的屬性轉(zhuǎn)化為組件的計算屬性
computed: {
// 內(nèi)部的計算屬性
ab() {
return this.a + this.b;
},
//.......其他內(nèi)部計算屬性都可以在這寫
// 全局的屬性轉(zhuǎn)為組件的計算屬性
...mapState({
bannerData: (state) => state.banner,
listData: (state) => state.list,
count: (state) => state.list.length,
}),
// 全局的計算屬性轉(zhuǎn)為組件的計算屬性
// 方式1:
// ...mapGetters(['recommendCount', 'type']),
// 方式2:
...mapGetters({
count: 'recommendCount',
type: 'type',
}),
}
vuex的mapMutations和mapActions
- mapMutations可以將全局中的matation為組件的methods
- mapActions可以將全局中的actions轉(zhuǎn)化為組件的methods
methods: {
//組件內(nèi)部的方法敛滋。许布。。
// 轉(zhuǎn)換全局的mutations為組件的methods
// ...mapMutations([]),
// ...mapMutations({}),
// 轉(zhuǎn)換全局的actions為組件的methods
// 方式1:
// ...mapActions(['requestBannerData', 'requestRecommendList']),
// 方式2:
...mapActions({
requestBanner: 'requestBannerData',
requestRecommend: 'requestRecomm,endList',
}),
},
vuex中的模塊化(modules)
- 當(dāng)我們在store中的index.js中寫所有的數(shù)據(jù)管理時,數(shù)據(jù)非常多,管理不方便,所以我們使用模塊化管理數(shù)據(jù)
- 創(chuàng)建新的文件分別管理不同組件的數(shù)據(jù),如下示例1
- 可以給模塊化設(shè)置命名空間,如下示例1
- 在index.js中導(dǎo)入組件數(shù)據(jù)管理的文件,如下示例2
- 在組件中調(diào)用時需要加上路徑名稱,如下示例3
- 當(dāng)有模塊化時候,我們需要使用到mapState,mapGetters,mapMutations,mapActions時候,需要加上模塊名稱,如下示例4
//示例1
//在管理組件數(shù)據(jù)的文件夾導(dǎo)出一個對象,
export default {
// 設(shè)置命名空間
namespaced: true,
state: {
banner: [1, 2, 3, 4]
},
getters: {
len(state, getters, rootState, rootGetters){
console.log(state, getters, rootState, rootGetters);
return state.banner.length;
}
},
mutations: {
add(state, payload){
console.log('home add.....');
state.banner.push(payload);
}
},
actions: {
addAction(context, payload){
console.log('home add action.....');
context.commit('add');
}
}
}
//示例2
import Vue from "vue";
import Vuex from "vuex";
//導(dǎo)入模塊
import user from './modules/user'
import home from './modules/home'
Vue.use(Vuex);
// 創(chuàng)建vue項目管理狀態(tài)的倉庫
const store = new Vuex.Store({
// 倉庫外部不能對state進行修改绎晃,只能在倉庫內(nèi)部修改
strict: true,
state: {},
mutations: {},
actions: {},
// 設(shè)置了倉庫的模塊
modules: {
//給user模塊重新命名為了u
u: user,
home
}
});
//示例3
export default {
methods: {
btnAction(){
// 調(diào)用模塊的state
console.log(this.$store.state.home.banner);
// 調(diào)用getters
console.log(this.$store.getters['home/len']);
// 調(diào)用muataions
this.$store.commit('home/add', 'a');
// 調(diào)用actions
this.$store.dispatch('home/addAction', 'a');
}
}
}
//示例4
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState({
name: state=>state.user.name
}),
...mapGetters({
age: 'user/age'
})
},
methods: {
...mapMutations({
modifyName: 'user/modifyName'
}),
...mapActions({
modifyNameAction: 'user/modifyNameAction'
})
},