失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Vue全家桶Vuex

Vue全家桶Vuex

时间:2022-08-14 15:27:31

相关推荐

Vue全家桶Vuex

文章目录

一、Vuex是什么?二、Vuex的安装及使用1.安装2.使用3.配置4.state4.1. 在main.js中创建Vuex实例4.2. 如何获取state?4.2.1.mapState辅助函数 5.getter5.1.mapGetters辅助函数 6.mutation6.1.mapMutaions辅助函数 7.action7.1.mapActions辅助函数 8.module模块化和命名空间

一、Vuex是什么?

在实际开发中经常会遇到多组件访问同一数据的情况,而且需要根据数据的变化做出响应,而这些组件之间并不是父子组件这种简单的关系,在这种情况下,就需要一个全局的状态管理方案。在Vue中,官方推荐使用Vuex。

在项目中应用的场景非常广泛,比如实现购物车,会员登录验证等功能,开发大型项目需要用Vuex来做数据流的管理。

二、Vuex的安装及使用

1.安装

可以使用CDN的方式安装,代码如下:

<!--引用最新版本--><script src=”/vuex”></script><!--引用指定版本--><script src=”/vuex@2.0.0”></script>

如果使用模块化开发,则使用NPM方法安装,输入并执行以下命令:

npm install --save vuex

2.使用

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

3.配置

在Vue的脚手架项目中使用,在src/main.js文件中的代码如下:

//导入Vueximport Vuex from "vuex";//安装插件Vue.use(Vuex);//实例化Vuex并调用Store方法let store=new Vuex.Store({});new Vue({router,store,//注册storerender: h => {return h(App)},}).$mount('#app')

4.state

Vuex使用单一状态树,用一个对象就包含了全部的应用层级状态。作为唯一的数据源而存在,这也意味着,每个应用将仅仅包含一个store实例。

4.1. 在main.js中创建Vuex实例

