laizimo / zimo-article

:books:博客——源于实践,乐于分享,欢迎Star~
1.06k stars 95 forks source link

浅入浅出Vue #44

Open laizimo opened 6 years ago

laizimo commented 6 years ago

前言

vue,在2017已经不是什么新鲜词了!作为一个前端学习者,今天写下学习总结。

本篇主要是一些vue的学习总结。开始写的原因——也是工作中,对于它的使用,逐渐增多了。并且也觉得是时候做一个总结。其实,我也算是三大框架的使用者啦!!!从最早期的angular,中期的react,直至vue。那么,就此开始做一个总结。如果你喜欢我的文章,欢迎评论,欢迎Star~。欢迎关注我的github博客

正文

其实,我并不知道从何开始去总结vue,因为vue的官方文档,可谓“中文开发者”的福音,实在是太全了!再次致敬悠大大。那么,我们废话不多说,还是从基本的东西说起——对象

相信看了文档的小伙伴,都会意识到Vue具备一个Vue的构造函数。如果使用ES5的语法来书写vue时,我们往往可以看到以下的实例:

var app = new Vue({
    //....
});

在其中配置各种的参数,例如:

当然咯,还会有其他的属性,例如components等等。具体的可以看官方文档。

数据响应

此处,我们引出了对象,那么我们就从vue的响应式原理讲起吧。Vue的思想可以说是从angular1.x开始衍生出来的,元素的基因,让他具备了一些轻便的指令。当然,从react中,它借鉴了VDOM等思想。那么,你是否考虑过它的响应式原理。

它同React一样,属于数据驱动型框架,它们均有一个范式:F(data) = view。同时,react可以通过setState这个关键方法达到这样子的效果,那么,Vue呢?Vue是如何实现的呢?

答案——「数据劫持」。其实,从ES5开始,对象就可以通过一个API来定义属性,如下:

var obj = {};

Object.defineProperty(obj, 'name', {
  value: 'zimo'
});

console.log(obj.name);

这里可以看到,我们通过这样子的方式也可以定义对象的属性。所以Vue在获得data中的内容之后,会将其中的数据,通过这样子的形式定义到Vue对象上面。然后,我们通过set和get方法的监听,来劫持数据,我们可以通过一个例子来说明:

var obj = {};

Object.defineProperty(obj, 'name', {
  get: function(){
    console.log('get');
    return val;
  },
  set: function(value){
    console.log('set');
    val = value;
  }
});

obj.name = 'zimo';    //'set'
console.log(obj.name);    //'get',  'zimo'

看过例子之后,我们会发现这defineProperty的API中使用set和get方法时,可以对对象数据进行劫持。这种效果,就可以达到setState的效果。

注:vue中,必须保证数据驱动的数据保证在对象创建时设置,即在data中设置。这样才可以达到数据劫持的效果。

官网原话:值得注意的是只有当实例被创建时 data 中存在的属性是响应式

但是,你会觉得这种方式是完美的吗?当然不是,我们可以来看一个例子(该例子通过上面改编的):

var obj = {};

Object.defineProperty(obj, 'name', {
  get: function(){
    console.log('get');
    return val;
  },
  set: function(value){
    console.log('set');
    console.log(value);
    val = value;
  }
});

obj.name = ['zimo'];
obj.name[0] = 1;
console.log(obj.name); 
// "set"
// ["zimo"]
// "get"
// "get"
// [1]

这个例子中发生了什么你一定好奇?或者说,你已经看出来了!那么我们直接说吧!

这里的obj.name[0]=1表达式并没有触发setter的函数。不信的话,你可以亲自动手尝试一下。相信只有亲自动手才会使得记忆深刻一些。

数组通过索引的方式去改变数据,适合并不会触发setter进行数据劫持。这个问题在早期的vue中的确存在。当然了,这么严重的问题,自然是会被解决的。相信熟悉ES6的人都知道,ES6中具备一个非常好的特性可以解决这个问题——proxy。每次就是数据代理,这种方式,可以在上述方法的基础上,进一步解决我们之前提到的缺点。

那么,关于proxy的问题,我在此处并不会做深入分析。

生命周期

上面我们大致搞清楚了vue的数据响应原理,那么data中的数据一旦发生变化,除了数据劫持发生之外,总该谈谈生命周期的话题了。

生命周期,就是一个组件,或是一个对象的存在时期。从最初的创建、安装、更新、卸载。我们可以通过官网的图来实际说明:

生命周期

这幅图中,清晰地讲明了,vue组件地从构造函数建立到销毁地全过程。

公用方法定义

既然我们知道了vue是由对象组成的,那么,我们往往会有些方法,并不仅仅是在一个Vue对象中使用的,举个例子:

我需要在vue中使用图表highchart,那么我可以做如下的操作:

import Highchart from 'highchart';

Vue.prototype.$highchart = Highchart;

const app = new Vue({
    methods: {
        init: function () {
            this.$highchart() //...
        }
    }
})

当然了,我们只是举了一个通俗的例子,通过这样子的方式,你就可以在Vue对象中新增许多原型方法,但是,需要记得的是——在方法定义时,请带上'$'符号,方便进行区分。

vue2.0

vue2.0是一个大版本的更迭,同时它的改变,使得越来越多的人喜欢使用它。它在这个版本中,引入了VDOM的概念。相信接触过React的小伙伴们,对VDOM这个概念应该一点也不陌生吧。

不得不说地是这样的改变,使得vue的性能得到了极大的提升。尤其是像diff算法的优化,react中体现地淋漓尽致。获取可以看我的另一篇文章——react diff算法

总结

关于vue的东西,其实还有很多。作为可以与react、angular并驾齐驱的三架马车。它的优越之处在于总结了angular1.0的失败之处,综合了react的优雅之点。同时,它也深深地嵌入了尤大大的个人智慧。同时,为前端程序员提供了良好的学习环境。本篇浅入浅出vue.js到此结束。

如果你对我写的有疑问,可以评论,如我写的有错误,欢迎指正。你喜欢我的博客,请给我关注Star~呦。大家一起总结一起进步。欢迎关注我的github博客