目录
概念:专门在vue中实现集中式状态(数据)管理的一个vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间的通讯方式,且适用于任意组件间通讯;
①、多个组件依赖同一状态;
②、来自不同组件的行为需要变更同一状态;
- // 项目的入口文件
-
- // 引入vue
- import Vue from 'vue'
- // 引入App,他是所有组件的父组件
- import App from './App'
- // 引入vuex
- import Vuex from 'vuex'
- // 引入store
- import store from './store'
-
- // 关闭vue的生产提示
- Vue.config.productionTip = false
- // 使用vuex
- Vue.use(Vuex)
-
- // 创建vue实例对象
- new Vue({
- el:'#app',
- render: h => h(App),
- store,
- })
- <template>
- <div>
- <Count>Count>
- div>
- template>
-
- <script>
- import Count from './components/Count.vue'
-
- export default {
- name: "App",
- components:{Count},
-
- }
- script>
- <template>
- <div>
- <h1>当前求和为:{{$store.state.sum}}h1>
- <select v-model.number="n">
-
- <option :value="1">1option>
- <option :value="2">2option>
- <option :value="3">3option>
- select>
- <button @click="increment">+button>
- <button @click="decrement">-button>
- <button @click="incrementOdd">当前求和为奇数再+1button>
- <button @click="incrementWait">等一等再+1button>
- div>
- template>
-
- <script>
- export default {
- name:'Count',
- data(){
- return{
- n:1,
-
- }
- },
- methods:{
- increment(){
- // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
- this.$store.commit("JIA",this.n)
- },
- decrement(){
- // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
- this.$store.commit("JIAN",this.n)
- },
- incrementOdd(){
- this.$store.dispatch("jiaOdd",this.n)
- },
- incrementWait(){
- this.$store.dispatch("jiaWait",this.n)
- }
- }
- }
- script>
-
- <style>
- button{
- margin-left: 5px;
- }
- style>
- // 该文件用于创建vuex中最核心的store
-
- // 引入Vue
- import Vue from 'vue'
-
- // 引入Vuex
- import Vuex from 'vuex'
-
- // 应用Vuex插件
- Vue.use(Vuex)
-
- // 准备actions————用于响应组件中的动作
- const actions = {
- // 接收两个参数:第一个是mini版的store,第二个是传过来的value值
-
- // 由于没有业务逻辑,所以可以让其直接调用mutations中的commit,而不需要再通过actions
- // jia(context,value){
- // // 调用mutations中的JIA函数
- // console.log('actions中的jia被调用了')
- // context.commit("JIA",value)
- // },
- // jian(context,value){
- // // 调用mutations中的JIA函数
- // console.log('actions中的jian被调用了')
- // context.commit("JIAN",value)
- // },
- jiaOdd(context,value){
- console.log('actions中的jiaOdd被调用了')
- if(context.state.sum % 2){
- // 调用mutations中的JIA函数
- context.commit("JIA",value)
- }
- },
- jiaWait(context,value){
- console.log('actions中的jia被调用了')
- setTimeout(()=>{
- // 调用mutations中的JIA函数
- context.commit("JIA",value)
- },500)
- }
- }
- // 准备mutations————用于操作数据(state)
- const mutations = {
- JIA(state,value){
- console.log('mutations中的JIA被调用了')
- state.sum+=value
- },
- JIAN(state,value){
- console.log('mutations中的JIAN被调用了')
- state.sum-=value
- }
- }
- // 准备state————用于存储数据
- const state = {
- sum:0
- }
-
-
-
- // 创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state
- })
借助mapState生成计算属性,从state中读取数据(对象写法)
- computed:{
- // 借助mapState生成计算属性:sum、school、subject(对象写法)
- ...mapState({sum:'sum',school:'school',subject:'subject'})
- },
借助mapState生成计算属性,从state中读取数据(数组写法)
- computed:{
- // 借助mapState生成计算属性sum、school、subject(数组写法)
- ...mapState(['sum','school','subject'])
- },
借助mapGetters生成计算属性,从getters中读取数据(对象写法)
- computed:{
- // 借助mapState生成计算属性sum、school、subject(数组写法)
- ...mapGetters({bigSum:'bigSum'}),
- },
借助mapGetters生成计算属性,从getters中读取数据(数组写法)
- computed:{
- // 借助mapState生成计算属性sum、school、subject(数组写法)
- ...mapGetters(['bigSum'])
- },
借助mapMutations生成对应的方法,方法中会调用commit去联系mutations;
这里调用increment和decrement方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n;
- <button @click="increment(n)">+button>
- <button @click="decrement(n)">-button>
- methods:{
- // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象方法)
- // 注意:这里调用increment和decrement方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n
- ...mapMutations({increment:'JIA',decrement:'JIAN'}),
-
- },
这里需要将html结构中调用的位置都改为JIA和JIAN;
- <button @click="JIA(n)">+button>
- <button @click="JIAN(n)">-button>
- methods:{
-
- // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组方法)
- // 注意:这里使用的是JIA和JIAN,需要在html结构中改为JIA和JIAN
- ...mapMutations(['JIA','JIAN']),
-
- },
帮我们生成与Actions对话的方法,即:包含$store.dispatch(xxx)的函数;
借助mapActions生成对应的方法,方法中会调用commit去联系mutations;
这里调用iincrementOdd和incrementWait方法会传入一个默认的参数events,所以需要在调用它的html结构中手动传入参数n;
- <button @click="incrementOdd(n)">当前求和为奇数再+1button>
- <button @click="incrementWait(n)">等一等再+1button>
- methods:{
- // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象方法)
- ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
-
- },
这里需要将html结构中调用的位置都改为jiaOdd和jiaWait;
- <button @click="jiaOdd(n)">当前求和为奇数再+1button>
- <button @click="jiaWait(n)">等一等再+1button>
- methods:{
-
- // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组方法)
- ...mapActions(['jiaOdd','jiaWait'])
-
- },
- <template>
- <div>
- <Count>Count>
- <Person>Person>
- div>
- template>
-
- <script>
- import Count from './components/Count.vue'
- import Person from './components/Person.vue'
-
- export default {
- name: "App",
- components:{Count,Person},
-
- }
- script>
- // 该文件用于创建vuex中最核心的store
-
- // 引入Vue
- import Vue from 'vue'
-
- // 引入Vuex
- import Vuex from 'vuex'
-
- // 应用Vuex插件
- Vue.use(Vuex)
-
- // 准备actions————用于响应组件中的动作
- const actions = {
- jiaOdd(context,value){
- console.log('actions中的jiaOdd被调用了')
- if(context.state.sum % 2){
- // 调用mutations中的JIA函数
- context.commit("JIA",value)
- }
- },
- jiaWait(context,value){
- console.log('actions中的jia被调用了')
- setTimeout(()=>{
- // 调用mutations中的JIA函数
- context.commit("JIA",value)
- },500)
- }
- }
- // 准备mutations————用于操作数据(state)
- const mutations = {
- JIA(state,value){
- console.log('mutations中的JIA被调用了')
- state.sum+=value
- },
- JIAN(state,value){
- console.log('mutations中的JIAN被调用了')
- state.sum-=value
- },
- ADD_PERSON(state,value){
- console.log('mutations中的ADD_PERSON被调用了')
- state.personList.unshift(value)
- }
- }
- // 准备state————用于存储数据
- const state = {
- sum:0,
- school:'尚硅谷',
- subject:'前端',
- personList:[
- {id:'001',name:'张三'}
- ]
- }
- // 准备getters————用于存储加工后的数据
- const getters = {
- bigSum(state){
- return state.sum*10
- }
- }
-
-
-
- // 创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state,
- getters
- })
- <template>
- <div>
- <h1>当前求和为:{{sum}}h1>
- <h1>当前求和扩大10倍为:{{bigSum}}h1>
- <h3>我在{{school}},学习{{subject}}h3>
-
- <h3 style="color:red;">Person组件的总人数为:{{personList.length}}h3>
- <select v-model.number="n">
-
- <option :value="1">1option>
- <option :value="2">2option>
- <option :value="3">3option>
- select>
- <button @click="increment(n)">+button>
- <button @click="decrement(n)">-button>
- <button @click="incrementOdd(n)">当前求和为奇数再+1button>
- <button @click="incrementWait(n)">等一等再+1button>
- div>
- template>
-
- <script>
- import {mapState,mapGetters, mapMutations, mapActions} from 'vuex'
- export default {
- name:'Count',
- data(){
- return{
- n:1,
-
- }
- },
- computed:{
- ...mapState(['sum','school','subject','personList']),
- ...mapGetters(['bigSum'])
- },
- methods:{
- ...mapMutations({increment:'JIA',decrement:'JIAN'}),
- ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
- },
- mounted(){
- const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
- }
- }
- script>
-
- <style>
- button{
- margin-left: 5px;
- }
- style>
- <template>
- <div>
- <h1>人员列表h1>
- <h3 style="color:red;">Count组件求和为:{{sum}}h3>
- <input type="text" placeholder="请输入名字" v-model="name">
- <button @click="add">添加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.personList
- },
- sum(){
- return this.$store.state.sum
- }
- },
- methods:{
- add(){
- const personObj = {id:nanoid(),name:this.name}
- this.$store.commit('ADD_PERSON',personObj)
- this.name = ''
- }
- }
- }
- script>
目的:让代码更好维护,让多种数据分类更加明确;
①、在store文件夹中,将不同内容分模块化进行分类,一种内容存储在一个js文件中,通过index.js文件进行import和模块化定义;
- import countOptions from './count'
- import personOptions from './person'
-
- // 创建并暴露store
- export default new Vuex.Store({
- modules:{
- countAbout:countOptions,
- personAbout:personOptions
- }
- })
②、将不同内容放在不同js文件中,并开启命名空间;
person.js和count.js文件结构如下:
- // 个人相关的配置
- export default {
- namespaced:true,
- actions:{
- // ...
- },
- mutations:{
- // ...
- },
- state:{
- // ...
- },
- getters:{
- // ...
- }
this.$store.state.personAbout.list
...mapState('countAbout',['sum','school','subject'])
this.$store.getters['personAbout/firstPersonName']
...mapGetters('countAbout',['bigSum'])
this.$store.dispatch('personAbout/addPersonWang',person)
...mapActions('countAbout',(incrementOdd:'jiaOdd',incrementWait:'jiaWait'))
this.$store.commit('personAbout/ADD_PERSON',person)
...mapActions('countAbout',(increment:'JIA',decrement:'JIAN'))
目录结构:
App.vue
- <template>
- <div>
- <Count>Count>
- <Person>Person>
- div>
- template>
-
- <script>
- import Count from './components/Count.vue'
- import Person from './components/Person.vue'
-
- export default {
- name: "App",
- components:{Count,Person},
-
- }
- script>
-
main.js
- // 项目的入口文件
-
- // 引入vue
- import Vue from 'vue'
- // 引入App,他是所有组件的父组件
- import App from './App'
- // 引入vuex
- import Vuex from 'vuex'
- // 引入store
- import store from './store'
-
- // 关闭vue的生产提示
- Vue.config.productionTip = false
- // 使用vuex
- Vue.use(Vuex)
-
- // 创建vue实例对象
- new Vue({
- el:'#app',
- render: h => h(App),
- store,
- })
components/Count.vue
- <template>
- <div>
- <h1>当前求和为:{{sum}}h1>
- <h1>当前求和扩大10倍为:{{bigSum}}h1>
- <h3>我在{{school}},学习{{subject}}h3>
-
- <h3 style="color:red;">Person组件的总人数为:{{personList.length}}h3>
- <select v-model.number="n">
-
- <option :value="1">1option>
- <option :value="2">2option>
- <option :value="3">3option>
- select>
- <button @click="increment(n)">+button>
- <button @click="decrement(n)">-button>
- <button @click="incrementOdd(n)">当前求和为奇数再+1button>
- <button @click="incrementWait(n)">等一等再+1button>
- div>
- template>
-
- <script>
- import {mapState,mapGetters, mapMutations, mapActions} from 'vuex'
- export default {
- name:'Count',
- data(){
- return{
- n:1,
-
- }
- },
- computed:{
- ...mapState('countAbout',['sum','school','subject']),
- ...mapState('personAbout',['personList']),
- ...mapGetters('countAbout',['bigSum'])
- },
- methods:{
- ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
- ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
- },
- mounted(){
- const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})
- }
- }
- script>
-
- <style>
- button{
- margin-left: 5px;
- }
- style>
components/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(){
- // 添加了personAbout
- return this.$store.state.personAbout.personList
- },
- sum(){
- // 添加了countAbout
- 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>
-
- <style>
-
- style>
store/count.js
- // 求和相关的配置
- export default {
- namespaced:true,
- actions:{
- jiaOdd(context,value){
- console.log('actions中的jiaOdd被调用了')
- if(context.state.sum % 2){
- // 调用mutations中的JIA函数
- context.commit("JIA",value)
- }
- },
- jiaWait(context,value){
- console.log('actions中的jia被调用了')
- setTimeout(()=>{
- // 调用mutations中的JIA函数
- 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
- }
- }
- }
store/index.js
- // 该文件用于创建vuex中最核心的store
-
- // 引入Vue
- 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
- }
- })
store/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){
- // 地址是一个随机自动显示文字的api
- 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
- }
- }
- }