Vue绑定方式

v-model

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

  <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等可以根据变量来改变。同时也是父组件往子组件传值的方法。

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

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

Vuex

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

state

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

state:{    name:"张三"}

vue实例

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

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

Getter

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

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

第二个参数是getters,可以访问到上下文的getters。

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

假如需要传参,可以通过方法访问

    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