文章目錄
- 一、需求
- 二、完整代碼
一、需求
步驟
二、完整代碼
Son1.vue
<template><div class="box"><h2>Son1 子組件</h2>從vuex中獲取的值: <label>{{ $store.state.count }}</label><br><button @click="handleAdd(1)">值 + 1</button><button @click="handleAdd(5)">值 + 5</button><button @click="handleAdd(10)">值 + 10</button><button @click="handleChange">一秒后修改成666</button><button @click="changeFn">改標題</button><hr><!-- 計算屬性getters --><div>{{ $store.state.list }}</div><div>{{ $store.getters.filterList }}</div><hr><!-- 測試訪問模塊中的state - 原生 --><div>{{ $store.state.user.userInfo.name }}</div><button @click="updateUser">更新個人信息</button><button @click="updateUser2">一秒后更新信息</button><div>{{ $store.state.setting.theme }}</div><button @click="updateTheme">更新主題色</button><hr><!-- 測試訪問模塊中的getters - 原生 --><div>{{ $store.getters['user/UpperCaseName'] }}</div></div>
</template><script>
export default {name: 'Son1Com',created () {console.log(this.$store.getters)},methods: {updateUser () {// $store.commit('模塊名/mutation名', 額外傳參)this.$store.commit('user/setUser', {name: 'xiaowang',age: 25})},updateUser2 () {// 調用action dispatchthis.$store.dispatch('user/setUserSecond', {name: 'xiaohong',age: 28})},updateTheme () {this.$store.commit('setting/setTheme', 'pink')},handleAdd (n) {// 錯誤代碼(vue默認不會監測,監測需要成本)// this.$store.state.count++// console.log(this.$store.state.count)// 應該通過 mutation 核心概念,進行修改數據// 需要提交調用mutation// this.$store.commit('addCount')// console.log(n)// 調用帶參數的mutation函數this.$store.commit('addCount', {count: n,msg: '哈哈'})},changeFn () {this.$store.commit('changeTitle', '傳智教育')},handleChange () {// 調用action// this.$store.dispatch('action名字', 額外參數)this.$store.dispatch('changeCountAction', 666)}}
}
</script><style lang="css" scoped>
.box{border: 3px solid #ccc;width: 400px;padding: 10px;margin: 20px;
}
h2 {margin-top: 10px;
}
</style>
Son2.vue
<template><div class="box"><h2>Son2 子組件</h2>從vuex中獲取的值:<label>{{ count }}</label><br /><button @click="subCount(1)">值 - 1</button><button @click="subCount(5)">值 - 5</button><button @click="subCount(10)">值 - 10</button><button @click="changeCountAction(888)">1秒后改成888</button><button @click="changeTitle('前端程序員')">改標題</button><hr><div>{{ filterList }}</div><hr><!-- 訪問模塊中的state --><div>{{ user.userInfo.name }}</div><div>{{ setting.theme }}</div><hr><!-- 訪問模塊中的state --><div>user模塊的數據:{{ userInfo }}</div><button @click="setUser({ name: 'xiaoli', age: 80 })">更新個人信息</button><button @click="setUserSecond({ name: 'xiaoli', age: 80 })">一秒后更新信息</button><div>setting模塊的數據:{{ theme }} - {{ desc }}</div><button @click="setTheme('skyblue')">更新主題</button><hr><!-- 訪問模塊中的getters --><div>{{ UpperCaseName }}</div></div>
</template><script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {name: 'Son2Com',computed: {// mapState 和 mapGetters 都是映射屬性...mapState(['count', 'user', 'setting']),...mapState('user', ['userInfo']),...mapState('setting', ['theme', 'desc']),...mapGetters(['filterList']),...mapGetters('user', ['UpperCaseName'])},methods: {// mapMutations 和 mapActions 都是映射方法// 全局級別的映射...mapMutations(['subCount', 'changeTitle']),...mapActions(['changeCountAction']),// 分模塊的映射...mapMutations('setting', ['setTheme']),...mapMutations('user', ['setUser']),...mapActions('user', ['setUserSecond'])// handleSub (n) {// this.subCount(n)// }}
}
</script><style lang="css" scoped>
.box {border: 3px solid #ccc;width: 400px;padding: 10px;margin: 20px;
}
h2 {margin-top: 10px;
}
</style>
store/index.js
// 這里面存放的就是 vuex 相關的核心代碼
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import setting from './modules/setting'// 插件安裝
Vue.use(Vuex)// 創建倉庫
const store = new Vuex.Store({// 嚴格模式 (有利于初學者,檢測不規范的代碼 => 上線時需要關閉)strict: true,// 1. 通過 state 可以提供數據 (所有組件共享的數據)state: {title: '倉庫大標題',count: 100,list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]},// 2. 通過 mutations 可以提供修改數據的方法mutations: {// 所有mutation函數,第一個參數,都是 state// 注意點:mutation參數有且只能有一個,如果需要多個參數,包裝成一個對象addCount (state, obj) {console.log(obj)// 修改數據state.count += obj.count},subCount (state, n) {state.count -= n},changeCount (state, newCount) {state.count = newCount},changeTitle (state, newTitle) {state.title = newTitle}},// 3. actions 處理異步// 注意:不能直接操作 state,操作 state,還是需要 commit mutationactions: {// context 上下文 (此處未分模塊,可以當成store倉庫)// context.commit('mutation名字', 額外參數)changeCountAction (context, num) {// 這里是setTimeout模擬異步,以后大部分場景是發請求setTimeout(() => {context.commit('changeCount', num)}, 1000)}},// 4. getters 類似于計算屬性getters: {// 注意點:// 1. 形參第一個參數,就是state// 2. 必須有返回值,返回值就是getters的值filterList (state) {return state.list.filter(item => item > 5)}},// 5. modules 模塊modules: {user,setting}
})// 導出給main.js使用
export default store
App.vue
<template><div id="app"><h1>根組件- {{ title }}- {{ count }}</h1><input :value="count" @input="handleInput" type="text"><Son1></Son1><hr><Son2></Son2></div>
</template><script>
import Son1 from './components/Son1.vue'
import Son2 from './components/Son2.vue'
import { mapState } from 'vuex'
// console.log(mapState(['count', 'title']))export default {name: 'app',created () {// console.log(this.$router) // 沒配console.log(this.$store.state.count)},computed: {...mapState(['count', 'title'])},data: function () {return {}},methods: {handleInput (e) {// 1. 實時獲取輸入框的值const num = +e.target.value// 2. 提交mutation,調用mutation函數this.$store.commit('changeCount', num)}},components: {Son1,Son2}
}
</script><style>
#app {width: 600px;margin: 20px auto;border: 3px solid #ccc;border-radius: 3px;padding: 10px;
}
</style>
store/index.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
console.log(store.state.count)Vue.config.productionTip = falsenew Vue({render: h => h(App),store
}).$mount('#app')