vuex入门

来源:互联网 发布:昆明理工大学教育网络 编辑:程序博客网 时间:2024/06/07 06:07

        在vue开发中,如果你的项目比较简单的话,在设计数据的状态、存储和操作的时候可以通过将数据存入到data中,通过eventBus的方式将数据发送出去,通过一堆methods来写关于这个操作的一些方法。但是如果到大型的项目开发中,如果通过这样子的方法去搞开发可以说不光打的代码多,而且代码的重用性非常的差,写代码会写的很繁琐。所以这个时候就应该用我们vue官方推荐的一个vuex来优化我们的模块设计。首先我们来看一下官方关于vuex的概念图:


        在这幅图中,state表示的是数据的存储状态,当你打开一个页面的时候,数据从后端获取并在浏览器那里加载完成后,一项关键的数据就会存入到state中,以供你以后操作的时候改变到state的变量时使视图发生相应的改变。components就是组件,components中通过vuex自带的一个mapGetters方法来获取state中相应的数据,从而渲染到components中,进而使整个视图层发生相应的改变。而actions就是对用户的操作进行反应,当用户点击一个按钮的时候,会触发这个按钮相应的方法,这个方法在actions中通过commit也就是提交,提交给mutaions让他去做处理,mutaions中通过在里面写业务的逻辑使得state中相应的对象属性发生改变,也只能有这条路才能让state发生改变,如果是通过对象的方式如用‘$store.state.属性=某个值‘来改变state的值都是非法的,官方不推荐,虽然可行,但是会乱了逻辑。接下来我就用一个简单的demo来实现上述的过程。

        在本次demo中,为了让新手简单了解起见,我没像官方那样用多个js文件来管理各个模块,我将整个vuex的流程都写入一个store.js的文件中。下面一个是能通过点击按钮进行流加减的程序流程。

        首先肯定是创建一个vue项目,用指令来初始化一个vue-cli:

vue init webpack haha
        然后安装后npm的依赖:

npm install
        然后运行看看有没有问题:

npm run dev
        没有问题后安装vuex:

npm install vuex
        我们在src目录下新建一个store.js文件,里面写关于我们的vuex逻辑的代码:


        在main.js中我们要把store.js文件import进来,然后挂着在new Vue中:

import Vue from 'vue'import App from './App'import store from './store'Vue.config.productionTip = false/* eslint-disable no-new */new Vue({  el: '#app',  store,  render: h => h(App)})
        然后在store.js中引入vue和vuex,并且要在vue中使用vuex:

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)
        这个Vue.use()方法必不可少,因为vuex是插件,如果没有了这个方法去把vuex引入到vue中,则后面写的代码都无效。在这个store.js中,肯定会有我刚刚提到的state、actions、mutations和getters的,写法如下:

var state = {  }const actions = {  }const mutations = {  }const getters = {  }
        通常state变量是页面一开始加载的时候通过ajax等异步方法获取到的后台数据就放在state中,getters就是将state里的某些属性给到components那里进行渲染,actions是用户点击一个按钮触发一个方法时就要经过这个actions,actions里面通过commit让mutaions执行相应的方法,只有mutations才能改state!然后这四个变量和常量要导出去,通过Vuex.Store来导出去:

export default new Vuex.Store({  actions,  getters,  mutations,  state})
        在App.vue文件的template中,我是这样写的:

<template>  <div id="app">    <h3>简单计数器</h3>    <button @click="increment">+1</button>    <button @click="decrement">-1</button>    <div>now is {{count}}</div>  </div></template>
        这里有两个按钮,两个按钮对应着两个方法,一个是加1,另一个是减1,那么我们该如何实现呢?首先我们在下面的script中先引入vuex中的两个有用的方法:mapGetters和mapActions,这是vuex提供给我们的语法糖,通过你按照传统的方式写的话在methods里面写increment和decrement方法的实现,但是这里是vuex!这里有vuex自己的规则。在这里我们的methods是这样写的:

<script>import {mapGetters, mapActions} from 'vuex'export default {  name: 'app',  methods: mapActions([    'increment',    'decrement'  ]),  computed: mapGetters([    'count'  ])}</script>
        在mapActions中通过传入一个数组,里面有上面对应的两个方法名,传给store.js文件中进行处理。而我们想获取的参数count,通过计算属性computed里写入一个mapGetters方法,在该方法里传入count,就会在store.js方法里面进行处理,在store.js方法中通过getters返回该数值回来。下面我们就回到store.js,看看里面相应的变量和常量是如何写的。

        首先state里我们在里面设立一个属性,这个为count的原始值:

