【Vuex】Vuex详解,一篇文章搞懂Vuex详细使用过程和代码编写

本篇博客跟学视频链接:Vuex从入门到实战_bilibili

1. 组件之间数据共享

  • 父向子传值:v-bind 属性绑定

  • 子向父传值:v-on 事件绑定

  • 兄弟组件之间共享数据:EventBus

    • $on 接收数据的那个组件

    • $emit 发送数据的那个组件

2. Vuex概述

  • 实现组件全局(数据)管理的一种机制,可以方便的实现组件之间共享数据,不同于上述三种传递值的方式。
  • 可以把vuex当成一个store仓库,可以集中管理共享的数据,并且存储在vuex中的数据都是响应式的,数据与页面同步。
  • 一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的data中。

3.Vuex基本使用

1)安装vuex依赖

npm install vuex --save

2)导入vuex包

import Vuex from 'vuex'
Vue.use(Vuex)

3)创建store对象

const store = new Vuex.Store({
    // state 中存放全局共享的数据
    state: {count:0}
})

4)store对象挂载到vue实例中

new Vue({
	el: '#app',
	render: h=>h(app),
	router,
	// 创建的共享数据挂载到vue实例
	// 所有组件能够直接从store中获取到全局的数据
	store
})

5)利用vue ui脚手架创建vue项目

复习一下吧:[保姆级教学]使用Vue ui创建一个完整的vue项目_使用vue ui创建vue项目-CSDN博客

  • 详见另一篇文档

3. 项目基础知识

1)格式化

  • 项目下创建文件.prettierrc,应与.gitignore同级,两句代码分别代表:去除分号,用单引号替换双引号。
{
    "semi": false, 
    "singleQuote": true
}

2)git提交

在这里插入图片描述

4. Vuex核心概念

1)State

  • State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。
 // 创建store数据源,提供唯一公共数据
 const store = new Vuex.Store({
 	state: { count: 0 }
 })
1:访问State方法一
  • 注意在唯一根组件template中,可以省略this不写

在这里插入图片描述

2:访问State方法二
  • 导入mapState并把所需要的State域中的属性映射为当前组件的计算属性。

在这里插入图片描述

<template>
    <div>
        <h3>当前最新的count值为:{{ count }}}</h3>
        <button>-1</button>
    </div>
</template>

<script>
import { mapState } from 'vuex';
export default {
    data() {
        return {}
    },
    // 把State全局域中的数据映射为我当前组件的计算属性
    computed: {
        ...mapState(['count'])
    }
}
</script>

2)Mutation

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  // 定义唯一的state域变量
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  // 注意mutations中的方法第一个参数必须是state而且必须带,否则无法调用state中的变量
  mutations: {
    // 不带参mutations
    add(state) {
      state.count++
    },
    // 带参数的mutations
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  }
})
1:触发Mutation方法一
  • 在vuex中不允许组件直接去修改全局域中的数据,必须通过Mutation来变更Store中的数据。 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化(可以监控是谁更改了State)。

addition.vue

<template>
  <div>
    <!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
    <h3>{{$store.getters.showNum}}</h3>
    <!-- 点击该按钮调用Mutation使count值+1 -->
    <button @click="btnHandler1">+1</button>
    <!-- 点击该按钮调用Mutation使count值+N -->
    <button @click="btnHandler2">+N</button>
  </div>
</template>

<script>
export default {
  data() {
    return {}
  },
  // methods方法实际调用的是vuex中的Mutation来改变State域中的值
  methods: {
    btnHandler1() {
      this.$store.commit('add')
      // this.$store.count++; // 不要在本组件中直接修改State域中数据的值
    },
    btnHandler2() {
      // commit 的作用,就是调用 某个 mutation 函数
      this.$store.commit('addN', 3)
    },
  }
}
</script>
2:触发Mutation方法二
  • 同样的,用一个mapMutations将全局的Mutation函数映射到本组件中。

subtraction.vue

<template>
  <div>
    <!-- <h3>当前最新的count值为:{{count}}</h3> -->
    <h3>{{showNum}}</h3>
    <button @click="btnHandler1">-1</button>
    <button @click="subN(3)">-N</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']), // 注册sub和subN函数
    btnHandler1() {
      this.sub()
    }
  }
}
</script>

3)Action

  • 如果我们想书写一个异步操作,如单击+1后等待1s后state域中的值才会发生变化,我们可以用js中的定时器来实现,但是vue不能在mutations函数中执行异步操作,此时我们引入Action。
  • Action 用于处理异步任务。如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发Mutation 的方式间接变更数据。
