Vuex使用总结

1 Vuex简介

  Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,Vuex抽取了各个组件的共享部分,以全局单例模式进行状态的管理。在原生vue中各个组件之间传值使用的是props和event,如果组件嵌套层数过多使用props进行传参会十分繁琐,vuex使用“唯一数据源”进行管理,所有的组件直接从vuex获取数据即可;在使用原生vue时,如果多个视图共享同一个状态的话,当一个视图修改这一状态,我们需要同步其他视图的状态,而vuex中的状态值都是响应式的,状态值一旦被修改,所有引用该值的地方就会自动更新。

  通过一个商品列表的栗子来演示一下Vuex的用法,首先看一下使用props进行传参的用法,添加两个组件:ProductListOne和ProductListTwe,两个组件都展示商品的名字和价格,组件代码如下:

<!-----------------------------App.vue--------------------------------->
<template>
<div id="app">
<production-list-one :products="products"></production-list-one>
<production-list-twe :products="products"></production-list-twe>
</div>
</template> <script>
import ProductListOne from "./components/ProductListOne.vue";
import ProductListTwe from "./components/ProductListTwe.vue";
export default {
name: "app",
components: {
"production-list-one": ProductListOne,
"production-list-twe": ProductListTwe
},
data() {
return {
products: [
{ id: 1, name: "电视", price: 2000 },
{ id: 2, name: "电脑", price: 5000 },
{ id: 3, name: "空调", price: 1500 },
{ id: 4, name: "冰箱", price: 3000 }
]
};
}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="production-list-one">
<h4>Product list one </h4>
<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>
</div>
</template> <script>
export default {
props:["products"],
data() {
return { };
}
};
</script> <!-----------------------------ProductListTwe.vue--------------------------------->
<template>
<div id="product-list-twe">
<h4>Product list twe</h4>
<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>
</div>
</template>
<script>
export default {
props: ["products"],
data() {
return {};
}
}
</script>

  运行程序后,显示如下:

state

  前边父组件App.vue中的数据products通过props传到这两个组件中,现在我们使用vuex来保存products,首先使用 cnpm install vuex --save 添加vuex包,然后添加一个store.js文件来保持数据,该文件代码如下,其中store对象作为“唯一数据源”而存在,所以每个应用都仅仅包含一个store实例,在store对象中state用于保存原始数据:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products: [
{id: ,name: "洗衣机",price: },
{id: ,name: "电脑",price: },
{id: ,name: "空调",price: },
{id: ,name: "冰箱",price: }
]
}
})

  接着在main.js中引入vuex,如下:

import Vue from 'vue'
import App from './App.vue'
import {store} from './store/store.js'
new Vue({
store:store,
el: '#app',
render: h => h(App)
})

  然后修改组件如下:

<!-----------------------------App.vue--------------------------------->
<template>
<div id="app">
<production-list-one></production-list-one>
<production-list-twe></production-list-twe>
</div>
</template> <script>
import ProductListOne from "./components/ProductListOne.vue";
import ProductListTwe from "./components/ProductListTwe.vue";
export default {
name: "app",
components: {
"production-list-one": ProductListOne,
"production-list-twe": ProductListTwe
},
data() {return {};}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="production-list-one">
<h4>Product list one </h4>
<ul>
<li v-for="product in saleProducts1" v-bind:key="product.id">
<span class=name>{{product.name}}</span>
<span class=price>¥{{product.price}}</span>
</li>
</ul>
</div>
</template> <script>
export default {
computed:{
saleProducts1(){
return this.$store.state.products
}
}
};
</script> <!-----------------------------ProductListTwe.vue--------------------------------->
<template>
<div id="product-list-twe">
<h4>Product list twe</h4>
<ul>
<li v-for="product in salesProducts2" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
</div>
</template> <script>
export default {
computed:{
salesProducts2(){
return this.$store.state.products
}
}
};
</script>

  运行程序后,显示和使用props传值的效果一样,两个列表组件的数据源都不在通过props获取,而是通过 this.$store.state.products 从vuex中获取,到这里我们已经完成了vuex的简单使用。

getters

  在vuex中state属性保存的是原始状态,有时候我们需要展示的数据是一些派生状态,就是是对state中的原始数据做一定的逻辑处理后数据,如我们展示的商品列表的价格是打八折后的价格。对应这种需求,我们可以先在组件中使用this.$store.state.xxx获取到原始数据然后在组件中直接写逻辑代码进行处理,但是如果逻辑处理获取的数据在多个组件中都要使用的话,这就需要在每个组件中都重复一遍逻辑代码。为了减少代码冗余,我们可以使用getter属性把"八折"这个共享的逻辑提取出来,实现很简单,直接看代码吧

修改store.js,代码如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products: [
{id: ,name: "洗衣机",price: },
{id: ,name: "电脑",price: },
{id: ,name: "空调",price: },
{id: ,name: "冰箱",price: }
]
},
getters: {
saleProducts(state) {
var saleProducts=state.products.map((product)=>{
return {id:product.id,name:`产品${product.id}:${product.name} `,price:product.price*0.8}
})
return saleProducts;
}
}
})

