@[toc]
效果展示:
<font color='red'>注意点1:</font>
问题:如何实现“当前和为奇数再加”?
<font color='red'>答案:</font>
incrementOdd(){
if(this.sum % 2){
this.sum += this.n
}
}
<font color='red'>注意点2:</font>
问题:select下拉框默认为1时,点击加号没问题,但是下拉框选中为2时,n值变成字符串了,不应该是数字类型名吗?
<font color='red'>旧代码:无论设置 value="1"还是 value=1都无效</font>
<h1>当前求和为:{{sum}}</h1>
<select v-model="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<font color='red'>答案:因为没设置值选中值为数值类型</font>
方式1,使用v-bind
<h1>当前求和为:{{sum}}</h1>
<select v-model="n">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
</select>
方式2,v-model设置修饰符
<h1>当前求和为:{{sum}}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
9.7求和案例_vuex模块化编码
<font color='red'>注意点1:</font>
<font color='red'>创建并暴露store有2种写法</font>
写法1完整写法
//创建并暴露store
export default new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
写法2简写,不写kye,默认就是key和value同名
//创建并暴露store
export default new Vuex.Store({
modules:{
countOptions,
personOptions
}
})
<font color='red'>注意点2:</font>
报错如图,问题发生在length不认识是哪个对象获得的,解决方案就是如下,mapState第一个参数必须指定分类,不然personList就是underfine,而underfine.length就会报错
<h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3>
...mapState('countAbout',['sum','school','subject']),
<font color='red'>注意点3:</font>
问题:mapState第一个参数指定分类时,报错如图
<font color='red'>解决方案:</font>mapState如果想指定分类,那有个前提,在配置vuex时候每个配置里面都加namespaced:true,不配置namespaced默认为false,只有这么写,你的创建并暴露store的modules的名称(也就是countAbout和personAbout),才能被mapState第一个参数认识。
<font color='red'>注意点4:</font>...mapState可以写很多个进行配置
<font color='red'>注意点5:</font>
问题:报错如图,就说明没指定这个JIA是哪个分类下面的
<font color='red'>解决方案:</font>mapMutations第一个参数也需要指定分类名称,代表从哪里来,正确代码,同理...mapActions第一个参数也需要指定分类名称。
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
<font color='red'>注意点6:</font>
Count.vue使用map方法封装函数,而Person.vue就用最原始的方法去练习
<font color='red'>注意点7:</font>
注意state、getters、dispatch、commit中配置modules的分类名称方法是不一样的,有的方法第一个参数,有的是使用/,识别/前面作为分类名,后面作为mutations的名,详情请看开头总结图片。
<font color='red'>注意点8:</font>
在Person.vue中定义的vuex配置项中的state可不是总的state,而是Person.vue它自己的state
<font color='red'>注意点9:</font>
读取对象属性使用点“.”的时候就不能使用“/”,
错误写法
firstPersonName(){
return this.$store.getters.personAbout/firstPersonName
}
正确写法
firstPersonName(){
return this.$store.getters['personAbout/firstPersonName']
}
完整代码
main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'
//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)
//创建vm
new Vue({
el:'#app',
render: h => h(App),
store,
beforeCreate() {
Vue.prototype.$bus = this
}
})
App.vue
<template>
<div>
<Count/>
<hr>
<Person/>
</div>
</template>
<script>
import Count from './components/Count'
import Person from './components/Person'
export default {
name:'App',
components:{Count,Person},
mounted() {
// console.log('App',this)
},
}
</script>
Count.vue
<template>
<div>
<h1>当前求和为:{{sum}}</h1>
<h3>当前求和放大10倍为:{{bigSum}}</h3>
<h3>我在{{school}},学习{{subject}}</h3>
<h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment(n)">+</button>
<button @click="decrement(n)">-</button>
<button @click="incrementOdd(n)">当前求和为奇数再加</button>
<button @click="incrementWait(n)">等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
name:'Count',
data() {
return {
n:1, //用户选择的数字
}
},
computed:{
//借助mapState生成计算属性,从state中读取数据。(数组写法)
...mapState('countAbout',['sum','school','subject']),
...mapState('personAbout',['personList']),
//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
...mapGetters('countAbout',['bigSum'])
},
methods: {
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
},
mounted() {
console.log(this.$store)
},
}
</script>
<style lang="css">
button{
margin-left: 5px;
}
</style>
Person.vue
<template>
<div>
<h1>人员列表</h1>
<h3 style="color:red">Count组件求和为:{{sum}}</h3>
<h3>列表中第一个人的名字是:{{firstPersonName}}</h3>
<input type="text" placeholder="请输入名字" v-model="name">
<button @click="add">添加</button>
<button @click="addWang">添加一个姓王的人</button>
<button @click="addPersonServer">添加一个人,名字随机</button>
<ul>
<li v-for="p in personList" :key="p.id">{{p.name}}</li>
</ul>
</div>
</template>
<script>
import {nanoid} from 'nanoid'
export default {
name:'Person',
data() {
return {
name:''
}
},
computed:{
personList(){
return this.$store.state.personAbout.personList
},
sum(){
return this.$store.state.countAbout.sum
},
firstPersonName(){
return this.$store.getters['personAbout/firstPersonName']
}
},
methods: {
add(){
const personObj = {id:nanoid(),name:this.name}
this.$store.commit('personAbout/ADD_PERSON',personObj)
this.name = ''
},
addWang(){
const personObj = {id:nanoid(),name:this.name}
this.$store.dispatch('personAbout/addPersonWang',personObj)
this.name = ''
},
addPersonServer(){
this.$store.dispatch('personAbout/addPersonServer')
}
},
}
</script>
Index.js
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)
//创建并暴露store
export default new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
count.js
//求和相关的配置
export default {
namespaced:true,
actions:{
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被调用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
},
mutations:{
JIA(state,value){
console.log('mutations中的JIA被调用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
},
},
state:{
sum:0, //当前的和
school:'尚硅谷',
subject:'前端',
},
getters:{
bigSum(state){
return state.sum*10
}
},
}
person.js
//人员管理相关的配置
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {
namespaced:true,
actions:{
addPersonWang(context,value){
if(value.name.indexOf('王') === 0){
context.commit('ADD_PERSON',value)
}else{
alert('添加的人必须姓王!')
}
},
addPersonServer(context){
axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
response => {
context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
},
error => {
alert(error.message)
}
)
}
},
mutations:{
ADD_PERSON(state,value){
console.log('mutations中的ADD_PERSON被调用了')
state.personList.unshift(value)
}
},
state:{
personList:[
{id:'001',name:'张三'}
]
},
getters:{
firstPersonName(state){
return state.personList[0].name
}
},
}
结果展示
本人其他相关文章链接
1.《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
2.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex版代码
3.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成getters
4.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapState与mapGetters
5.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成mapMutations与mapActions
6.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成多组件共享数据
7.《进阶篇第9章》学习vuex知识点后练习:把求和案例改成vuex模块化编码
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。