vue.js vuex
Vuex简介 (Introduction to Vuex)
Vuex is the official state management library for Vue.js.
Vuex是Vue.js的官方状态管理库。
Its job is to share data across the components of your application.
它的工作是在应用程序的各个组件之间共享数据。
Components in Vue.js out of the box can communicate using
开箱即用的Vue.js中的组件可以使用
props, to pass state down to child components from a parent
props ,将状态从父级传递到子级组件
events, to change the state of a parent component from a child, or using the root component as an event bus
events ,从子级更改父组件的状态,或将根组件用作事件总线
Sometimes things get more complex than what these simple options allow.
有时候事情变得比这些简单的选项所允许的更为复杂。
In this case, a good option is to centralize the state in a single store. This is what Vuex does.
在这种情况下,一个好的选择是将状态集中在一个存储中。 这就是Vuex所做的。
为什么要使用Vuex (Why should you use Vuex)
Vuex is not the only state management option you can use in Vue (you can use Redux too), but its main advantage is that it’s official, and its integration with Vue.js is what makes it shine.
Vuex不是您可以在Vue中使用的唯一状态管理选项(您也可以使用Redux ),但是它的主要优点是它是官方的,并且与Vue.js的集成才使它发光。
With React you have the trouble of having to choose one of the many libraries available, as the ecosystem is huge and has no de-facto standard. Lately Redux was the most popular choice, with MobX following up in terms of popularity. With Vue I’d go as far as to say that you won’t need to look around for anything other than Vuex, especially when starting out.
使用React,您将不得不选择众多可用库之一,因为该生态系统庞大且没有实际标准。 最近,Redux是最受欢迎的选择,MobX在人气方面紧随其后。 有了Vue,我想说的就是,除了Vuex之外,您无需四处寻找其他东西,尤其是在入门时。
Vuex borrowed many of its ideas from the React ecosystem, as this is the Flux pattern popularized by Redux.
Vuex从React生态系统中借鉴了许多想法,因为这是Redux流行的Flux模式。
If you know Flux or Redux already, Vuex will be very familiar. If you don’t, no problem - I’ll explain every concept from the ground up.
如果您已经了解Flux或Redux,那么Vuex将非常熟悉。 如果不这样做,那就没问题-我将彻底解释每个概念。
Components in a Vue application can have their own state. For example, an input box will store the data entered into it locally. This is perfectly fine, and components can have local state even when using Vuex.
Vue应用程序中的组件可以具有自己的状态。 例如,一个输入框将在本地存储输入到其中的数据。 这非常好,即使使用Vuex,组件也可以具有局部状态。
You know that you need something like Vuex when you start doing a lot of work to pass a piece of state around.
您知道开始做大量工作来传递状态时需要Vuex之类的东西。
In this case Vuex provides a central repository store for the state, and you mutate the state by asking the store to do that.
在这种情况下,Vuex为状态提供了一个中央存储库,您可以通过请求状态来对状态进行更改。
Every component that depends on a particular piece of the state will access it using a getter on the store, which makes sure it’s updated as soon as that thing changes.
依赖于状态的特定部分的每个组件都将使用商店中的getter来访问它,以确保在状态发生变化时立即对其进行更新。
Using Vuex will introduce some complexity into the application, as things need to be set up in a certain way to work correctly, but if this helps solve the unorganized props passing and event system that might grow into a spaghetti mess if too complicated, then it’s a good choice.
使用Vuex会给应用程序带来一些复杂性,因为需要以某种特定的方式进行设置才能正常工作,但是如果这有助于解决无组织的道具传递和事件系统(如果过于复杂则可能会变成意大利面条),那么一个不错的选择。
开始吧 (Let’s start)
In this example I’m starting from a Vue CLI application. Vuex can be used also by directly loading it into a script tag, but since Vuex is more in tune with bigger applications, it’s much more likely you will use it on a more structured application, like the ones you can start up quickly with the Vue CLI.
在此示例中,我从Vue CLI应用程序开始。 也可以通过直接将Vuex加载到脚本标签中来使用Vuex,但是由于Vuex更适合大型应用程序,因此您更有可能在结构化的应用程序上使用它,例如可以通过Vue快速启动的应用程序。 CLI。
The examples I use will be put CodeSandbox, which is a great service that has a Vue CLI sample ready to go at https://codesandbox.io/s/vue. I recommend using it to play around.
我将使用的示例放在CodeSandbox上,它是一项很棒的服务,具有准备在https://codesandbox.io/s/vue上的Vue CLI示例。 我建议使用它来玩耍。
Once you’re there, click the Add dependency button, enter “vuex” and click it.
到达后,单击“ 添加依赖项”按钮,输入“ vuex”,然后单击它。
Now Vuex will be listed in the project dependencies.
现在,Vuex将列在项目依赖项中。
To install Vuex locally you can run npm install vuex
or yarn add vuex
inside the project folder.
要在本地安装Vuex,可以运行npm install vuex
或yarn add vuex
在项目文件夹中yarn add vuex
。
创建Vuex商店 (Create the Vuex store)
Now we are ready to create our Vuex store.
现在,我们准备创建Vuex商店。
This file can be put anywhere. It’s generally suggested to put it in the src/store/store.js
file, so we’ll do that.
该文件可以放在任何地方。 通常建议将其放在src/store/store.js
文件中,因此我们将这样做。
In this file we initialize Vuex and we tell Vue to use it:
在此文件中,我们初始化Vuex并告诉Vue使用它:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({})
We export a Vuex store object, which we create using the Vuex.Store()
API.
我们导出使用Vuex.Store()
API创建的Vuex存储对象。
商店的用例 (A use case for the store)
Now that we have a skeleton in place, let’s come up with an idea for a good use case for Vuex, so I can introduce its concepts.
现在我们已经有了一个框架,让我们提出一个关于Vuex的好用例的想法,以便我介绍它的概念。
For example, I have 2 sibling components, one with an input field, and one that prints that input field content.
例如,我有2个同级组件,一个带有一个输入字段,另一个打印该输入字段的内容。
When the input field is changed, I want to also change the content in that second component. Very simple but this will do the job for us.
当输入字段更改时,我还要更改第二个组件中的内容。 很简单,但这将为我们完成工作。
介绍我们需要的新组件 (Introducing the new components we need)
I delete the HelloWorld component and add a Form component, and a Display component.
我删除HelloWorld组件,并添加一个Form组件和一个Display组件。
<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input name="flavor">
</div>
</template>
<template>
<div>
<p>You chose ???</p>
</div>
</template>
将这些组件添加到应用程序 (Adding those components to the app)
We add them to the App.vue code instead of the HelloWorld component:
我们将它们添加到App.vue代码而不是HelloWorld组件中:
<template>
<div id="app">
<Form/>
<Display/>
</div>
</template>
<script>
import Form from './components/Form'
import Display from './components/Display'
export default {
name: 'App',
components: {
Form,
Display
}
}
</script>
将状态添加到商店 (Add the state to the store)
So with this in place, we go back to the store.js file and we add a property to the store called state
, which is an object, that contains the flavor
property. That’s an empty string initially.
因此,将其放置到位后,我们返回到store.js文件,并向商店添加一个名为state
的属性,该属性是一个对象,其中包含flavor
属性。 最初是一个空字符串。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
}
})
We’ll update it when the user types into the input field.
当用户在输入字段中键入内容时,我们将对其进行更新。
添加突变 (Add a mutation)
The state cannot be manipulated except by using mutations. We set up one mutation which will be used inside the Form component to notify the store that the state should change.
除非使用突变,否则无法操纵状态。 我们设置了一个突变,该突变将在Form组件内部用于通知商店状态应该更改。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
}
})
添加获取器以引用状态属性 (Add a getter to reference a state property)
With that set, we need to add a way to look at the state. We do so using getters. We set up a getter for the flavor
property:
设置好之后,我们需要添加一种查看状态的方法。 我们使用吸气剂来做到这一点。 我们为flavor
属性设置了一个吸气剂:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
},
getters: {
flavor: state => state.flavor
}
})
Notice how getters
is an object. flavor
is a property of this object, which accepts the state as the parameter, and returns the flavor
property of the state.
请注意, getters
是如何成为对象的。 flavor
是此对象的属性,它接受状态作为参数,并返回状态的flavor
属性。
将Vuex商店添加到应用程序 (Adding the Vuex store to the app)
Now the store is ready to be used. We go back to our application code, and in the main.js file, we need to import the state and make it available in our Vue app.
现在该商店已准备就绪,可以使用。 我们回到应用程序代码,在main.js文件中,我们需要导入状态并将其在我们的Vue应用程序中可用。
We add
我们增加
import { store } from './store/store'
and we add it to the Vue application:
并将其添加到Vue应用程序中:
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})
Once we add this, since this is the main Vue component, the store
variable inside every Vue component will point to the Vuex store.
一旦添加它,由于这是主要的Vue组件,每个Vue组件内的store
变量都将指向Vuex商店。
使用提交更新用户操作的状态 (Update the state on a user action using commit)
Let’s update the state when the user types something.
让我们在用户键入内容时更新状态。
We do so by using the store.commit()
API.
我们通过使用store.commit()
API来实现。
But first, let’s create a method that is invoked when the input content changes. We use @input
rather than @change
because the latter is only triggered when the focus is moved away from the input box, while @input
is called on every keypress.
但是首先,让我们创建一个在输入内容更改时调用的方法。 我们使用@input
而不是@change
因为后者仅在焦点从输入框移开时触发,而@input
在每次按键时都被调用。
<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input @input="changed" name="flavor">
</div>
</template>
<script>
export default {
methods: {
changed: function(event) {
alert(event.target.value)
}
}
}
</script>
Now that we have the value of the flavor, we use the Vuex API:
现在我们有了风味的价值,我们使用Vuex API:
<script>
export default {
methods: {
changed: function(event) {
this.$store.commit('change', event.target.value)
}
}
}
</script>
see how we reference the store using this.$store
? This is thanks to the inclusion of the store object in the main Vue component initialization.
看看我们如何使用this.$store
引用this.$store
? 这是由于在主Vue组件初始化中包含了存储对象。
The commit()
method accepts a mutation name (we used change
in the Vuex store) and a payload, which will be passed to the mutation as the second parameter of its callback function.
commit()
方法接受一个突变名称(我们在Vuex存储中使用了change
)和一个有效负载,这些负载将作为其回调函数的第二个参数传递给该突变。
使用吸气剂打印状态值 (Use the getter to print the state value)
Now we need to reference the getter of this value in the Display template, by using $store.getters.flavor
. this
can be removed because we’re in the template, and this
is implicit.
现在,我们需要使用$store.getters.flavor
在Display模板中引用此值的getter。 this
可以去掉,因为我们在模板, this
是隐含的。
<template>
<div>
<p>You chose {{ $store.getters.flavor }}</p>
</div>
</template>
结语 (Wrapping up)
That’s it for an introduction to Vuex!
就是对Vuex的介绍!
The full, working source code is available at https://codesandbox.io/s/zq7k7nkzkm
完整且有效的源代码可从https://codesandbox.io/s/zq7k7nkzkm获得
There are still many concepts missing in this puzzle:
这个难题中仍然缺少许多概念:
- actions 行动
- modules 模组
- helpers 帮手
- plugins 外挂程式
but you have the basics to go and read about them in the official docs.
但是您有一些基础知识可以在官方文档中阅读。
Happy coding!
编码愉快!
vue.js vuex