修改组件代码如下:

<!-----------------------------App.vue--------------------------------->
<template>
<div id="app">
<production-list-one></production-list-one>
<production-list-twe></production-list-twe>
</div>
</template> <script>
import ProductListOne from "./components/ProductListOne.vue";
import ProductListTwe from "./components/ProductListTwe.vue";
export default {
name: "app",
components: {
"production-list-one": ProductListOne,
"production-list-twe": ProductListTwe
},
data() {return {};}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="production-list-one">
<h4>Product list one </h4>
<ul>
<li v-for="product in saleProducts1" v-bind:key="product.id">
<span class=name>{{product.name}}</span>
<span class=price>¥{{product.price}}</span>
</li>
</ul>
</div>
</template> <script>
export default {
computed:{
saleProducts1(){
return this.$store.getters.saleProducts
}
},
};
</script> <!-----------------------------ProductListTwe.vue--------------------------------->
<template>
<div id="product-list-twe">
<h4>Product list twe</h4>
<ul>
<li v-for="product in saleProducts2" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
computed:{
saleProducts2(){
return this.$store.getters.saleProducts
}
}
};
</script>

  我们可以通过 this.$state.getters.xxx 去获取getters中的数据,运行程序后结果如下:

mutations

  上边的state用于存储和获取原始值,getters负责封装公共逻辑,获取计算后的状态,两者都是获取数据时使用的。当我们想修改store中的状态怎么实现呢?提交mutations是更改vuex的stroe中状态的唯一方法。看一个需求:添加一个降价按钮,每次点击都会降价指定的金额。

  首先修改store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products: [
{id: ,name: "洗衣机",price: },
{id: ,name: "电脑",price: },
{id: ,name: "空调",price: },
{id: ,name: "冰箱",price: }
]
},
getters: {
saleProducts(state) {
var saleProducts=state.products.map((product)=>{
return {id:product.id,name:`产品${product.id}:${product.name} `,price:product.price*0.8}
})
return saleProducts;
}
},
mutations:{
reducePrice:function(state,num){
state.products.forEach(proudcts=>proudcts.price-=num)
}
}
})

  修改组件如下:

<!-----------------------------App.vue--------------------------------->
<template>
<div id="app">
<production-list-one></production-list-one>
<production-list-twe></production-list-twe>
</div>
</template> <script>
import ProductListOne from "./components/ProductListOne.vue";
import ProductListTwe from "./components/ProductListTwe.vue";
export default {
name: "app",
components: {
"production-list-one": ProductListOne,
"production-list-twe": ProductListTwe
},
data() {return {};}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="production-list-one">
<h4>Product list one </h4>
<ul>
<li v-for="product in saleProducts1" v-bind:key="product.id">
<span class=name>{{product.name}}</span>
<span class=price>¥{{product.price}}</span>
</li>
</ul>
<button @click="reducePrice(10)">商品降价</button>
</div>
</template> <script>
export default {
//使用vuex中的getters
computed:{
saleProducts1(){
return this.$store.getters.saleProducts
}
}, //使用mutations降价
methods:{
reducePrice:function(num){
this.$store.commit('reducePrice',num)
}
}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="product-list-twe">
<h4>Product list twe</h4>
<ul>
<li v-for="product in saleProducts2" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
computed:{
saleProducts2(){return this.$store.getters.saleProducts}
}
};
</script>

  刷新页面,效果如下:

actions

  使用mutations我们可以直接修改store中的原始值,但是官方不推荐这种做法,官方推荐需要修改store中的值时,我们首先要提交一个action,在action中提交mutation来修改状态值。这种方式方便我们进行调试,同时容易实现异步操作。还是使用降价的栗子,我们点击按钮2秒后实现降价。action的参数是一个和store具有相同方法和属性的context对象,我们可以通过 context.state 和 context.getters 来获取state和getters,也可以使用 context.commit(mutation,payload) 来提交一个mutation,使用首先修改store.js:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products: [
{id: ,name: "洗衣机",price: },
{id: ,name: "电脑",price: },
{id: ,name: "空调",price: },
{id: ,name: "冰箱",price: }
]
},
getters: {
saleProducts(state) {
var saleProducts=state.products.map((product)=>{
return {id:product.id,name:`产品${product.id}:${product.name} `,price:product.price*0.8}
})
return saleProducts;
}
},
mutations:{
reducePrice:function(state,num){
state.products.forEach(proudcts=>proudcts.price-=num)
}
},
//两秒后在提交reducePrice,context是上下文相当于组件中的this.$store
actions:{
reducePriceAction:(context,num)=>{
setTimeout(function(){
context.commit("reducePrice",num)
},)
}
}
})

  修改组件如下:

<!-----------------------------App.vue--------------------------------->
<template>
<div id="app">
<production-list-one></production-list-one>
<production-list-twe></production-list-twe>
</div>
</template> <script>
import ProductListOne from "./components/ProductListOne.vue";
import ProductListTwe from "./components/ProductListTwe.vue";
export default {
name: "app",
components: {
"production-list-one": ProductListOne,
"production-list-twe": ProductListTwe
},
data() {return {};}
};
</script> <!-----------------------------ProductListOne.vue--------------------------------->
<template>
<div id="production-list-one">
<h4>Product list one</h4>
<ul>
<li v-for="product in saleProducts1" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
<button @click="reducePrice(10)">商品降价</button>
</div>
</template> <script>
export default {
//使用vuex中的getters
computed: {
saleProducts1() {
return this.$store.getters.saleProducts;
}
}, //使用action降价,每次降价20元
methods: {
reducePrice: function(num) {
this.$store.dispatch("reducePriceAction", num);
}
}
};
</script> <!-----------------------------ProductListTwe.vue--------------------------------->
<template>
<div id="product-list-twe">
<h4>Product list twe</h4>
<ul>
<li v-for="product in saleProducts2" v-bind:key="product.id">
<span class="name">{{product.name}}</span>
<span class="price">¥{{product.price}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
computed:{
saleProducts2(){
return this.$store.getters.saleProducts
}
}
};
</script>

  实现效果如下:

  本文是vuex的简单入门笔记,更高的特性在以后开发中遇到了在做研究,如果文中有错误希望大家可以指出,我会及时改正。