let store=new Vuex.Store({//状态数据放在state选项中state:{count:0}});

4.2. 如何获取state?

//1.标签中获取<template><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{$store.state.count}}</div></template>//2.js中<script>export default {name: "home",created(){//在js中访问store实例中state选项的count属性值console.log(this.$store.state.count);}}</script>

4.2.1.mapState辅助函数

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。

<template><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{count}}</div></template>import {mapState} from "vuex";computed:{//使用扩展运算符提取mapState函数返回的对象属性...mapState({//方式1:箭头函数可使代码更简练(推荐使用)count:state=>state.count,//方式2:传字符串参数count等同于 `state => state.count`count:"count",//方式3:为了能够使用this获取局部状态,可以使用常规函数count(state){return state.count}方式4:使用数组的方式获取state存放的数据...mapState(["count"])})}

5.getter

它与计算属性类似相当于computed(只不过这是全局的),有时候我们需要从store中的state中派生出一些状态,例如对列表进行过滤并计数:

// 1.main.js创建的Vuex实例let store=new Vuex.Store({state:{users:[{id:1,name:"张三",age:18},{id:2,name:"李四",age:20},{id:3,name:"王五",age:22},{id:4,name:"赵六",age:25}]},getters:{/*第一个参数:本模块中的state第二个参数:其他 getter第三个参数:所有模块的state*/getUsers(state,getters,rootState){//筛选age大于18的数据let users=state.users.filter((res)=>{return res.age>18})return users;}}});//2.在需要的组件中使用<template><div class="page"><ul><li v-for="item in $store.getters.getUsers" :key="item.id">{{item.name}}--{{item.age}}</li></ul></div></template><script>export default {name: "home",created() {//在js中访问getterconsole.log(this.$store.getters.getUsers)}}</script>

5.1.mapGetters辅助函数

<template><div class="page"><ul><li v-for="item in getUsers" :key="item.id">{{item.name}}--{{item.age}}</li></ul></div></template><script>import {mapGetters} from "vuex";export default {name: "home",computed:{//使用扩展运算符提取mapGetters函数返回的对象属性//方式一:数组字符串形式...mapGetters(["getUsers"]),//方式二:对象形式(推荐使用)...mapGetters({getUsers:"getUsers"})}}</script>

6.mutation

如果想要改变state中的count的值唯一方法是提交 mutation。Vuex中的 mutation 非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。

// 1.main.js 中创建vuex实例let store=new Vuex.Store({//状态数据放在state选项中state:{count:0},mutations:{//自定义inc方法inc(state,payload){state.count+=payload.amount;}}});//2.在需要的组件中使用<template><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{$store.state.count}} <button type="button" @click="increment">+</button></div></template><script>export default {name: "home",methods:{increment(){//使用commit调用store实例中mutations中的inc方法 载荷提交(推荐使用)this.$mit("inc",{amount:10});//对象风格的提交this.$mit({type:"inc",amount:10});}}

使用常量替代Mutation事件类型(多人开发时可以使用这种形式):

1.首先在src文件夹下创建store文件夹,在该文件夹下创建mutation-types.js文件,该文件的代码如下:

//1.导出一个名为INC的常量值为“incexport const INC="inc";

2.导入一个名为INC的常量值为“inc”,在src/main.js文件中的代码如下:

//导入INC常量import {INC} from "./store/mutation-types";mutations:{//使用ES6风格的计算属性命名功能来使用一个常量作为函数名[INC](state,payload){state.count+=payload.amount;}}

6.1.mapMutaions辅助函数

在实际开发中,大多数都使用辅助函数的方式提交mutation。

<template><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{count}} <button type="button" @click="increment">+</button></div></template>import {mapMutations} from "vuex";methods:{//使用ES6扩展运算符提取mapMutations函数返回的对象属性//方式一(推荐):使用对象的方式,将this.inc()映射为this.$mit("inc")...mapMutations({inc:"inc"}),//方式二:使用字符串数组方式,将this.inc()映射为this.$mit("inc")...mapMutations(["inc"]),increment(){//这里的inc方法就是上面...mapMutations(["inc"])中的incthis.inc({amount:10});}},

注意:一条重要的原则就是要记住 mutation必须是同步函数。如果使用异步函数比如setTimeout,代码执行上不会有任何问题。只是在调试上变得困难,比如我们正在debug一个应用并且观察 devtool 中的 mutation 日志。devtools是一款基于chrome游览器的插件,用于调试Vue应用,可以去百度搜索vue-devtools进行下载安装,使用非常简单,这里就不在做详细的介绍,因为在开发中没有必要非用vue-devtools调试。

7.action

Action类似 mutation,不同在于,Action提交的是 mutation,而不是直接变更状态,Action可以包含任意的异步操作。

//1.实例化Vuex并调用store方法let store=new Vuex.Store({//状态数据放在state选项中state:{count:0},mutations:{inc(state,payload){//接收action分发的payloadstate.count+=payload.amount;}},actions:{asyncInc({commit},payload){//将接收的分发payload,组装新的对象形式的值{amount:payload.amount}使用commit提交给mutationcommit("inc",{amount:payload.amount})}}});

// 2.使用<template><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{count}} <button type="button" @click="increment">+</button></div></template>methods:{increment(){//以载荷形式分发this.$store.dispatch("asyncInc",{amount:10});//以对象形式分发this.$store.dispatch({type:"asyncInc",amount:10}); }},

7.1.mapActions辅助函数

同样action和mutation一样也有辅助函数使用方式也一样,在实际开发中我们使用辅助函数来进行分发。

<template><div class="page"><div class="page"><!--在视图中访问store实例中state选项的count属性值-->计数器:{{count}} <button type="button" @click="increment">+</button></div></div></template>import {mapActions} from "vuex";methods:{//使用扩展运算符ES6扩展运算符提取mapActions函数返回的对象属性//方式一:使用对象的方式,将this.asyncInc()映射为this.$store.dispatch("asyncInc")...mapActions({asyncInc:"asyncInc"}),//方式二:使用字符串数组方式,将this.asyncInc()映射为this.$store.dispatch("asyncInc")...mapActions(["asyncInc"]),increment(){//这里的asyncInc方法就是上面...mapActions(["asyncInc"])中的incthis.asyncInc({amount:10})}},

8.module模块化和命名空间

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割,例如:

const moduleA = {state: {... },mutations: {... },actions: {... },getters: {... }}const moduleB = {state: {... },mutations: {... },actions: {... }}const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}})store.state.a // -> moduleA 的状态store.state.b // -> moduleB 的状态

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的,这样使得多个模块能够对同一mutation或action作出响应。 如果希望模块具有更高的封装度和复用性,可以通过添加namespaced: true的方式使其成为带命名空间的模块。当模块被注册后,它的所有getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

let counter={namespaced:true,//开启支持命名空间};

如果觉得《Vue全家桶Vuex》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。