前端学习笔记Vue篇(2)

1.Vue中数据双向绑定的实现原理

首先我们要知道什么是数据的双向绑定

双向绑定也就是我们平时所说的MVVM模式,即model,view,view-model

假如你在js中定义了一个对象

var cat = {
	name: 'Tom'
} 

假定我们通过某种方法使整个对象的数据和某个DOM节点关联起来,以达到以下目的:

修改DOM节点的数据可以改变cat对象的数据,

修改cat对象的数据可以改变DOM节点的数据。

这便是我们所说的MVVM模式

搞清楚什么是双向绑定后,现在来说说Vue中的实现方式

vue.js 采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

这句话一时也许很难理解

首先在Vue中什么是数据劫持,它就是通过Object.defineProperty()来获取属性的getter和setter方法,来进行数据的监控

其次什么是发布者-订阅者模式,它有另一个更为熟悉的模式,即观察者模式,这是一种javascript的设计模式。用通俗的话来讲,它就像是微信公众号和订阅者的关系,作为订阅者的你不必每天去请求公众号给你发信息。

接下来就来看看它的实现原理了


上图中,new MVVM()便是我们最终需要的,它的实现主要通过Observer,Compile,Watcher。

1.Observer使用Object.defineProperty()对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者;

2.Compile是一个解析器,其目的就是渲染视图。它通过解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

3.Watcher便是这里的订阅者,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

以上便是Vue的双向绑定实现原理

2.Vuex

什么是Vuex?

简单来说,Vuex是专门设计为Vue进行状态管理的模式

Vuex在项目中的应用

首先初始化一个vue项目,并通过以下指令安装vuex依赖:

npm install vuex -s

之后在项目的src目录下新建一个store文件夹,形成以下文件结构:


下面讲解以下以上文件的作用:

state

state中储存数据的状态,也就是你需要管理的数据保存在state中

// state保存数据的状态
const state = {
  val: {
    count: 0,
    type: Number
  }
}

export default state

getter

getter相当于store的computed属性,对数据进行加工过滤

export const count = (state) => {
  return state.val.count
}
export const type = (state) => {
  return state.val.type
}

这里便是将val的count和type剥离了出来

mutation-type

mutation-type并不是vuex的核心概念,它是一种mutation的规范,定义mutation的函数名

export const ADD = 'ADD'

mutation

在vuex中,改变数据状态的唯一方式就是提交mutation;

mutation获取state中数据的状态,并对其进行操作,需要注意的是mutation中进行的都是同步操作

import * as types from './mutation-type.js'

export default {
  [types.ADD] (state) {
    state.val.count += 1
  }
}

actions

action和mutation的作用相同,但区别在于action中进行的是异步操作,或者多个commit

import * as types from './mutation-type.js'

export default {
  addAction ({commit}) {
    setTimeout(() => {
      commit(types.ADD)
    }, 1000)
    console.log('异步执行的actions')
  }
}

以上是提交一个add的mutation,commit是进行提交必要的参数,这里使用setTimeout是为了体现异步执行

store

store便是装配以上内容后对外导出的接口了,通常将装配写在store下的index.js中

import vue from 'vue'
import vuex from 'vuex'
import state from './state.js'
import * as getters from './getters.js'
import mutations from './mutations.js'
import actions from './actions.js'
import m1 from './modules/m1.js'
import m2 from './modules/m2.js'

vue.use(vuex)

export default new vuex.Store({
  state,
  getters,
  mutations,
  actions,
  modules: {
    m1,
    m2
  }

})

这里的model之后再进行解释

在组件中使用

有以下四个方法:

mapstate 获取state数据

mapgetters 获取getters数据

mapMutations 调用mutations方法

mapActions 调用actions方法

<div @click="add">{{count}}</div>
<div @click="addAction">{{count}</div>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
  computed: {
    // 获取state中的数据
    // ...mapState(['count'])
    ...mapGetters(['count'])
  },
  methods: {
    ...mapMutations({
      'add': 'ADD'
    }),
    ...mapActions({
      'addAction': 'addAction'
    })

  }

上述4种函数调用的时候可以使用扩展运算符...直接调用

获取数据的方式可以是

...mapState(['count'])//当state中的count和组件中的count名相同时
...mapState({'count': 'icount')当state中数据和组件中不同名时,这里是icount

由于state中的数据是嵌套对象,所以使用mapGetters来获取count

module

当组件数量增多时,其状态也会变多,此时所有的状态在同一个store中便会很复杂。

这时就可以创建不同的module,使用不同或相同的state,getters,mutations,actions ,使结构更加清晰

猜你喜欢

转载自blog.csdn.net/m0_37782372/article/details/81015072