Vuex实现状态管理的更多相关文章

  1. 理解vuex的状态管理模式架构

    理解vuex的状态管理模式架构 一: 什么是vuex?官方解释如下:vuex是一个专为vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种可预测的 ...

  2. vuex vue状态管理

    第一步安装vuex(安装在生产环境) npm install vuex 第二步 src下新建store文件夹 用来专门放状态管理,store文件夹下新建四个js文件 index.js  actions ...

  3. vue2.0 仿手机新闻站(三)通过 vuex 进行状态管理

    1.创建 store 结构 2.main.js  引入 vuex 3. App.vue  组件使用 vuex <template> <div id="app"&g ...

  4. Vuex,状态管理模式

    对于 Vue 本人目前接触不深,只得浅层分析,Vue 是单向数据流, state,驱动应用的数据源: view,以声明方式将 state 映射到视图: actions,响应在 view 上的用户输入导 ...

  5. Vuex.js状态管理共享数据 - day8

    VScode文件目录: amount.vue代码如下: <template> <div> <!-- <h3>{{ $store.state.count }}& ...

  6. vuex的状态管理模式

    1.store.js Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)) state:存放数据. mutations:提交状态 ...

  7. 举个例子去理解vuex(状态管理),通俗理解vuex原理,通过vue例子类比

    通俗理解vuex原理---通过vue例子类比   本文主要通过简单的理解来解释下vuex的基本流程,而这也是vuex难点之一. 首先我们先了解下vuex的作用vuex其实是集中的数据管理仓库,相当于数 ...

  8. Vuex 模块化实现待办事项的状态管理

    前言 在vue里,组件之间的作用域是独立的,父组件跟子组件之间的通讯可以通过prop属性来传参,但是在兄弟组件之间通讯就比较麻烦了.比如A组件要告诉一件事给B组件,那么A就要先告诉他们的爸组件,然后爸 ...

  9. vuejs组件交互 - 03 - vuex状态管理实现组件交互

    组件交互模式的使用场景 简单应用直接使用props down,event up的模式就可以了 小型应用使用事件中心模式即可 中大型应用使用vuex的状态管理模式 vuex 包含要管理的应用数据和更新数 ...

随机推荐

  1. python 模块、包

    #-----模块.包----- 模块: 一个.py 文件就称之为模块模块好处:1.提高代码可读性 2.编写代码不需要从零开始 python 模块: 1.python标准库 2.第三方模块 3.应用程序 ...

  2. Centos 7 下yum搭建lnmp环境(yum安装方式)

    我们都知道linux下安装软件主要有三种方式: 1.源码编译安装,即下载软件源代码,利用gcc g++ make 等编译工具进行编译安装: 此方式的优点:可以指定软件版本,可选择性好:编译时可以手动指 ...

  3. Python 简易的异步协程使用方法

    代码 import asyncio async def ex(id, n): print(id+" start") await asyncio.sleep(n/2) print(i ...

  4. USB摄像头驱动框架分析

    usb摄像头驱动程序,里面涉及硬件的操作.比如说,想设置亮度的时候,需要把亮度的参数发给硬件.去得到真正视频数据的时候,需要访问硬件得到数据.usb摄像头驱动程序框架与虚拟摄像头驱动程序的框架是一样的 ...

  5. 201871010132--张潇潇--《面向对象程序设计(java)》第十五周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.co ...

  6. flask如何返回真正意义上的json字符串?以及中文如何正常显示?

    flask中,不能直接return字典,需要把字典转换为json字符串方式有三种:1. return str(字典)2.return json.dumps(字典)3.return jsonify(字典 ...

  7. zz斯坦福Jure Leskovec图表示学习:无监督和有监督方法

    斯坦福Jure Leskovec图表示学习:无监督和有监督方法(附PPT下载) 2017 年 12 月 18 日  专知 专知内容组(编) 不要讲得太清楚 [导读]现实生活中的很多关系都是通过图的形式 ...

  8. Ubuntu16.04安装flume

    参考:https://www.cnblogs.com/soyo/p/7686702.html

  9. 每天一道Rust-LeetCode(2019-06-07)

    每天一道Rust-LeetCode(2019-06-07) 622. 设计循环队列 坚持每天一道题,刷题学习Rust. 原题 题目描述 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基 ...

  10. 解决 SpringMVC 非spring管理的工具类使用@Autowired注解注入DAO为null的问题

    在SpringMVC框架中,我们经常要使用@Autowired注解注入Service或者Mapper接口,我们也知道,在Controller层中注入service接口,在service层中注入其它的s ...