[VUE]VUEX笔记

Vue绑定方式

v-model

v-model是专门用于input,select,textare等表单控件的绑定。它能够渲染变量在dom上,同时控件的value改变时,对应变量也会作出改变。(在表单控件或者组件上建立双向绑定)。vue

<input type="text" v-model="name">
  <textarea v-model="message" placeholder="add multiple lines"></textarea>
  <input type="checkbox" id="checkbox" v-model="checked">
  <input type="radio" id="one" value="One" v-model="picked">
  <select v-model="selected">
        <option disabled value>请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
  </select>

v-bind

动态地绑定一个或多个特性,或一个组件 prop 到表达式。就是把属性变量化,class,style等能够根据变量来改变。同时也是父组件往子组件传值的方法。vuex

<img v-bind:src="imageSrc" :title="imageNum">

v-bind:能够简写成:。例子中图片的地址和title都是来自于vue实例里的变量。dom

Vuex

vuex 是一个专门为vue.js应用程序开发的状态管理模式。
这个状态咱们能够理解为在data中的属性,须要共享给其余组件使用的部分。
也就是说,是咱们须要共享的data,使用vuex进行统一集中式的管理。
vuex周期的大概流程是,在vue实例中调用store下的state后,想要改变state,要先经过store.commit(有异步操做要先dispath)来改变state,从而在vue页面中渲染。
avatar异步

state

store里的数据源库(一个全局的data),可在全局调用$store.state访问。
每当 state 变化的时候, 都会从新求取计算属性,而且触发更新相关联的 DOM。
在store里函数

state:{
    name:"张三"
}

vue实例this

<div>用户名: {{$store.state.name}}</div>

引用vuex后,在项目任意vue实例里均可以访问到state的内容。spa

Getter

从 store 中的 state 中派生出一些状态。(能够认为是对数据获取以前的再次编译, store 的计算属性)。他并不会改变state自己。只有当它的依赖值发生了改变才会被从新计算。(相似于vue实例的computed)
Getter 接受 state 做为其第一个参数,能够访问store里的state双向绑定

getters: {
        doneTodos: state => {
            return state.todos.filter(todo => todo.done)
        }
     }

第二个参数是getters,能够访问到上下文的getters。localstorage

getters: {
        doneTodosCount: (state, getters) => {
            return getters.doneTodos.length
        }
    }

假如须要传参,能够经过方法访问code

getters: {
         getTodoById: (state) => (id) => {
            return state.todos.find(todo => todo.id === id)
        }
    }

在vue实例中访问getters

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

mutation

mutation是更改 Vuex 的 store 中的状态的惟一方法。须要用store.commit()触发。
mutations:第一个参数是state,第二个参数是载荷(Payload)。即传参,在大多数状况下,载荷应该是一个对象。
很是重要的一点,mutation内必须是同步函数。

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

执行时store.commit()第一个参数是mutations的名称(字符串),第二个是载荷对象。

store.commit('increment', {
  amount: 10
});

Action

Action是专门处理store异步操做的。
Action 提交的是 mutation,而不是直接变动状态。
Action 经过store.dispatch()触发。
actions第一个参数是context(上下文),第二个参数是载荷。

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

vue实例里执行action。

store.dispatch('incrementAsync', {
  amount: 10
})

Module

因为使用单一状态树,应用的全部状态会集中到一个比较大的对象。当应用变得很是复杂时,store 对象就有可能变得至关臃肿。
module 能够把store 分割成模块(module)。每一个模块拥有本身的 state、mutation、action、getter。
store.js

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

在vue实例里访问时

$store.state.a // -> moduleA 的状态
$store.state.b // -> moduleB 的状态

这种写法下state会区分模块,但mutation和action的调用时,写法是同样的。

$store.commit(“set”);
$store.dispath(“set”);

命名空间

假如不一样的模块里有出现相同名称的mutations,就会出现问题。为了不,可使用命名空间。
在每一个模块下添加namespaced: true。便可实现命名空间。

const moduleA = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

在vue实例中调用时改成

$store.commit(“a/set”);
$store.dispath(“b/set”);

vuex和data

vuex是全局存在的,对于一些只在一个vue页面(组件)中用到的信息,能够只存在对于的页面(组件)的data中。store中通常存放一些在多处会读取或者改写的信息,这样能够避免多层的父子传值。通常常见的存放在store里的有用户信息,标签信息等。这样能够在不一样的地方操做标签。
例子:在一个项目中有一个右键弹出菜单的组件。组件须要传参,来决定传入内容。
store里

{
    state:{
        rightMenuData: [{
            name: '刷新此窗口',
            key: 'refresh'
        }, 
        {
            name: '关闭此窗口',
            key: 'close'
        }, {
            name: '关闭所有窗口',
            key: 'closeAll'
         }]
    }
}

vue页面中

<right-menu
    :menuData="rightMenuData"
    :eventHandler="rightClickHandler"
    v-on:handleSelect="handleRightSelect"
></right-menu>

列子中的菜单内容存在store里,在一个页面里调用了对应数据。但是实际上项目里只要一个页面须要用到这个数据。这种状况能够把数据只放到页面data里,避免store过于臃肿。

另外一个例子:
vue页面中

mounted() {
    let user = global.myLocalStorage.getItem("user");
    if (user) {
      user = JSON.parse(user);
      this.sysUserName = user.name || "";
      this.sysUserAvatar = user.avatar || "agree.bee.png";
    }
    //...省略部分

这里页面中用到一个用户信息,因为本地保存的关系,用户数据被存到localstorage里。而后项目在各处拿用户信息的时候会直接从localstorage里拿。这种状况,能够考虑,在页面打开时,只从localstorage拿一次数据,存在store里。在项目运行的过程当中就能够直接在store里访问用户信息。

多个store运用

在一些大型应用中,有可能存在多个store的状况,来保持自身的store不受影响。
例子:A实例下面有多个vue子页面b,c,d。它们都须要有本身的store。则在内部Vue实例中new一个vuex.store,并存起来(不必定要存$store,能够是其余变量)。

beforeCreate(){
        this.$store = new Vuex.store({
            stata,
            mutations,
            actions
        })
    }

此时vue实例b,c,d中

this.$store

返回的应该是本身的store。
若是想要访问A页面原来的store,能够用$root,访问根部vue实例,因为他的this.$store并无被重写,因此指向的仍是原来全局的store。

this.$root.$store
相关文章
相关标签/搜索