做者:小土豆biubiubiujavascript
博客园:www.cnblogs.com/HouJiao/css
掘金:juejin.im/user/58c61b…html
简书:www.jianshu.com/u/cb1c3884e…前端
微信公众号:土豆妈的碎碎念(扫码关注,一块儿吸猫,一块儿听故事,一块儿学习前端技术) vue
欢迎你们扫描微信二维码进入群聊讨论(若二维码失效可添加微信JEmbrace拉你进群) ![]()
码字不易,点赞鼓励哟~java
Vuex
被称为是专为Vue
应用程序开发的的状态管理模式。它的做用使用一句话描述就是:让组件之间能够共享数据
。webpack
话很少少,先抛开概念,咱们写一个简单的示例感觉一波。web
Vuex
入门实践将分为三篇,本篇是第一篇。vuex
项目开发环境搭建请移步做者的另一篇文章 新手入门vue-教你使用vue-cli搭建项目开发环境。vue-cli
本次的项目目录以下:
使用Vuex
前须要先进行安装,安装命令:npm install vuex --save--dev
。
首先咱们先须要在E:\MyStudy\test\VueDemo\src\
目录下新建一个目录vuex
和文件store.js
。
接着在store.js
中使用Vuex
建立一个全局的共享数据。
// E:\MyStudy\test\VueDemo\src\vuex\store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 在state中建立一个全局共享的数据 counter
state: {
counter: 0
}
})
复制代码
能够看到使用Vuex
建立一个共享数据的语法也比较简单,即在new Vuex.Store
中定义state
对象,在state
对象中就能够建立全局的共享数据,本次咱们建立了一个counter
数据。
共享数据前面咱们已经建立好了,接着须要在入口文件main.js
中配置Vuex
,配置的步骤以下:
1.引入咱们编写的关于Vuex的代码模块store.js
2.在根实例上配置Vuex
复制代码
// E:\MyStudy\test\VueDemo\src\main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router/router'
//1.引入vuex
import store from './vuex/store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>',
router: router,
// 2.根实例上配置vuex
store: store
})
复制代码
前面咱们已经完成了两件事:使用Vuex
建立共享数据counter
和配置Vuex
。
接着咱们就须要在组件中访问这个共享数据counter
。
咱们先新建一个Index.vue
组件,在该组件中编写访问counter
的代码。
<!-- E:\MyStudy\test\VueDemo\src\components\Index.vue -->
<template>
<div>
<h1>这里是Index.vue组件</h1>
<h1>Index组件获取共享数据:{{ $store.state.counter }}</h1>
</div>
</template>
<script> export default { name: 'Index' } </script>
复制代码
访问共享数据counter
的代码为:
<h1>Index组件获取共享数据:{{ $store.state.counter }}</h1>
复制代码
接着在App.vue
中编写一样的代码访问这个counter
,而且在App.vue
组件中将Index.vue
组件引入并展现。
<!-- E:\MyStudy\test\VueDemo\src\App.vue -->
<template>
<div id="app">
<img src="./assets/logo.png">
<!-- 获取共享数据 -->
<h1>这里是App组件</h1>
<h1> App组件获取共享数据 : {{ $store.state.counter }} </h1>
<hr/>
<Index></Index>
</div>
</template>
<script> import Index from './components/Index' export default { name: 'App', components: { Index } } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
复制代码
咱们分别在App.vue
组件和Index.vue
组件中访问了共享数据counter
,如今咱们启动项目在浏览器中看下结果。
App
组件和
Index
组件都可以访问到
counter
的值。
到此,咱们简单的建立一个共享数据而且在组件中成功的访问到了这个共享数据,这里咱们对Vuex
的使用步骤作一个小总结:
1.安装vuex:npm install vuex
2.全局配置vuex:建立vuex实例,调用store方法配置在state中建立共享数据。
3.组件中使用$store.state.counter能够访问到共享数据
复制代码
Vuex
中,假如须要改变共享数据,必须在Vuex
实例对象的Store
方法中约定这个变化。
咱们在store.js
中对counter
作两个约束:递增
和递减
。
// E:\MyStudy\test\VueDemo\src\vuex\store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 在state中建立一个全局共享的数据 counter
state: {
counter: 0
},
mutations: {
// 递增
increase(state) {
state.counter++
},
// 递减
decrement(state) {
state.counter--
}
}
})
复制代码
mutations
中的increase
方法就是约定共享数据counter
每次递增1
;decrement
方法约定共享数据counter
每次递减1
。
约束共享数据的变化已经完成了,接着就开始触发这个变化从而使共享数据发生变化。
咱们在
App.vue
组件中触发counter递减
,在Index.vue
中触发counter递增
。
<!-- E:\MyStudy\test\VueDemo\src\App.vue -->
<template>
<div id="app">
<img src="./assets/logo.png">
<!-- 获取共享数据 -->
<h1>这里是App组件</h1>
<h1> App组件获取共享数据 : {{ $store.state.counter }} </h1>
<button v-on:click="$store.commit('decrement')">点击触发共享数据counter递减1</button>
<hr/>
<Index></Index>
</div>
</template>
<script> import Index from './components/Index' export default { name: 'App', components: { Index } } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
复制代码
<!-- E:\MyStudy\test\VueDemo\src\components\Index.vue -->
<template>
<div>
<h1>这里是Index.vue组件</h1>
<h1>Index组件获取共享数据:{{ $store.state.counter }}</h1>
<button v-on:click="$store.commit('increase')">点击该组件触发共享数据counter递增1</button>
</div>
</template>
<script> export default { name: 'Index' } </script>
复制代码
能够看到在组件中触发共享数据counter
递增和递减的逻辑分别为:$store.commit('increase')
和 $store.commit('decrement')
,
即便用$store.commit
方法并传递对应的函数名称
。
能够看到,点击App
组件中的按钮,成功的将counter
减1
,且Index
组件中的数据也自动更新;点击Index
组件中的按钮,成功的将counter
加1
,App
组件中的数据也自动更新。
假设咱们前面的递增递减的需求变成:点击按钮后,过3
秒再去修改counter
的值。那么这个时候应该怎么实现呢?
咱们直接上代码。
// E:\MyStudy\test\VueDemo\src\vuex\store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 在state中建立一个全局共享的数据 counter
state: {
counter: 0
},
mutations: {
// 递增
increase(state) {
state.counter++
},
// 递减
decrement(state) {
state.counter--
}
},
actions: {
increaseAction(context){
setTimeout(function(){
context.commit('increase')
}, 3000);
},
decrementAction(context){
setTimeout(function(){
context.commit('decrement')
}, 3000);
}
}
})
复制代码
在store.js
中,咱们把异步修改数据的逻辑定义在actions
中,而且经过提交mutations
改变共享数据的状态。
那在组件中须要使用$store.dispatch
对应去触发共享数据的改变。
下面咱们看一下组件中如何使用$store.dispatch
。
<!-- E:\MyStudy\test\VueDemo\src\App.vue  -->
<template>
<div id="app">
<img src="./assets/logo.png">
<!-- 获取共享数据 -->
<h1>这里是App组件</h1>
<h1> App组件获取共享数据 : {{ $store.state.counter }} </h1>
<button v-on:click="$store.dispatch('decrement')">点击等待3秒触发共享数据counter递减1</button>
<hr/>
<Index></Index>
</div>
</template>
<script> import Index from './components/Index' export default { name: 'App', components: { Index } } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
复制代码
<!-- E:\MyStudy\test\VueDemo\src\components\Index.vue -->
<template>
<div>
<h1>这里是Index.vue组件</h1>
<h1>Index组件获取共享数据:{{ $store.state.counter }}</h1>
<button v-on:click="$store.dispatch('increase')">点击等待3秒触发共享数据counter递增1</button>
</div>
</template>
<script> export default { name: 'Index' } </script>
复制代码
最后,咱们在浏览器看下效果。
能够看到,setTimeout
这个异步逻辑成功执行。
关于上面想要实现的异步
递增和递减,咱们的第一反应可能就是在mutations
中的递增递减函数添setTimeout
延迟执行函数,咱们来实践一下。
App.vue
和Index.vue
不作任何修改,仍是前面的内容,只修改store.js
。
// E:\MyStudy\test\VueDemo\src\vuex\store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 在state中建立一个全局共享的数据 counter
state: {
counter: 0
},
mutations: {
// 递增
increase(state) {
// 添加定时器执行
setTimeout(function(){
state.counter++
},3000);
},
// 递减
decrement(state) {
//添加定时器
setTimeout(function(){
state.counter--
},3000);
}
}
})
复制代码
浏览器看下结果:
能够看到效果和actions
同样!!!
没办法,我这人就是想多造做造做给你们看点不同的东西。
那对于mutations
官网确实有明确的说明,mutations
必须是同步函数。
mutations
必须是同步函数了。
缘由一:若是是异步函数,在触发mutations的时候,浏览器的调试功能看不到数据的变化;
缘由二:mutations中异步函数中的数据变化没法追踪。
复制代码
到这里呢,咱们就不继续往下探究了,由于基础的尚未总结完,基础总结完后在探究这个问题。
vue
组件中的计算属性想必你们都知道,那么Vuex
中共享数据的计算属性的用途和原理也是同vue
组件中的计算属性。
咱们假设vue
组件中须要对共享数据作一些其余的转换:将某个字符串进行翻转,而且转为大写。(这个场景项目中几乎不会用到,仅仅为了演示而编造的)。当多个组件都须要对某个共享数据作这样的转化时,想必写起来也会比较繁琐,所以Vuex
共享数据的计算属性就帮了咱们解决这个问题。下面咱们使用Vuex
的共享数据的计算属性来实现这个需求。
// E:\MyStudy\test\VueDemo\src\vuex\store.js
// 在该文件中已经将前面定义的counter删除,从新定义了一个共享数据str
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 在state中建立一个全局共享的数据 str
state: {
str: 'hello'
},
getters: {
reverseAndToUpper(state){
return state.str.split("").reverse().join("");
}
}
})
复制代码
关于共享数据的计算属性的访问,咱们只在App组件
中添加访问代码。
<!-- E:\MyStudy\test\VueDemo\src\App.vue -->
<!-- 在App组件中,将Index组件的引入代码已经删除 -->
<template>
<div id="app">
<img src="./assets/logo.png">
<!-- 获取共享数据 -->
<h1>这里是App组件</h1>
<h1> App组件获取共享数据 : {{ $store.getters.reverseAndToUpper }} </h1>
</div>
</template>
<script> import Index from './components/Index' export default { name: 'App', components: { Index } } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
复制代码
浏览器查看一下结果:
能够看到,在App组件
中已经成功的访问到了str
的计算属性。
前面咱们一共实践了Vuex
的这些内容:
1.在state中定义共享属性,在组件中可以使用$store.state.属性名访问共享属性。
2.在mutations可中定义修改共享数据的方法,在组件中可以使用$store.commit('方法名')同步修改共享属性。
3.在actions中可定义异步修改共享数据的方法,在组件中可以使用$store.dispatch('方法名')异步修改共享属性。
4.在getters中可定义共享数据的计算属性,在组件中可以使用$store.getters.计算属性名访问共享数据的计算属性。
复制代码
那最后我在将文章最开始的图拿过来。
根据咱们前面实践的内容,你们能看懂这个状态变化吗?
做者:小土豆biubiubiu
简书:www.jianshu.com/u/cb1c3884e…
微信公众号:土豆妈的碎碎念(扫码关注,一块儿吸猫,一块儿听故事,一块儿学习前端技术)
欢迎你们扫描微信二维码进入群聊讨论(若二维码失效可添加微信JEmbrace拉你进群) ![]()
码字不易,点赞鼓励哟~