第四十二章 Vue中使用mutations修改Vuex仓库数据
目录
一、mutations修改仓库数据
1.1. 概述
1.2. mutations修改数据基本步骤
1.3. 完整代码
1.3.1. main.js
1.3.2. App.vue
1.3.3. index.js
1.3.4. Son1.vue
1.3.5. Son2.vue
二、mutations传参语法
2.1. mutations传参基本步骤
2.2. 完整代码
2.2.1. index.js
2.2.2. Son1.vue
三、输入框和Store仓库数据双向绑定
1.3.1. main.js
1.3.2. App.vue
1.3.3. index.js
1.3.4. Son1.vue
1.3.5. Son2.vue
一、mutations修改仓库数据
1.1. 概述
在Vue中,明确vuex同样遵循单向数据流,即组件中不能直接修改仓库的数据,我们可以通过 strict: true 可以开启严格模式,防止在组件中非法修改仓库数据。
this.$store.state.count++ (错误写法)
在Vue中,组件想要修改Vuex的数据,可以通过Vue提供的mutations来实现。本章节我们将通过掌握mutations的操作流程,来修改state数据。 (state数据的修改只能通过mutations )
1.2. mutations修改数据基本步骤
1. 定义 mutations 对象,对象中存放修改 state 的方法
2. 组件中提交调用 mutations
1.3. 完整代码
1.3.1. main.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
console.log(store.state.count)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
1.3.2. App.vue
<template>
<div id="app">
<h1>根组件 - {{ title }} - {{ count }}</h1>
<input 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'
export default {
name: 'app',
created () {
console.log(this.$store.state.count)
},
data () {
return {
}
},
computed: {
...mapState(['count', 'title'])
},
components: {
Son1,
Son2
}
}
</script>
<style>
</style>
1.3.3. index.js
// 存放的是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'
// 配置插件给Vue使用
Vue.use(Vuex)
// 创建仓库(空仓库)
const store = new Vuex.Store({
// 严格模式(有利于初学者,检测不规范的代码 => 上线的时候可以去掉)
strict: true,
// 1. 通过 state提供数据(所有组件可以共享)
state: {
title: '大标题',
count: 100
},
// 2. 通过 mutations 可以提供修改数据的方法
mutations: {
// 所有mutation函数,第一个参数,都是 state
addCount (state) {
// 修改数据
state.count += 1
},
addFive (state) {
state.count += 5
},
changeTitle (state) {
state.title = '小标题'
}
}
})
// 导出给main.js使用
export default store
1.3.4. Son1.vue
<template>
<div class="box">
<h2>{{ $store.state.title }}</h2>
从vuex中获取的值:<label>{{ $store.state.count }}</label>
<br>
<button @click="handleAdd">值 + 1</button>
<button @click="addFive">值 + 5</button>
<button @click="changeTitle">改标题</button>
</div>
</template>
<script>
export default {
name: 'Son1Com',
methods: {
handleAdd () {
// 错误代码(vue默认不会监测,监测需要成本)
// this.$store.state.count++
// console.log(this.$store.state.count)
// 应该通过 mutation 核心概念,进行修改仓库数据
// 需要提交调用mutation
this.$store.commit('addCount')
},
addFive () {
this.$store.commit('addFive')
},
changeTitle () {
this.$store.commit('changeTitle')
}
}
}
</script>
<style lang="css" scoped>
.box {
border: 3px solid #ccc;
width: 400px;
padding: 10px;
margin: 20px;
}
h2 {
margin-top: 10px;
}
</style>
1.3.5. Son2.vue
<template>
<div class="box">
<h2>Son2 子组件</h2>
从vuex中获取的值:<label>{{ count }}</label>
<br>
<button>值 - 1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Son2Com',
computed: {
...mapState(['count'])
}
}
</script>
<style lang="css" scoped>
.box {
border: 3px solid #ccc;
width: 400px;
padding: 10px;
margin: 20px;
}
h2 {
margin-top: 10px;
}
</style>
二、mutations传参语法
2.1. mutations传参基本步骤
提交mutation还可以传递参数 `this.$store.commit( 'xxx', 参数 )`
1. 提供 mutation 函数 (带参数 - 提交载荷 payload )
2. 页面中提交调用 mutation
注:提交参数只能一个,如果有多个参数,需要将该参数包装成一个对象传递
2.2. 完整代码
2.2.1. index.js
// 存放的是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'
// 配置插件给Vue使用
Vue.use(Vuex)
// 创建仓库(空仓库)
const store = new Vuex.Store({
// 严格模式(有利于初学者,检测不规范的代码 => 上线的时候可以去掉)
strict: true,
// 1. 通过 state提供数据(所有组件可以共享)
state: {
title: '大标题',
count: 100
},
// 2. 通过 mutations 可以提供修改数据的方法
mutations: {
// 所有mutation函数,第一个参数,都是 state
addCount (state, n) {
// 修改数据
state.count += n
},
subCount (state, n) {
// 修改数据
state.count -= n
},
changeTitle (state, obj) {
state.title = obj.newTitle
}
}
})
// 导出给main.js使用
export default store
2.2.2. Son1.vue
<template>
<div class="box">
<h2>{{ $store.state.title }}</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="handleSub(1)">值 - 1</button>
<button @click="handleSub(5)">值 - 5</button>
<button @click="handleSub(10)">值 - 10</button>
<button @click="changeTitle">改标题</button>
</div>
</template>
<script>
export default {
name: 'Son1Com',
methods: {
handleAdd (n) {
// 错误代码(vue默认不会监测,监测需要成本)
// this.$store.state.count++
// console.log(this.$store.state.count)
// 应该通过 mutation 核心概念,进行修改仓库数据
// 需要提交调用mutation
this.$store.commit('addCount', n)
},
handleSub (n) {
this.$store.commit('subCount', n)
},
changeTitle () {
this.$store.commit('changeTitle', { name: '王哲晓', newTitle: '2024加油,迎接新的开始,新的起点,新的人生' })
}
}
}
</script>
<style lang="css" scoped>
.box {
border: 3px solid #ccc;
width: 400px;
padding: 10px;
margin: 20px;
}
h2 {
margin-top: 10px;
}
</style>
三、输入框和Store仓库数据双向绑定
1.3.1. main.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
console.log(store.state.count)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
1.3.2. 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'
export default {
name: 'app',
created () {
console.log(this.$store.state.count)
},
data () {
return {
}
},
methods: {
handleInput (e) {
// 1.实时获取输入框的值
const num = e.target.value
// 2.提交mutation,调用mutation函数
this.$store.commit('changeCount', num)
}
},
computed: {
...mapState(['count', 'title'])
},
components: {
Son1,
Son2
}
}
</script>
<style>
</style>
1.3.3. index.js
// 存放的是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'
// 配置插件给Vue使用
Vue.use(Vuex)
// 创建仓库(空仓库)
const store = new Vuex.Store({
// 严格模式(有利于初学者,检测不规范的代码 => 上线的时候可以去掉)
strict: true,
// 1. 通过 state提供数据(所有组件可以共享)
state: {
title: '大标题',
count: 100
},
// 2. 通过 mutations 可以提供修改数据的方法
mutations: {
// 所有mutation函数,第一个参数,都是 state
addCount (state, n) {
// 修改数据
state.count += n
},
subCount (state, n) {
// 修改数据
state.count -= n
},
changeTitle (state, obj) {
state.title = obj.newTitle
},
changeCount (state, newCount) {
state.count = newCount
}
}
})
// 导出给main.js使用
export default store
1.3.4. Son1.vue
<template>
<div class="box">
<h2>{{ $store.state.title }}</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="handleSub(1)">值 - 1</button>
<button @click="handleSub(5)">值 - 5</button>
<button @click="handleSub(10)">值 - 10</button>
<button @click="changeTitle">改标题</button>
</div>
</template>
<script>
export default {
name: 'Son1Com',
methods: {
handleAdd (n) {
// 错误代码(vue默认不会监测,监测需要成本)
// this.$store.state.count++
// console.log(this.$store.state.count)
// 应该通过 mutation 核心概念,进行修改仓库数据
// 需要提交调用mutation
this.$store.commit('addCount', n)
},
handleSub (n) {
this.$store.commit('subCount', n)
},
changeTitle () {
this.$store.commit('changeTitle', { name: '王哲晓', newTitle: '2024加油,迎接新的开始,新的起点,新的人生' })
}
}
}
</script>
<style lang="css" scoped>
.box {
border: 3px solid #ccc;
width: 400px;
padding: 10px;
margin: 20px;
}
h2 {
margin-top: 10px;
}
</style>
1.3.5. Son2.vue
<template>
<div class="box">
<h2>Son2 子组件</h2>
从vuex中获取的值:<label>{{ count }}</label>
<br>
<button>值 - 1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Son2Com',
computed: {
...mapState(['count'])
}
}
</script>
<style lang="css" scoped>
.box {
border: 3px solid #ccc;
width: 400px;
padding: 10px;
margin: 20px;
}
h2 {
margin-top: 10px;
}
</style>