vue项目分析--Vuex


https://vuex.vuejs.org/zh/installation.html

安装

在引入vue之后直接引入vuex可以直接安装

<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

如果不使用全局的script标签引用的话
也可以使用npm

npm install vuex --save

在模块化的打包系统里,需要显式的通过Vue.use()安装vuex

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

Vuex 依赖 Promise (opens new window)。如果你支持的浏览器并没有实现 Promise (比如 IE),那么你可以使用一个 polyfill 的库,例如 es6-promise (opens new window)。
你可以通过 CDN 将其引入:

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>

然后 window.Promise 会自动可用。

开始使用

每一个vuex应用的核心是store,包含着应用里大部分状态,vuex的状态存储是响应式的,vue组件从store里读取状态的时候,状态一旦变化,组件也相应更新
不能直接改变store里的状态,唯一途径就是显式地提交(commit)mutation(改变)
开始创建一个store
(只需要提供一个初始state对象和一些mutation)
比如创建了一个state里一个count参数
在mutations里定义一个自增函数,里面传入state,对state里的count进行操作

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

之后在外面使用commit调用mutations里的increment方法

store.commit('increment')

获取store里的state里的参数

console.log(store.state.count) 

为了在vue组件里能访问,需要在new vue根组件的时候用store选项的方式注入store机制

new Vue({
  el: '#app',
  store: store,
})

如果使用ES6标准的话可以使用ES6对象的property 简写 (用在对象某个 property 的 key 和被传入的变量同名时):

new Vue({
  el: '#app',
  store
})

之后就可以从组件的方法里提交变更
比如在method里把上面两句话封装成一个局部方法

methods: {
  increment() {
    this.$store.commit('increment')
    console.log(this.$store.state.count)
  }
}

提交mutation的方式不是直接改变store.state里的参数,而是利用mutations里的方法改变可以更明确的追踪到状态的变化,阅读代码的时候也可以感受到应用内部的状态改变,能实现一些记录每次状态变化,保存状态快照的调试工具
由于store里的状态是响应式的,所以在组件里调用store里的状态只需要在计算属性里返回,触发变化也仅仅是在组件的 methods 中提交 mutation。

state

vuex使用单一状态树,一个对象包含所有应用层的级状态,所以作为一个为唯一数据源存在,一个应用就包含这一个store实例,这个单一的状态树可以直接定位任意一个特定的状态片段,而且调试过程能轻易取得整个当前应用状态的快照
(单一状态树依然可以模块化–本项目就是把状态和状态变更事件分布到了各个子模块里)
在vue组件里获得vuex状态

存储在vuex里的数据和vue实例里的data状态对象都必须是纯粹的(含有零个或多个的 key/value 对)
从store实例里读取状态最简单的方法是在计算属性里返回某个状态
比如创建一个counter组件,模板里引用count方法,computed里的count方法里返回store里的count参数

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

这样每次store里的变化的时候都会重新求计算属性之后更新相关的dom

这种模式导致组件依赖全局状态单例,在模块化的构建系统里,组件会频繁的导入,而且在测试组件的时候需要模拟状态
vuex通过store选项提供了一种把状态从根组件注入到每一个子组件的方式(需调用 Vue.use(Vuex)):

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

在根组件里把store引入之后,component里注册的所有组件就都可以使用this.$store访问store里的参数和方法了

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

mapstate辅助函数可以在一个组件获取多个状态的时候帮助生成计算属性(减少代码冗余)
mapstate函数返回的是一个对象,如何把它和局部计算属性混合使用?
可以使用一个工具函数把多个对象合并成一个,把最终对象传给computed属性(可以使用对象展开运算符简化写法)

Getter属性

有时候会从store里的state里派生出来一些状态,例如对列表进行过滤并计数:

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

如果多个组件需要用到这个属性,比较麻烦
vuex可以在store里定义getter计算属性,其返回值会根据其依赖被缓存起来,只有它的依赖值发生变化才会重新计算,取代在子组件里定义的方法
Getter 接受 state 作为其第一个参数:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

getter使用store.getters的方式访问
getter也可以接受其他 getter 作为第二个参数:

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}
store.getters.doneTodosCount // -> 1

在其他组件里使用

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

Mutations

处理同步事务

Actions

处理异步事务

=>箭头函数

https://www.cnblogs.com/liyuanhong/articles/10139214.html
=>是ES6的新增的箭头函数

x => x * x

相当于

function (x) {
    return x * x;
}

箭头函数就相当于一个匿名函数,并且简化了函数的定义,还可以包含多条语句

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

如果匿名函数的参数布不止一个,可以使用()包含起来

// 两个参数:
(x, y) => x * x + y * y

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

箭头函数与匿名函数的区别
箭头函数内部的this是词法作用域由上下文决定

分析一下项目的store文件夹

一个index.js文件和getter.js文件以及modules文件夹
index.js
是先引入了vue和vuex之后把modules里的各个js文件作为模块引入到新建的vuex的store实例里,还引入了getter.js文件
在这里插入图片描述
可以看到里面是没有state和mutations的,只有modules,关于引入的其他js文件export的接口变量里比如app.js
在这里插入图片描述
里面是有state和mutations的,所以这种方式是模块化子store,引用的时候可以看一下getter.js文件
在这里插入图片描述
所有的子模块里的state里的参数都使用state引用,相当于都是index.js里的vuex.store实例的state

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值