为CSDN博主:安之ccy,博客首页地址:/qq_43523725
转载请注明出处,谢谢支持和鼓励
今日份萌宠图,祝所有勤奋努力善良可爱的小天使们天天开心~💕
写在前面:
摘自官网:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化如果您的应用够简单,您最好不要使用 Vuex如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择
所以,并不是所有的情况都适合使用vuex哦,按需使用最重要😜~ 正文开始~
安装vuex
创建store文件,抽离数据
不使用vuex时,数据是分开维护的
使用vuex时,数据存储在store中
getters获取数据
mutations修改数据
actions设置异步
推荐chrome扩展程序:Vue.js devtools
安装vuex
这次想试试cnpm,指定国内镜像:
npm config set registry https://registry.
验证是否成功:
npm config get registry
如果输出了刚刚设置的那个镜像的链接,代表设置成功
安装cnpm:
npm install -g cnpm --registry=https://registry.
验证cnpm是否安装成功:
cnpm -v
如果输出了各库的版本而非报错信息,代表cnpm安装成功
安装vue cli脚手架:
cnpm -g @vue/cli-init或者 cnpm i -g @vue/cli-init
选择模板webpack-simple创建项目:
vue init webpack-simple vuex-test(项目名称)
进入项目:
cd vuex-test(项目名称)
安装项目依赖:
cnpm install
运行项目:
cnpm run dev
然后会自动在默认浏览器里打开localhost:8080
,里面是系统默认配置的vue版helloworld,大概是这样的:
显示这个页面,说明已经创建项目成功啦~
暂停当前的vue服务(关闭终端窗口或ctrl+c),安装vuex:
npm install vuex --save
在项目文件夹下的package.json文件就会有一个vuex的依赖:
"dependencies": {"vue": "^2.5.11","vuex": "^3.6.2"},
表示vuex安装成功,重新使用cnpm run dev
启动一下项目
我的小插曲(先记录一下):
今天安装的时候忽然出了bug,居然提示我找不到vue-cli文件,node_modules目录下的npm文件没了,于是乎,我就又安装了一遍。重点是需要那个npm文件夹,可以找朋友的npm文件复制过来
创建store文件,抽离数据
背景:
有时,我们可能在不同组件运用了同一组数据;比如商品的价格,不论是预览还是详情页,该商品的价格是一样的。如果这些组件各自维护这组数据,为保证数据的一致,一旦某个子组件需要改动数据,其他子组件都需要做同样的修改。涉及的组件数量很多时,就变得麻烦易错,且冗余度太高。这时,我们可以通过vuex来管理这组数据
不使用vuex时,数据是分开维护的
没有用vuex时,组件各自维护自己的数据,就像这样:
主页面App.vue中创建数据:
data () {return {products:[{name:"陕西大苹果",price:120},{name:"菠萝",price:12},{name:"大西瓜",price:60},{name:"百香果",price:20}]}}
用v-bind动态传递给两个子页面product-list-one和product-list-two:
<template><div id="app"><product-list-one v-bind:products="products"></product-list-one><product-list-two v-bind:products="products"></product-list-two></div></template>
子页面用props接收后展示:
<ul><li v-for="product in products" v-bind:key="product.id"><span class="name">{{product.name}}</span><span class="price">¥{{product.price}}</span></li></ul>
效果:
是的,我们每个子组件都拿到了父组件传来的数据。如果我们想要修改数据,需要在每个组件中添加一个修改函数saleProducts,这个案例有两个需要修改的组件,就需要添加两次这个函数:
saleProducts(){var saleProducts = this.products.map((product)=>{return {name: product.name+"-onsale",price:product.price/2}})return saleProducts}
效果:这个函数,只为了让商品价格都降一半
那可能就有小伙伴在想了,直接在父组件那边修改了数据,然后传给子组件不就好了嘛?欸~我也这么觉得。vuex将这个想法完善成一套机制,用store存储和管理数据,当组件需要这些数据时,去store里取就好了;需要统一修改数据时,也通过提交事件来操作store里的数据。子组件只管取,别的交给vuex
You just move on and I’ll do the rest.
你只管向前,剩下的交给我。
案例修改思路如下:
转移(剪切)主组件App.vue里的数据,删除主组件v-bind动态传递数据和子组件props接收数据的代码新建一个目录存放store代码,包括数据存储、数据获取等在main.js文件中引入store文件,并注册到vue实例对象中,此处命名为store在子页面使用store,如果仅需要获取源数据,可以使用this.$store.state.数据
如果在vue对象中注册时命名为x,就写成
this.$x.state.数据
如果需要对源数据做一些过滤、计数操作,可以在getters中进行,如上面说的商品降价,因为此处只是临时降价,不修改源数据,而是拷贝一份出来修改
使用vuex时,数据存储在store中
在src目录下新建文件夹,命名store;里面新键文件,命名store.js,将数据存到这里
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export const store = new Vuex.Store({state:{products:[{name:"陕西大苹果",price:120},{name:"菠萝",price:12},{name:"大西瓜",price:60},{name:"百香果",price:20}]}}})
在main.js中引入并注册到vue实例中:
import Vue from 'vue'import App from './App.vue'import {store} from './store/store.js'new Vue({//将store注册到vue实例中,命名为storestore:store,el: '#app',render: h => h(App)})
在子组件中使用:
computed:{products(){return this.$store.state.products;}}
<ul><li v-for="product in products" v-bind:key="product.id"><span class="name">{{product.name}}</span><span class="price">¥{{product.price}}</span></li></ul>
这样就可以正常使用数据products了:
Take it one step at a time.
一步一步慢慢来。
getters获取数据
源数据可以正常使用后,我们就可以在store里新增getters字段,在这里定义降价函数:
getters:{// products里的价格都减一半,name加上星星做标记,代表这是降价一半的价格saleProducts:(state)=>{// map会逐一操作每个元素并返回一个新的对象,不改变源数据var saleProducts = state.products.map((product)=>{return {name: "**"+product.name+"**",price: product.price/2}})return saleProducts}
子组件使用降价函数:
computed:{saleProducts(){return this.$store.getters.saleProducts}}
<ul><li v-for="product in saleProducts" v-bind:key="product.id"><span class="name">{{product.name}}</span><span class="price">¥{{product.price}}</span></li></ul>
效果:
fine,又是this又是$符号的,看起来又高级又简洁(吹牛🤥)
如果我们要真正修改数据,要怎么做呢?
mutations修改数据
摘自官网:
更改 Vuex 的 store 中的状态的唯一方法是提交mutation。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型(type) 和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
我们不能随意更改数据,需要使用事件来提交请求,这跟vue里子向父传值需要使用事件传值应该是相似的理念
具体操作如下:
在store对象里新增mutations字段,定义“价格修改函数”在子组件中设置监听当某事件发生时,触发处理函数,commit提交修改数据(状态)请求
在store的mutations字段中定义处理函数reducePrice:
mutations:{reducePrice:(state)=>{state.products.forEach((product)=>{product.price -= 1;})}}
子组件中commit提交事件请求:
methods:{reducePrice(number){this.$mit('reducePrice') }}
在子组件加一个按钮,绑定点击事件,每次点击按钮时将商品价格减少1
<button @click="reducePrice()">降价</button>
由于数据展示时,会经过上面设置的saleProducts函数——数值降价一半后再显示,我们点击一次按钮,展示时只减了0.5,源数据其实是减了1的,此处都展示出来,做一个对比:
<template><div id="product-list-one"><h2>ProductListOne</h2><h3>降价一半后的数据:</h3><ul><li v-for="product in saleProducts" v-bind:key="product.id"><span class="name">{{product.name}}</span><span class="price">¥{{product.price}}</span></li></ul><h3>源数据在此:</h3><ul><li v-for="product in products" v-bind:key="product.id"><span class="name">{{product.name}}</span><span class="price">¥{{product.price}}</span></li></ul><button @click="reducePrice()">降价</button></div></template>
效果:
我们还可以向reduceProducts函数传入参数,比如每次点击按钮降价4元,这个参数,在store有一个专有名:playload
使用处传参:4:
<button @click="reducePrice(4)">降价</button>
mutations处接收并处理:
mutations:{reducePrice:(state,playload)=>{state.products.forEach((product)=>{product.price -= playload;})}}
效果:
mutations中只能定义同步函数,不允许异步操作,异步操作由actions设置
actions设置异步
摘自官网:
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作
使用起来还是类似的操作步骤:
在store对象中新增actions字段,写异步代码,子组件处dispatch同样可以传参,用playload接收
store中新增actions字段,定义异步操作reducePrice:
actions:{reducePrice:(context,playload)=>{setTimeout(function(){mit("reducePrice",playload)},3000)}}
子组件处使用:
methods:{reducePrice(number){this.$store.dispatch("reducePrice",number)}}
效果:点击按钮3秒后,商品价格减4
推荐chrome扩展程序:Vue.js devtools
这个扩展程序可以帮助我们查看调试vuex的操作,如mutations和actions
可以在chrome应用商店里面搜索并安装
安装好之后,可以看到控制台多了一个vue的标签,刚开始界面是这样子的,展示了我们的html标签还有我们的computed:
如果我们在程序中使用了mutations,我们可以借助这个扩展程序查看程序运行到这个部分时的操作,如我点击了“降价”按钮(此时没有设置降价的异步操作),可以直接看到数据发生改变
对于actions,当按下按钮3秒后,数据发生改变的同时,可以看到调试部分出现了改变
可以说是很nice了,有效追踪数据是何时发生变化的
好啦,今天的分享就到这里啦,欢迎各位大佬们点赞、评论、收藏、分享,感谢支持~~
你不会不点赞就走了叭~