1:触发Action方式一

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  // 定义唯一的state域变量
  state: {
    count: 0
  },
  mutations: {
    add(state) {
      // 不要在 mutations 函数中,执行异步操作
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 actions 中,不能直接修改 state 中的数据;
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
})

  • commit函数用于触发Mutations,而dispatch函数用于触发Action,注意Action无法直接修改state域中的值,还是必须通过Mutations来间接的修改state域中的值。

Addition.vue

<template>
  <div>
    <!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
    <h3>{{$store.getters.showNum}}</h3>
    <!-- 点击该按钮调用Mutation使count值+1 -->
    <button @click="btnHandler1">+1</button>
    <!-- 点击该按钮调用Mutation使count值+N -->
    <button @click="btnHandler2">+N</button>
    <button @click="btnHandler3">+1 Async</button>
    <button @click="btnHandler4">+N Async</button>
  </div>
</template>

<script>
export default {
  data() {
    return {}
  },
  // methods方法实际调用的是vuex中的Mutation来改变State域中的值
  methods: {
    btnHandler1() {
      this.$store.commit('add');
      // this.$store.count++; // 不要在本组件中直接修改State域中数据的值
    },
    btnHandler2() {
      // commit 的作用,就是调用 某个 mutation 函数
      this.$store.commit('addN', 3)
    },
    // 异步地让 count 自增 +1
    btnHandler3() {
      // 这里的 dispatch 函数,专门用来触发 action
      this.$store.dispatch('addAsync')
    },
    btnHandler4() {
      this.$store.dispatch('addNAsync', 5)
    }
  }
}
</script>
2:触发Action方法二
  • 同样的可以使用mapActions数据结构来引入在store.js中注册过的Action和mapState、mapMutations同理。注意用mapMutations、mapActions注册过的方法可以直接根据函数名来调用。

Subtraction.vue

<template>
  <div>
    <!-- <h3>当前最新的count值为:{{count}}</h3> -->
    <h3>{{ showNum }}</h3>
    <button @click="sub">-1</button>
    <button @click="subN(3)">-N</button>
    <button @click="subAsync">-1 Async</button>
    <button @click="subNAsync(5)">-N Async</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync']),
    // 注意这里的subAsync和subNAsync都可以直接作为函数被调用,不用像btnHandler1一样新开一个函数来调用
    // 由map注册过的方法都可以直接调用
    btnHandler1() {
      this.sub()
    }
  }
}
</script>

4)Getter

  • Getter用于对Store中的数据进行加工处理并形成新的数据,类似于Vue中的计算属性,Store中的数据发生变化,Getter中的数据也发生变化,存在一个响应关系。
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  // 定义唯一的state域变量
  state: {
    count: 0
  },
  mutations: {
	···
  },
  actions: {
    ···
  },
  // getter方法模拟显示当前最新的值
  getters: {
    showNum(state) {
      return '当前最新的数量是【' + state.count + '】'
    }
  }
})
1:使用getters的两种方法

在这里插入图片描述

5. Vuex综合案例

  • 详见于 vuex_demo2,里面有我非常详细的注释。
  • 注意打开新项目时应当删除module_nodes和package-lock.json两个文件夹,并输入指令npm i(即install)和npm run serve来启动服务。
  • 24
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js是一个流行的JavaScript框架,它允许您构建动态Web应用程序。Vuex是一个专为Vue.js应用程序开发的状态管理模式。它允许您在应用程序中管理和维护状态,例如用户信息、购物车、主题等。Vuex将状态存储在一个集中的存储库中,称为store。Vuex的核心概念包括state、mutations、actions和getters。 - state:存储应用程序级别的状态,可以通过store.state访问。 - mutations:用于更改状态的函数,必须是同步函数。可以通过store.commit方法调用。 - actions:用于处理异步操作的函数,可以包含任意异步操作。可以通过store.dispatch方法调用。 - getters:用于从store中获取状态的函数,可以通过store.getters访问。 下面是一个简单的示例,演示如何在Vue.js应用程序中使用Vuex: 1.安装Vuex ```shell npm install vuex --save ``` 2.创建store ```javascript import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }, getters: { getCount: state => { return state.count } } }) export default store ``` 3.在Vue组件中使用store ```javascript <template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="incrementAsync">Increment Async</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex' export default { computed: { ...mapGetters([ 'getCount' ]) }, methods: { ...mapActions([ 'increment', 'incrementAsync' ]) } } </script> ``` 在上面的示例中,我们创建了一个名为count的状态,并定义了一个名为increment的mutation和一个名为incrementAsync的action。我们还定义了一个名为getCount的getter,用于从store中获取count状态。在Vue组件中,我们使用mapGetters和mapActions帮助程序将getter和action映射到组件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值