var state = {  count: 10}
        当用户点击按钮的时候,在actions中与之对应的方法就会commit该方法名给mutations,让mutations进行处理;

const actions = {  increment: ({commit}) => {    commit('increment')  },  decrement: ({commit}) => {    commit('decrement')  }}const mutations = {  increment: (state) => {    state.count++  },  decrement: (state) => {    state.count--  }}
        最后,当App.vue组件想要获取count的数值的时候,需要在getters里面返回:

const getters = {  count: (state) => {    return state.count  }}
        题外话。有同学说我可以不用按照官方的来做,比如下面这样做也可以达到相应的效果:

<script>// import {mapGetters, mapActions} from 'vuex'export default {  name: 'app',//  methods: mapActions([//    'increment',//    'decrement'//  ]),//  computed: mapGetters([//    'count'//  ])  data () {    return {      a: this.$store.state.count    }  },  methods: {    increment () {      this.a += 1    },    decrement () {      this.a -= 1    }  }}</script>
        在store.js文件中只需要state就可以了,看起来好像很简单啊。但是到需求量变的很大的时候,你这个方法无疑是搬起石头砸自己的脚。关键是这个不符合官方的规范!这个东西我已经在整篇文章提了三次,这个重要的东西值得说三次!

在官方那里除了我所提到的state、mutaions、actions、getters之外,还有一个modules。modules的功能就是分模块,在modules里面可以有state、mutaions、actions、getters,如果我们只是用那四个不用modules的话那么那四个相当于全局性的。在官方里modules的用法如下:

const moduleA = {  state: { ... },  mutations: { ... },  actions: { ... },  getters: { ... }}const moduleB = {  state: { ... },  mutations: { ... },  actions: { ... }}const store = new Vuex.Store({  modules: {    a: moduleA,    b: moduleB  }})store.state.a // -> moduleA 的状态store.state.b // -> moduleB 的状态
        那么我们如何利用这个modules来改写我们刚刚写的代码呢?跟着我一步一步来。

const moduleA = {  state: {    count: 10  },  actions: {    increment: ({commit}) => {      commit('increment')    },    decrement: ({commit}) => {      commit('decrement')    }  },  mutations: {    increment: (state) => {      state.count++    },    decrement: (state) => {      state.count--    }  },  getters: {    count: (state) => {      return state.count    }  }}export default new Vuex.Store({  modules: {    a: moduleA  }})
        仿照官方那样,记住一定要export导出去,不然App.vue那里就不能import了。还要提的一点是,当你要执行异步操作的时候,是在actions里面进行的而不是在mutaions里面。如果在mutaions里面执行异步操作的话会使整个逻辑比较乱。具体更多的细节请参考官方文档。



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玉米出芽后土壤不够湿怎么办 雨伞请输入授权码怎么办 网页放手机端后看不了怎么办 微信收款码存在违法行为怎么办 tst优惠码密码忘了怎么办 扩展器登录不上怎么办 微信学法小程序积分不更新怎么办 开发商不给办房产证怎么办 传淘宝产品规格不匹配怎么办 刚买的手机想退怎么办 空调主机空间不足不散热怎么办 lol网速快延迟高怎么办 4g手机延迟高怎么办 天气冷鼻炎就犯怎么办 天气冷宝宝发烧了怎么办 wp手机开机忘记了密码怎么办 微商退货不退款怎么办 微商退货了不退款怎么办 微商退货后不退款怎么办 有赞买东西付款没发货怎么办 赞礼号掉了东西怎么办 万达贷系统维护还不了款怎么办 qq文件发不出去怎么办 1688分销没有传淘宝怎么办 京东的货运代理怎么办 天天练推广期没了怎么办 微信自动建群怎么办 刚刚不小心扫了无痕爆客怎么办 苹果6升级卡死怎么办 随行付换手机了怎么办 融e联账号冻结怎么办 58同城高危账户怎么办 网购迟迟不发货怎么办 优酷不能投屏了怎么办 爱尚街借款不还怎么办 小米商城买东西没收到货怎么办 微信投票地区限制怎么办 微信退款未到账怎么办 微信钱包锁忘了怎么办 xp系统管理员密码忘了怎么办 沃尔沃menu键没反应怎么办