Vue.js 系列教程 4:Vuex
原文:intro-to-vue-4-vuex
译者:nzbin
这是关于 JavaScript 框架 Vue.js 五个教程的第四部分。在这一部分,我们会学习使用 Vuex 进行状态管理。这个系列教程并不是一个完整的用户手册,而是通过基础知识让你快速了解 Vuejs 以及它的用途。
系列文章:
- 渲染, 指令, 事件
- 组件, Props, Slots
- Vue-cli
- Vuex (你在这!)
- Animations
Vuex
如果你错过了关于组件及 Vue-cli 的部分,在阅读本篇文章之前应该先读读这几部分。现在我们已经了解了关于组件、传递状态和 props 的基本知识,接下来讨论一下 Vuex,它是状态管理的好工具。
之前,我们是从顶层组件向下传递状态,而同胞组件之间并没有分享数据。如果它们需要相互通信,我们要在应用程序中推送状态。这是可以的!但是一旦你的程序变得复杂,这种方法就没有意义了。如果你之前用过 Redux,那 Vuex 中所有的概念及实现对你也不陌生。Vuex 是 Vue 中的 Redux。实际上,Redux 也可以用于 Vue,但是,使用专门为 Vue 设计的工具 Vuex 更加有利。
首先,安装 Vuex:
npm install vuex
或者
yarn add vuex
我这样设置: 在 `/src` 目录下,我创建了名为 store 的目录 ( 这是一种选择,你也可以在同级目录创建一个 `store.js` 文件 ),再在其中创建一个名为 `store.js`的文件。`store.js` 中的初始设置如下 ( vstore sublime snippet ):
import Vue from 'vue'; import Vuex from 'vuex';Vue.use(Vuex);export const store = new Vuex.Store({state: {key: value} });
key: value
是状态数据的占位符。在其他例子中,我们已经使用 counter: 0
。
在 `main.js` 文件中,我们将执行以下更新(加粗显示更新的行):
import Vue from 'vue'; import App from './App.vue';import { store } from './store/store';new Vue({el: '#app',store: store,template: '<App/>',components: { App } });
更新之后,和之前做的组件一样,我们可以把 data()
作为状态,然后我们通过以下三种方式使用或者更新状态:
- Getters 可以在模板中静态的显示数据。换句话说,getters 可以读取数据,但不能改变状态。
- Mutations 允许更新状态,但永远是同步的。Mutations 是 store 中改变状态数据的唯一方式。
- Actions 允许异步更新状态,但是需要使用一个已经存在的 mutation 。如果你需要以特定的顺序同时执行不同的 mutations 会非常有用。
如果你以前没有接触过,也许很难理解为什么会使用异步状态的变化,所以先看看理论上它会发生什么,然后再开始下一部分。假如你运行 Tumblr。如果页面中有大量长时间运行的 gif 图片。你只想每次载入其中一部分,比如当用户将页面滚动到底部 200px 时,加载 20 个图片。
你需要使用 mutation 展示后面的 20 个。但是现在还没有后面的 20 个,你不知道何时到达页面底部。因此,在程序中,创建一个事件来监听滚动的位置然后触发相应的操作。
然后,该操作将从数据库中检索后面 20 个图像的 URL,并将 20 个图片的状态添加到 mutation 中然后显示。
本质上,Actions 创建一个请求数据的框架。它们使用一致的方法来应用异步方式中的数据。
最基本的抽象例子
在下面的例子中,展示了每个属性最基本的实现方式,因此你可以了解如何设置及使用。载荷是可选参数,可以通过它定义正在更新的组件的数值。不用担心,我们随后将演示一个实际案例,现在最重要的是了解基本概念。
`store.js`:
export const store = new Vuex.Store({state: {counter: 0},// 展示内容, 无法改变状态 getters: {tripleCounter: state => {return state.counter * 3;}},// 改变状态//mutations 永远是同步的 mutations: {// 显示传递的载荷 payload, 用 num 表示increment: (state, num) => {state.counter += num;}}, // 提交 mutation, 这是异步的 actions: {// 显示传递的载荷 payload, 用 asynchNum ( 一个对象 )表示asyncDecrement: ({ commit }, asyncNum) => {setTimeout(() => {// asyncNum 对象可以是静态值commit('decrement', asyncNum.by);}, asyncNum.duration);}} });
一个很好的功能是我们可以在 mutations 中返回整个状态对象,但是不必这样做,我们只使用我们需要的。时间穿梭测试(进入 mutations 中寻找错误)仍然可以工作。
在组件中,我们将对 getters 使用 computed
(这很重要,因为 value 值已经计算好了),在 methods
中使用 dispatch
来访问 mutations 和 actions:
`app.vue`:
computed: {value() {return this.$store.getters.value;} }, methods: {increment() {this.$store.dispatch('increment', 2)} }
或者,您可以使用扩展运算符。我发现如果需要大量 mutations/actions 的时候是非常有用的:
export default {// ... methods: {...mapActions(['increment', // 将 this.increment() 映射到 this.$store.commit('increment')'decrement','asyncIncrement'])} }
简单的实例
让我们再看一看天气通知的程序, 在它的 Vuex store 中有少量且简单的状态。这是示例代码的仓库.
See the Pen Vue Weather Notifier by Sarah Drasner (@sdras) on CodePen.
`store.js`:
import Vue from 'vue'; import Vuex from 'vuex';Vue.use(Vuex);export const store = new Vuex.Store({state: {showWeather: false,template: 0},mutations: {toggle: state => state.showWeather = !state.showWeather,updateTemplate: (state) => {state.showWeather = !state.showWeather;state.template = (state.template + 1) % 4;}} });
我们在这里设置了 showWeather
的状态,它的初始值为 false ,因为我们不希望任何动画立即执行,只有当用户点击按钮时才会执行。在 mutations 中,我们可以切换 showWeather
的状态。
我们也将状态中的 template
设置为 0 。我们会在每个天气组件中循环使用这个数字。所以在 mutations 中,我们创建了一个名为 updateTemplate
的方法。它会同时切换 showWeather
的状态并且更新 template
加 1 后的数值,但是值为 4 时再点击会变成 0 。
App.vue:
<template><div id="app">...<g id="phonebutton" @click="updateTemplate" v-if="!showWeather">...</g><transition @leave="leaveDroparea":css="false"><g v-if="showWeather"><app-droparea v-if="template === 1"></app-droparea><app-windarea v-else-if="template === 2"></app-windarea><app-rainbowarea v-else-if="template === 3"></app-rainbowarea><app-tornadoarea v-else></app-tornadoarea></g></transition>...</div> </template>
<script>import Dialog from './components/Dialog.vue';...export default {computed: {showWeather() {return this.$store.state.showWeather;},template() {return this.$store.state.template;}},methods: {updateTemplate() {this.$store.commit('updateTemplate');}},...components: {appDialog: Dialog,...} } </script>
`dialog.vue`:
<script> export default {computed: {template() {return this.$store.state.template;}},methods: {toggle() {this.$store.commit('toggle');}},mounted () {//enter weatherconst tl = new TimelineMax();...} } </script>
在上面的代码中,App 组件使用了 showWeather
依次展示模板, 而 Dialog 组件只切换组件的可见性。在 App.vue 中,我们根据 App <template>
中的模板数值,通过第一章学过的的条件渲染来展示以及隐藏不同的子组件。在 App 中, 我们通过 computed
数值监听 store 中状态的变化,使用 methods 中的 toggle()
和 updateTemplate()
提交 store 的 mutations 。
这是一个基本示例,但是你可以了解如何处理有大量状态的复杂程序,这有利于在在一个地方管理所有的状态,而不是上下移动组件。尤其当同胞组件之间通信的时候。
如果你想深入了解 Vuex , 可以看这篇 文档 。你肯能注意到我们在最后一个例子中使用了 <transition>
组件,还有大量动画。我们会在下一部分展开讨论。
转载于:https://www.cnblogs.com/nzbin/p/6380670.html
Vue.js 系列教程 4:Vuex相关推荐
- Vue.js 系列教程 3:Vue-cli,生命周期钩子
原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...
- Vue.js入门教程-组件注册
一.组件创建 1.1 创建步骤 创建Vue的组件都有三个基本步骤是 [①创建组件构造器.②注册组件和③使用组件]. 1.2 基本示例 比如,我们创建一个Button组件. // 1. 创建一个组件构造 ...
- 【D3.V3.js系列教程】--(十四)有路径的文字
[D3.V3.js系列教程]--(十四)有路径的文字 1. 在 svg 中插入一個 text // 在 body 中插入一個 svg var svg = d3.select('body').appen ...
- Vue.js入学教程
Vue.js是什么 Vue.js 是用于构建交互式的 Web 界面的库. Vue.js 提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单.灵活的 API. Vue.js(类似于view)是一 ...
- js系列教程5-数据结构和算法全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- js系列教程13-原型、原型链、作用链、闭包全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- js系列教程12-浏览器存储全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- js系列教程11-json、ajax(XMLHttpRequest)、comet、SSE、WebSocket全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- js系列教程10-canvas绘图全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
最新文章
- 电子白板 矢量 编码_当涉及白板编码采访时,请记住准备
- tomcat、腾讯云主机和微信
- 我发现一个新的软件,用自然语言编程!非常酷!
- 粒子群算法实例-求解函数极值
- Spring事务管理器分类
- 护理方面关于人工智能的构想_如何提出惊人的AI,ML或数据科学项目构想。
- mysql降级导入_mysql 升级和降级
- 聚焦技术和实践,腾讯全面揭秘基础设施和大数据演进之路
- vue如何强行停止ajax请求,VueJs和VueResource,从Ajax请求中删除头字段
- iOS面试总结(待完善)
- 安全基础知识 最强0到33600端口详解
- [译]R语言——Shiny框架之入门(二):如何构建一个Shiny应用
- SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解
- 时间插件--做到前几个月和后个几月的设置
- C语言编程中 提取运行时间的函数,C语言中用于修改文件的存取时间的函数使用...
- JZOJ5775 农夫约的假期
- 20191230每日一句
- 华为手机如何投屏到电脑
- 百度地图定位不准的问题
- 中文文字检测及识别(ORC)
热门文章
- 杨氏模量_快!准!狠!——5分钟搞定A-Level物理必考知识点杨氏模量曲线...
- python 元类的call_通过 python的 __call__ 函数与元类 实现单例模式
- android php 实时通信,Android_Android实现Activity之间通信的方法,本文实例讲述了Android实现Activi - phpStudy...
- 惠普服务器u盘系统安装win7系统教程,惠普星14笔记本U盘安装win7系统的操作教程...
- excel打开空白不显示内容 没有隐藏_办公软件操作技巧097:如何隐藏excel表格中没有数据的空白区域...
- React:创建用于获取数据的自定义Hook
- ref转发到DOM元素
- go json tag 字符串 整数_json:你或许还不知道的序列化操作(一)
- 1.两数之和-LeetCode
- epub 深入linux内核架构_深入分析Linux内核源代码6-Linux 内存管理(2)