目录
1.在src目录下新建store文件夹,里面新建index.js:
1.概念:当state中的数据需要进行加工后使用时,可以使用getter加工 src/store/index.js
六、mapSatate方法和mapGetters方法写在computed里面
1.mapState方法:用于帮助我们映射state中的数据为计算属性:
2.mapGetters方法:用于帮助我们映射getters中的数据为计算属性:
1.mapMutations方法:用于帮助我们生成与mutations对话的方法,即包含$store.commit(xxx)函数:
1.mapActions方法:用于帮助我们生成与actions对话的方法,即包含$store.dispatch(xxx)函数:
4.src/componets/Counter.vue:(使用map实现)
5.src/components/Person.vue:(不适用map方法实现)
一、使用场景(共享)
多个组件依赖同一个状态
来自不同组件的行为需要变更同一状态
二、版本限制
vue2中,要用vuex的3版本
vue3中,要用vuex的4版本
npm i vuex@3
三、搭建Vuex开发环境
1.在src目录下新建store文件夹,里面新建index.js:
// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 使用Vuex插件
Vue.use(Vuex)
// 准备actions--用于响应组件中的动作
const actions = {}
// 准备mutations--用于操作数据(state)
const mutations = {}
// 准备state--用于存储数据
const state = {}
//创建并导出store
export default new Vuex.Store({
actions,
mutations,
state
})
2.在main.js文件中使用:
// 引入store
import store from './store'
new Vue({
render: h => h(App),
store,
beforeCreate () {
Vue.prototype.$bus = this
}
}).$mount('#app')
五、分别实现加、减、是奇数且等等再加的案例(基本使用)
1. src/store/index的逻辑代码
// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 使用Vuex插件
Vue.use(Vuex)
// 准备actions--用于响应组件中的动作,可以发送请求在actions里面
const actions = {
increment (context, value) { //context里面就是一个小型的store,value就是传过来的值
// console.log('actions里面的increment被调用了', value, context)
context.commit("INCREMENT", value) //向mutations提交数据 大写是传统默认的
},
decrement (context, value) {
context.commit("DECREMENT", value)
},
waitIncrement (context, value) {
if (context.state.sum % 2) {
setTimeout(() => { context.commit('INCREMENT', value) }, 2000)
}
}
}
// 准备mutations--用于操作数据(state)
const mutations = {
INCREMENT (state, value) { //state为状态,value为传过来的值
// console.log('mutations里面的INCREMENT被调用了', state, value)
state.sum += value * 1
},
DECREMENT (state, value) {
state.sum -= value
}
}
// 准备state--用于存储数据
const state = {
// 当前的和
sum: 0
}
//创建并导出store
export default new Vuex.Store({
actions,
mutations,
state
})
2.App.vue的实现代码
<template>
<div>
<h1>现在的数值是:{{ $store.state.sum }}</h1>
<select name="" id="" v-model="count">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">点我加一</button>
<button @click="jian">点我减一</button>
<button @click="waiteAdd">是奇数且等等加一</button>
</div>
</template>
<script>
export default {
name: 'TestApp',
data () {
return {
count: 1
}
},
methods: {
add () {
// 这个dispatch配送过去只是调用store的action加里面没有业务逻辑可以直接跳过action
// this.$store.dispatch("increment", this.count) //不跳过actions
this.$store.commit("INCREMENT", this.count) //跳过actions直接找mutations
},
jian () {
// this.$store.dispatch("decrement", this.count) //不跳过actions
this.$store.commit("DECREMENT", this.count) //跳过actions直接找mutations
},
waiteAdd () {
this.$store.dispatch("waitIncrement", this.count)
}
}
};
</script>
五、配置项gitters
1.概念:当state中的数据需要进行加工后使用时,可以使用getter加工 src/store/index.js
// 准备getter--用于加工state
const getters = {
bigSum (state) { //state就是状态
return state.sum * 10
}
}
// 准备state--用于存储数据
const state = {
// 当前的和
sum: 0
}
//创建并导出store
export default new Vuex.Store({
actions,
mutations,
state,
getters //配置getters
})
2.使用:App.vue
<h3>放大十倍的数值是:{{ $store.getters.bigSum }}</h3>
六、mapSatate方法和mapGetters方法写在computed里面
帮助我们解决每一次都要写{{ $store.state.sum }}或{{ $store.getters.bigSum }}
import {mapSatate,mapGetters} from 'vuex' 引入才能用
1.mapState方法:用于帮助我们映射state中的数据为计算属性:
<h1>现在的数值是:{{ sum }}</h1>
computed: {
// 借助mapState生成计算属性,sum(对象写法)
// ...mapState({ sum: "sum" })
// 借助mapState生成计算属性,sum(数组写法)
...mapState(['sum'])
},
2.mapGetters方法:用于帮助我们映射getters中的数据为计算属性:
computed: {
// 借助mapGetters生成计算属性,bigSum(对象写法)
// ...mapGetters({ bigSum: "bigSum" }),
// 借助mapGetters生成计算属性,sum(数组写法)
...mapGetters(['bigSum'])
},
七、mapActions方法和mapMutations方法
import {mapActions,mapMutations} from 'vuex' 引入才能用
1.mapMutations方法:用于帮助我们生成与mutations对话的方法,即包含$store.commit(xxx)函数:
对象写法时的@click
<button @click="add(count)">点我加一</button>
<button @click="jian(count)">点我减一</button>
数组写法时的@click
<button @click="INCREMENT(count)">点我加一</button>
<button @click="DECREMENT(count)">点我减一</button>
methods: {
// 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
// add为@click触发的方法哦,"INCREMENT"为store里面的mutations里面的方法
...mapMutations({ add: 'INCREMENT', jian: "DECREMENT" })
// 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
// 注意@click事件与mutation里面的方法一样时可以用
...mapMutations(['INCREMENT',"DECREMENT"])
}
1.mapActions方法:用于帮助我们生成与actions对话的方法,即包含$store.dispatch(xxx)函数:
// 对象时的写法
<button @click="waiteAdd(count)">是奇数且等等加一</button>
// 数组时的写法
<button @click="waitIncrement(count)">是奇数且等等加一</button>
// 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
// waiteAdd是@click方法名,waitIncrement是store里面的actions里面的方法名
...mapActions({ waiteAdd: "waitIncrement" }),
// 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
// 注意@click事件与store里面的action里面的方法名字一样时可以用
...mapActions(["waitIncrement"])
八、Vuex的模块化+namespace(技能提示)
这个我们分两个部分一个使用map的方法(count.js)一个使用store自己写的方法(person.js)
1.src/store/count.js:
export default {
namespaced: true,
actions: {
waitIncrement (context, value) {
if (context.state.sum % 2) {
setTimeout(() => { context.commit('INCREMENT', value) }, 2000)
}
}
},
mutations: {
INCREMENT (state, value) {
state.sum += value * 1
},
DECREMENT (state, value) {
state.sum -= value
}
},
getters: {
bigSum (state) {
return state.sum * 10
}
},
state: { sum: 0 }
}
2.src/store.person.js:
import axios from 'axios'
export default {
namespaced: true,
actions: {
add (context) {
axios({
url: "https://api.uixsj.cn/hitokoto/get?type=social",
method: 'GET',
}).then(
response => {
context.commit("addPersonList", { id: 1, name: response.data })
}
)
}
},
mutations: {
addPersonList (state, value) {
state.personList = [value, ...state.personList]
}
},
getters: {
name (state) {
return state.personList.length == 0 ? "还未添加用户" : state.personList[0].name
}
},
state: {
personList: [
]
}
}
3.src/store/index.js:
// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
import countAbout from './count'
import personAbout from './person'
// 使用Vuex插件
Vue.use(Vuex)
//创建并导出store
export default new Vuex.Store({
modules: {
// countAbout:countAbout, //可以这样写也可以简写
countAbout,
personAbout
}
})
4.src/componets/Counter.vue:(使用map实现)
<template>
<div>
<h1>Count组件</h1>
<div style="display: flex">
<div style="width: 400px; height: 100px">
<h2
style="
border: 1px solid #999;
width: 400px;
height: 50px;
line-height: 50px;
text-align: center;
margin: 0;
"
>
当前的count组件值的和为:<span style="color: purple">{{ sum }}</span>
</h2>
<h2
style="
border: 1px solid #999;
width: 400px;
height: 50px;
line-height: 50px;
text-align: center;
margin: 0;
"
>
当前的count组件值的十倍为:<span style="color: purple">{{
bigSum
}}</span>
</h2>
</div>
<h2
style="
border: 1px solid #999;
width: 400px;
height: 100px;
line-height: 100px;
text-align: center;
margin: 0;
"
>
当前person组件的总人数为:<span style="color: red">{{
personList.length
}}</span>
</h2>
</div>
<div
style="
width: 800px;
border: 1px solid #999;
margin-top: 10px;
display: flex;
justify-content: space-around;
padding: 10px;
box-sizing: border-box;
"
>
<select name="" id="" v-model="count">
<option value="1">每次加1</option>
<option value="2">每次加2</option>
<option value="3">每次加3</option>
</select>
<button @click="INCREMENT(count)">点我加</button>
<button @click="DECREMENT(count)">点我减</button>
<button @click="waitIncrement(count)">点我是奇数加</button>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'TestCount',
computed: {
...mapState('countAbout', ['sum']),
...mapState('personAbout', ['personList']),
...mapGetters('countAbout', ['bigSum'])
},
methods: {
...mapMutations('countAbout', ['INCREMENT']),
...mapMutations('countAbout', ['DECREMENT']),
...mapActions('countAbout', ["waitIncrement"])
},
data () {
return {
count: 1
}
},
};
</script>
<style scoped>
* {
box-sizing: border-box;
}
</style>
5.src/components/Person.vue:(不适用map方法实现)
<template>
<div>
<h1>Person组件</h1>
<div
style="
display: flex;
width: 800px;
height: 60px;
justify-content: space-around;
border: 1px solid red;
padding: 10px;
"
>
<input
type="text"
placeholder="输入一个成员"
style="width: 300px"
ref="input"
v-model.trim="fullName"
/>
<button style="width: 150px" @click="add()">添加</button>
</div>
<div
style="
margin-top: 10px;
display: flex;
width: 800px;
height: 60px;
justify-content: space-around;
border: 1px solid red;
"
>
<h3 style="line-height: 60px; margin-top: 0">
第一个人员姓名为:{{ personName }}
</h3>
<button @click="addPerson">随机添加用户</button>
</div>
<hr />
<h4>人员列表:</h4>
<p
style="padding-left: 40px"
v-for="(item, index) in personList"
:key="index"
>
{{ item.name }}
</p>
</div>
</template>
<script>
export default {
name: 'TestPerson',
data () {
return {
fullName: ""
}
},
computed: {
personList () {
return this.$store.state.personAbout.personList
},
personName () {
return this.$store.getters['personAbout/name']
}
},
mounted () {
this.$refs.input.focus()
},
methods: {
add () {
if (this.fullName === "") {
return alert("请输入姓名")
}
this.$store.commit("personAbout/addPersonList", { id: 1, name: this.fullName })
this.fullName = ""
},
addPerson () {
this.$store.dispatch("personAbout/add")
}
}
};
</script>
<style scoped>
* {
box-sizing: border-box;
}
</style>
6.src/App.vue:
<template>
<div>
<Count />
<hr />
<Person />
</div>
</template>
<script>
import Count from './components/Count.vue'
import Person from './components/Person.vue'
export default {
name: 'TestApp',
components: { Person, Count },
};
</script>