Vue.js双向数据绑定原理及生命周期详解

    —— 什么是Vue.js ——

    Vue.js是一套构建用户界面的渐进式框架

    Vue被设计为可以自底向上逐层应用。

    Vue的核心库只关注视图层,不仅易于上手

    还便于和第三方库或既有项目整合。

    另一方面,当与现代化的工具链以及各种类库结合使用时Vue也能为复杂的单页应用提供驱动

   Vue基于MVVM模式

   将视图与模型双向数据绑定的数据驱动页面框架,M是数据,V是视图,VM是提供视图与模型之间双向数据绑定的通道。

   特点:

   1. View的变化会自动更新到viewModel
   2. viewModel的变化也会自动同步到view上显示
   3.这种同步是因为viewModel中的属性实现了observer
   4.当属性变更都能触发对应的操作

   —— 我的理解 ——

   Vue.js是一个构建用户界面数据驱动的渐进式框架

   通过尽可能简单的API实现响应的数据绑定和组合的视图组件  

  —— 渐进式框架 ——

 自由可控,对比三大框架的其他两个框架

1.当我们要用Angular框架时,要知道它是强主张的,必须遵循以下三条原则

        必须使用它的模块机制

        必须使用它的依赖注入

        必须使用它的特殊形式定义组件

2.当我们时候用React时,主张函数式的编程

    你需要知道什么是副作用

    什么是纯函数,如何隔离副作用

Vue就比较自由,你想把你的页面分的更加具体,分成更小的可控单元,那就使用组件反之可以不用。

不管是单页面还是多页面。首先都是通过声明式渲染声明每个字段,这是基本的要求。

通常我们会把公共的头部和尾部抽出来,做成组件。

单页面应用程序时往往是需要路由,这时候需要把vue的插件(vue-router)拉进来做路由

如果我们的项目足够复杂,大量的使用组件而且难以去管理组件的状态,这个时候我们使用vuex

项目完成后需要构建工具来build我们的系统,来提高我们的效果,最后形成完成的项目。

 

—— Vue.js强大魅力 ——

使用Vue会感到身心愉悦

同时兼备Angular和React的优点

轻量级框架 简单易用

MVVM模式 双向数据绑定

组件化和响应式的设计

实现数据和结构的分离

虚拟DOM运行速度快

 

 双向数据绑定如何监听数据层到视图层的变化?

一.发布者-订阅者模式( backbone.js ) 

使用自定义的data属性在HTML代码中指明绑定。

所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。

任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,反过来将变化广播并传播到所有绑定的对象和元素

 

二.脏值检查 ( Angular.js )

Angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,Angular只有在指定的事件触发时进入脏值检测

1.DOM事件,譬如用户输入文本,点击按钮等

2.XHR响应事件 ( $http )

3.浏览器Location变更事件 ( $location )

4.Timer事件( $timeout , $interval )

5.执行 $digest() 或 $apply()

 

三.数据劫持(Vue.js)

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

 

—— Vue双向数据绑定原理 ——

采用数据劫持结合发布者--订阅模式的方式

通过Object.definePropety

来劫持规格属性的setter和getter

在数据变动时发布消息给订阅者

触发相应的监听回调

 

原理剖析:

我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。

如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。

因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。

接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析

将相关指令(如v-model,v-on)对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数

此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。

 

—— Vue的生命周期 ——

Vue一整个的生命周期中会有很多钩子函数提供给我们在vue生命周期不同的时刻进行操作

        beforeCreate     创建前

        created        创建后

        beforeMount     载入前

        mounted        载入后

        beforeUpdate     更新前

        updated        更新后

        beforeDestroy    销毁前

        destroyed       销毁后

 

详细描述Vue生命周期的过程

我们首先需要创建一个实例

也就是在 new Vue()的对象过程当中

首先执行了init

在init的过程当中首先调用了beforeCreate

然后在injections(注射)和reactivity(反应性)的时候,它会再去调用created。

所以在init的时候,事件已经调用了,我们在beforeCreate的时候千万不要去修改data里面赋值的数据,最早也要放在created里面去做(添加一些行为)。

当created完成之后,它会去判断instance(实例)里面是否含有“el”option(选项)

如果没有的话,它会调用vm.$mount(el)这个方法

然后执行下一步;

如果有的话,直接执行下一步。

紧接着会判断是否含有“template”这个选项,如果有的话,它会把template解析成一个render function ,这是一个template编译的过程,结果是解析成了render函数:

render (h) {

  return h('div', {}, this.text)

}

解释一下,render函数里面的传参h就是Vue里面的createElement方法,return返回一个createElement方法,其中要传3个参数,第一个参数就是创建的div标签;第二个参数传了一个对象,对象里面可以是我们组件上面的props,或者是事件之类的东西;第三个参数就是div标签里面的内容,这里我们指向了data里面的text。

使用render函数的结果和我们之前使用template解析出来的结果是一样的。

render函数是发生在beforeMount和mounted之间的,这也从侧面说明了,在beforeMount的时候,$el还只是我们在HTML里面写的节点,然后到mounted的时候,它就把渲染出来的内容挂载到了DOM节点上。这中间的过程其实是执行了render function的内容。

在使用.vue文件开发的过程当中,我们在里面写了template模板,在经过了vue-loader的处理之后,就变成了render function,最终放到了vue-loader解析过的文件里面。这样做有什么好处呢?原因是由于在解析template变成render function的过程,是一个非常耗时的过程,vue-loader帮我们处理了这些内容之后,当我们在页面上执行vue代码的时候,效率会变得更高。

beforeMount在有了render function的时候才会执行,当执行完render function之后,就会调用mounted这个钩子,在mounted挂载完毕之后,这个实例就算是走完流程了。

后续的钩子函数执行的过程都是需要外部的触发才会执行。比如说有数据的变化,会调用beforeUpdate,然后经过Virtual DOM,最后updated更新完毕。当组件被销毁的时候,它会调用beforeDestory,以及destoryed。

1. 在beforeCreate和created钩子函数之间

在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在created的时候数据已经和data属性进行绑定(放在data中的属性当值发生改变的同时,视图也会改变)。
注意看下:此时还是没有el选项

2.created钩子函数和beforeMount间的生命周期

首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)

3.beforeMount和mounted间的生命周期

此时是给vue实例对象添加$el成员,并且替换掉挂在的DOM元素。因为在之前console中打印的结果可以看到beforeMount之前el上还是undefined

4. 在mounted通过插值表达式进行占位的已经加载到页面中显示了

5.当vue发现data中的数据发生了改变,会触发对应组件的重新渲染,先后调用beforeUpdate和updated钩子函数

6.beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。  

  Vue常用指令

 指令:是带有v-前缀的特殊属性

 职责是:当表达式的值改变时,将其产生的连带影响,响应式的作用于DOM.

—— 常用指令 ——

            v-model  双向绑定数据

            v-for       循环

            v-show    显示于隐藏

            v-if         条件

             v-else     选择

             v-else-if 判断选择条件

            v-bind 动态绑定

            v-on 事件

            v-text读取文本不能读取html标签

            v-html能读取html标签

            v-class 类名

            v-cloak防止闪烁

原文:https://blog.csdn.net/KyreneCurry/article/details/84745041 

你可能感兴趣的:(Vue,Vue.js)