关于vue.js:Vuex

77次阅读

共计 3922 个字符,预计需要花费 10 分钟才能阅读完成。

一、简介
Vuex 是服务于 Vue.js 应用程序的状态管理模式。
vue 状态治理分为三局部

  • state, 驱动利用的数据源
  • view, 以申明形式将 state 映射到视图
  • actions, 响应在 view 上的用户输出导致的状态变动

vuex 的设计思维:在多个组件共享状态时,将该共享状态抽离进去以一个全局单例模式治理。通过定义和隔离状态治理中的各种概念,并通过强制规定维持视图和状态间的独立性,让代码变得更结构化且易保护。


二、装置
npm 装置

npm install vuex --save

在模块化的打包零碎中,通过 Vue.use()装置 vuex
(当通过全局 script 标签援用 Vuex 时,不须要应用 Vue.use()装置)

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

Vue.use(Vuex)

三、Store 与 State
每一个 Vuex 利用的外围就是 store 仓库,store 是一个容器,蕴含利用中大部分的 state。
Vuex 与单纯的全局对象的区别:
1、Vuex 状态存储是响应式的,当 vue 组件从 store 中读取 state 时,若 state 发生变化,则相应的组件也会相应地失去高效更新。
2、不能间接扭转 store 中的 state,扭转的惟一路径就是 commit mutation。能够更不便跟踪每一个状态的变动。

应用 new Vuex.Store()创立 store

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

/* 装置 Vuex*/
Vue.use(Vuex)

// 创立一个 store 实例
const store = new Vuex.Store({
  state: {count: 0},
  mutations: {increment(state) {state.count++}
  }
})
// 创立一个组件实例,读取 state,批改 state
const Counter = {
  template: `<div>
  <div class="btn" @click='add'> 减少 </div>
  {{count}}</div>`,
  computed: {
    // 将 state 定义为计算属性
    count() {
      // return store.state.count

      // 在根实例 vm 中注册 store 当前,所有子组件都能通过 this.$store 拜访到 state
      return this.$store.state.count
    }
  },
  methods: {add() {
      // 批改 state 必须提交一个 commit
      // store.commit('increment')

      // 在根实例 vm 中注册 store 当前,所有子组件都能通过 this.$store 拜访到 state
      this.$store.commit('increment')
    }
  }
}
// 创立一个 vue 实例,提供一个创立好的 store
let vm = new Vue({
  el: '#app',
  store, // 把 store 对象提供给‘store’选项,能够把 store 的实例注入所有子组件中
  components: {Counter}
})

mapState 获取多个状态
当一个组件须要获取多个状态时,将这些状态都申明为计算属性会有些反复和冗余,可应用 mapState 辅助函数帮忙咱们生成计算属性。

// 引入 mapState
//import {mapState} from 'vuex'
const mapState = Vuex.mapState

const store = new Vuex.Store({
  state: {
    count: 0,
    isLogin: true,
    user: {
      username: 'Liane',
      id: '1',
      gender: 'female'
    }
  },
  mutations: {increment(state) {state.count++}
  }
})

const Counter = {
  template: `<div>
        <div class="btn" @click='add'> 减少 </div>
        <div>{{count}}</div>
        <div>{{user.username}}</div>
        <div>{{user.id}}</div>
        </div>`,
  // 应用 mapState()辅助函数
  computed: mapState({// count() {
    //   return this.$store.state.count
    // }
    //count 可简化如下
    count: state => state.count,
    isLogin: state => state.isLogin,
    user: state => state.user
  }),
  methods: {add() {this.$store.commit('increment')
    }
  }
}
let vm = new Vue({
  el: '#app',
  store,
  components: {Counter}
})

当映射的计算属性名称与 state 的子节点名称雷同时,也能够给 mapState()传递一个字符串数组

computed: mapState([
  'count',
  'isLogin', 
  'user'
])

通常咱们应用扩大运算符将须要用到的 state 通过 mapState 与组件的计算属性混合

computed:{
  ...mapState([
    'count',
    'isLogin',
    'user'
  ])
}

四、Getter
当咱们须要 store 中的某些 state 派生出一些状态时,能够应用 Getter,getter 就像是 store 中的计算属性一样,会依据它的依赖被缓存起来,依赖一旦产生扭转,就会从新计算。

// 定义一个 store 存储代办事项的状态
const store = new Vuex.Store({
  state: {
    todos: [{ id: 1, text: 'study', done: true},
      {id: 2, text: 'exercise', done: true},
      {id: 3, text: 'painting', done: false}
    ]
  },
  getters: {
    // 失去已实现的事项
    doneTodos: state => {return state.todos.filter(todo => todo.done)
    },
    // 失去已实现的事件个数
    doneTodosCount: (state, getters) => {return getters.doneTodos.length}
  }
})
const Counter = {
  template: `<div>
    <span> 已实现 {{doneTodosCount}} 件代办事项 </span>
    <ul>
      <li v-for="item in doneTodos">
        {{item.text}}
      </li>
    </ul>
  </div>`,
  computed: {doneTodos() {return this.$store.getters.doneTodos},
    doneTodosCount() {return this.$store.getters.doneTodosCount}
  }
}
let vm = new Vue({
  el: '#app',
  store,
  components: {Counter}
})

mapGetter 辅助函数

computed: {
  ...mapGetter([
    'doneTodos',
    'doneTodosCount'
  ])
}

若想将 getter 属性另取名字,可应用对象模式

computed:{
  ...mapGetter({doneCount: 'doneTodosCount'})
}

五、Mutations
更改 store 中属性的惟一办法就是 commit 一个 mutation。
vuex 中的 mutation 相似事件,每个 mutation 都有一个字符串的事件类型(type)和一个回调函数(handler)

const mapState = Vuex.mapState
const store = new Vuex.Store({
  state: {
    isLogin: false,
    user: {}},
  mutations: {setLogin(state, val) {state.isLogin = val},
    setUser(state, val) {state.user = val}
  }
})
const Counter = {data() {
    return {username: ''}
  },
  template:
        `<div>
          <div v-if='isLogin'>
            {{user.username}}已登录
            <a @click="signOut" href="javascript:;"> 退出登录 </a>
          </div>
          <div v-else>
            <input v-model="username" placeholder="输出用户名">
            <div class="btn" @click="submit"> 登录 </div>
          </div>
        </div>`,
  computed: {...mapState(['isLogin', 'user'])
  },
  methods: {submit() {if (this.username) {this.$store.commit('setLogin', true)
        this.$store.commit('setUser', {
          id: 1,
          username: this.username
        })
      }
    },
    signOut() {this.$store.commit('setLogin', false)
      this.$store.commit('setUser', {})
    }
  }
}
let vm = new Vue({
  el: '#app',
  store,
  components: {Counter}
})

六、Actions
Action 相似于 mutation, 区别:
1、Action 提交的是 mutation, 而不是间接变更状态。
2、Action 能够蕴含任意异步操作

正文完
 0