[关闭]
@GaoyuanHfut 2017-08-13T10:52:25.000000Z 字数 7578 阅读 557

vue起手式

vue.js

此处输入图片的描述
谈vue之前,我们先来了解为什么要用框架?

什么是Vue.js

不管你想不想了解,你只需要大概知道,Vue就是和jQuery一样是一个前端框架,它的中心思想就是数据驱动,像远古时代的老前辈jQuery是结构驱动,什么意思呢,以前我们写代码时常用$('.dom').text('我把值改变了'),这种写法先要获得结构,然后再修改数据更新结构,而Vue的做法直接就是this.msg="我改变了",然后msg就会同步到某个结构上,视图管理抽象为数据管理,而不是管理dom结构了。不懂没关系,慢慢来。

还有一点必须要知道的是,Vue是国人写的,技术文档也妥妥的是中文,想到这我就有学习的动力。

基于HTML的前端界面开发正变得越来越复杂,其本质问题基本都可以归结于如何将来自于服务器端或者用户输入的动态数据高效的反映到复杂的用户界面上。vue框架正是完全面向此问题的一个解决方案,按官网描述,其出发点为:用于开发数据不断变化的大型应用程序(Building large applications with data that changes over time)。相比传统型的前端开发,vue开辟了一个相当另类的途径,实现了前端界面的高效率高性能开发。

预备知识

1. vue的原理

在Web开发中,我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。
浏览器把实现页面渲染的部分和解析js的部分分开来实现,既然是分开的,一旦两者需要产生连接,就要付出代价。

官方例子:把DOM和js(ECMAScript)各自想象为一座岛屿,它们之间用收费桥进行连接。ECMAScript每次访问DOM,都要途径这座桥,并交纳“过桥费”。访问DOM的次数越多,费用也就越高。
q
因此,推荐的做法是:尽可能的减少过桥的次数,努力待在ECMAScript岛上。
复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。vue为此引入了虚拟DOM(VirtualDOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于vue进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,vue都会重新构建整个DOM树,然后vue将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且vue能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,然后又从B变成A,vue会认为UI不发生任何变化,而如果通过手动控制,这种逻辑通常是极其复杂的。尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操作的仅仅是Diff部分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。
Alt text
借用Facebook介绍vue的视频中聊天应用的例子,当一条新的消息过来时,传统开发的思路如上图,你的开发过程需要知道哪条数据过来了,如何将新的DOM结点添加到当前DOM树上;而基于vue的开发思路如下图,你永远只需要关心数据整体,两次数据之间的UI如何变化,则完全交给框架去做。
Alt text
可以看到,使用vue大大降低了逻辑复杂性,意味着开发难度降低,可能产生Bug的机会也更少。至于vue如何做到将原来O(n^3)复杂度的Diff算法降低到O(n),大家可以参考这篇文章

2. 组件化的开发思路

虚拟DOM不仅带来了简单的UI开发逻辑,同时也带来了组件化开发的思想,所谓组件,即封装起来的具有独立功能的UI部件。vue推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体UI的构建。例如,Facebook的instagram.com整站都采用了vue来开发,整个页面就是一个大的组件,其中包含了嵌套的大量其它组件,大家有兴趣可以看下它背后的代码。

如果说MVC的思想让你做到视图-数据-控制器的分离,那么组件化的思考方式则是带来了UI功能模块之间的分离。我们通过一个典型的Blog评论界面来看MVC和组件化开发思路的区别。

对于MVC开发模式来说,开发者将三者定义成不同的类,实现了表现,数据,控制的分离。开发者更多的是从技术的角度来对UI进行拆分,实现松耦合。
Alt text
上图右边使我们往常写的代码,对于vue而言,则完全是一个新的思路,开发者从功能的角度出发,将UI分成不同的组件,每个组件都独立封装。
Alt text
在vue中,你按照界面模块自然划分的方式来组织和编写你的代码,对于评论界面而言,整个UI是一个通过小组件构成的大组件.如果要构建一些大型的应用,基于组件的开发模式是一个不错的选择,我们将整个系统拆分成一个一个小组件,就像乐高一样,然后将这些组件拼接起来。每个组件只关心自己部分的逻辑,彼此独立。这样最外层的界面的Render只需要如下代码:
Alt text
通过这种方式,每个组件的UI和逻辑都定义在组件内部,和外部完全通过API来交互,通过组合的方式来实现复杂的功能。vue认为一个组件应该具有如下特征:

3. vue组件开发的例子

为什么vue.js一眼看上去很美?
对其他框架我是佩服,对vue.js我则是爱。我就是一眼看上了vue.js,于是用它做各种东西,反反复复多次,然后觉得有些融会贯通,然后,我稍微细的思量了下,到底vue.js靓丽在哪?
demo
一个span,两个按钮,点击按钮会让span加1或者减1。它简单到你不需要分心关注,但是由足够说明典型的html场景——就是既有数据呈现也有按钮操作。

vanilla.js


首先出场的是vanilla.js(vanilla.js的意思是,不使用任何框架) ,代码是这样的:

<div id="app">
    <p>
        <span id="count">0</span>
        <button id="inc">+</button>
        <button id="dec">-</button>
    </p>
</div>
<script>
    var counter = document.getElementById('count');
    var btn1 = document.getElementById('inc');
    var btn2 = document.getElementById('dec');
    var count = 0;
    btn1.addEventListener('click',function (){
                counter.innerHTML = ++count;
            }
    )
    btn2.addEventListener('click',function (){
                counter.innerHTML = --count;
            }
    )
</script>

代码行数倒是不算多,但是看起来的感受是:

使用了多个DOM API(getElementById,innerHTML)

  1. DOM API设计的复合词太长
  2. 我偏爱简洁的代码,而使用DOM API就构成了一种代码的臭味,让我喜欢不起来。

jquery


第二个出场的是jquery。我个人认为前端历史上来说,有几个标志性事件
3. 微软加入了XMLHttpRequest。从此Ajax技术一发而不可收
4. jquery。简单的Selector,精简的API,令世人只有有jquery,不知道有Vanilla.js
5. Vue.js等相类似的框架。引入了数据绑定,以及组件技术到前端开发所有,jquery当然是排的上好的技术了。那么,使用jq,效果如何呢?

<script>
  src="https://code.jquery.com/jquery-3.1.1.js"
  integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
  crossorigin="anonymous"></script>
<div id="app">
<p><span id="count">0</span>
    <button id="inc">+</button> 
    <button id="dec">-</button>
  </p>
</div>
<script>
var count = 0 
$('#inc').click(function(){
      $("#count").html(++count)
    })
    $('#dec').click(function(){
  $("#count").html(--count)
})
</script>

分析一下:

  1. jquery的选择器比起原生的更好,即使和querySelector相比也更简洁
  2. 使用精简的API替代Vanilla的。比如.html()比起.getElementById()来说,是要看着舒服点的

然而,内核基本不变:依然是添加EventListener,命令式的取值和修改值,依然你得懂得DOM的节点选择、事件监听、回调函数等。

Vue.js


最后出场的是vue,代码是这样的:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
  <p>{{count}}
    <button @click="inc">+</button>
    <button @click="dec">-</button>
  </p>
</div>
<script>
new Vue({
  el:'#app',
  data () {
    return {
      count: 0
    }
  },
  methods: {
    inc () {
      this.count++
    },
    dec () {
      this.count--
    }
  }
})
</script>

第一感觉就是:

  1. 规整。数据(data),方法(methods)放置的工工整整,一目了然。它充分的利用js的字面量对象的语法
  2. 整个应用接口设计,基本上采用的都是简单。一眼看过去,一个复合词也没有(比如getElementById就是4个复合词)

好处是:

  1. 现在,你不需要挂接EventListener,使用@click语法自动绑定事件,使用{{}}自动绑定数据
  2. 你不需要DOM的一系列的知识就可以构造此程序;对初学者来说,这个门槛真是降低太多

Vue.js的优美和简约,来源于声明式编程的理念。就是说我不需要通过一系列的函数调用来完成一件事儿,而是直接声明想要什么事儿。比如:

  1. 程序员直接声明{{count}},告诉Vue,此处使用Vue实例中的data对象内的count属性来填充。而不是调用.getElementById,.textContent来设置。
  2. 程序员通过@click直接声明点击事件指向位置为Vue实例内对象methods对应的方法。而不是通过调用.addEventListener,传入回调函数的方式来实现事件监听

整个Vue.js的应用接口设计的非常优美,但是能量巨大,做到这一点需要很多功力。这就是我佩服的设计哲学。把麻烦留给自己,让开发者感受简洁。

4.生命周期,一幅图

Alt text

5. 前端状态管理史之新力量--vuex

做一个比喻

想想现代物流系统的发展的不同阶段,我们寄一件东西的过程,

没有物流系统时:

打包准备好要送出去的东西;
- 出门到距离家最近的物流公司,填写物品,收件人等基本信息;
- 物流公司替你送物品到你的朋友处,自己可以回家做别的事情了;
- 多了一个中介,要付一定的运送成本,但是东西可以送到远在几千公里之外的其它人了,用一点点钱节约了自己宝贵的时间,完成了以前我们不可能做的事情;

没有物流系统时对应的就是没有使用状态管理的的前端阶段,做一件事情很直接,如果只是送快递给一个特别近的人,那当然是非常方便。就算你要从北京送一个东西到上海,在这个阶段你也可以实现,但是需要付出的代价就太大了。

而出现了各大物流公司对应的就是使用vue等框架的阶段,学习vue需要付出成本,如果你只需要做简单的事情(比如说你想把东西送给你的邻居),那使用此类框架其实显得特别累赘,把简单的事情复杂化了,但是如果你想做复杂一点的事情(同时寄礼物给三个不同城市的人),那么选择快递公司是不会错的。

那么vue和vuex的关系又该如何理解呢?

我觉得我们可以把vue比如为一家自建快递系统的公司(京东?),在一定范围内,它的快递系统已经足够好了(部分一二线城市一天内直达),但是要管理这个日益复杂的快递系统,需要公司付出巨大的成本。

vuex可以看做业内最好的第三方快递系统(顺丰?),使用它比较贵(学习成本稍微有点高),但是他到达全国主要城市都会特别快,如果你是一个电商老板,采用这个第三方物流系统之后,你只需要关注于自己的货物,几乎不用再去关心物流怎么办了。

不同于顺丰每一次寄货都要那么高的价格,vuex是一个学习一次,就可以免费寄货的优秀第三方快递系统,那我们当然要解散自己的物流公司来采用这个第三方的选择的。不过话说回来,学习是需要有成本的,所以是直接使用vue还是学习vuex再使用,这是你一个你需要依据你自己项目的实际情况作出选择的事情。

不过这个例子可能并不足够合适,vuex做的不仅仅是管理原来vue里state里面的状态。vuex其实可以接管我们的app里所有的数据。接下来我们具体看看vuex究竟做了什么。

vues可以做什么??(相对应得react.js有redux)

常常听到一种说法,“vuexvuex/vu是一个非常好的状态管理器”,那究竟什么是状态呢。

重新理解前端中的状态

想想我们平时看的网页,app,或者任何其它和我们有交互的东西,我们感觉到交互的发生是因为界面依据我们的行为作出了反馈,界面所有的改变,其实都可以看作是状态的改变,或者说界面会改变是因为我们的某个行为(事件)(click,drag,move...)触发了某个函数,函数造成了状态的改变,进而改变了界面。

如此看来,无论是显示隐藏这种可见的状态,还是从服务器获取更多的数据,这些都可以看做是状态,而这些状态就是我们的vuex要管理的。

换一句比较专业一点的说法吧,状态包括

API State;(数据)
UI State;(UI的表现形式)

为了更好的展示vuex的好,我们回顾一下前端的状态管理史(称为史其实并不合适,以下三种模式现在都有大量人在使用)。

vuex官网

总结

前端界总是喜欢创造新的概念,仿佛谁说的名词更晦涩,谁的水平就越高,听到 vue 这个概念一脸懵逼的话,只要记住以下定义即可:

vue 是一套可以用简洁的语法高效绘制 DOM 的框架

如上所述,vue是一个全新思路的前端UI框架,它完全接管了UI开发中最为复杂的局部更新部分,擅长在在复杂场景下保证高性能;同时,它引入了基于组件的开发思想,从另一个角度来重新审视UI的构成。通过这种方法,不仅能够提高开发效率,而且可以让代码更容易理解,维护和测试。vue在发布一年的时间里就获得了极大的关注,Github上拥有超过1万的Star,相信其对前端开发的方向,甚至Web Component的标准,都将产生一定的影响。

拓展 weex

通过 JSON 文件传递信息的不足之处:只能传递配置信息,无法表达逻辑。从本质上讲,这是因为 JSON 毕竟只是纯文本,它缺乏像编程语言那样的运行能力。

而 vue 在前端取得突破性成功以后,JavaScript 布道者们开始试图一统三端。他们利用了移动平台能够运行 JavaScript 代码的能力,并且发挥了 JavaScript 不仅仅可以传递配置信息,还可以表达逻辑信息的优点。

当痛点遇上特点,两者一拍即合,于是乎:

一个基于 JavaScript,具备动态配置能力,面向前端开发者的移动端开发框架,weex,诞生了!

看到了么,这是一个面向前端开发者的框架。它的宗旨是让前端开发者像用 vue 写网页那样,用 vue 写移动端应用。这就是为什么 vue 自称:

Learn once,Write anywhere!

而非很多跨平台语言,项目所说的:

Write once, Run anywhere!

weex 希望前端开发者学习完 vue 后,能够用同样的语法、工具等,分别开发安卓和 iOS 平台的应用并且不用一行原生代码。

如果用一个词概括 weex,那就是:Native 版本的 vue。

大概的简述一些其原理,我们知道 C系列的语言,经过编译,链接等操作后,会得到一个二进制格式的可执行文,所谓的运行程序,其实是运行这个二进制程序。

而 JavaScript 是一种脚本语言,它不会经过编译、链接等操作,而是在运行时才动态的进行词法、语法分析,生成抽象语法树(AST)和字节码,然后由解释器负责执行或者使用 JIT 将字节码转化为机器码再执行。整个流程由 JavaScript 引擎负责完成。

vue学习预备知识

es6 Module 的语法

vue学习资源

vue插件汇总
vue重用指令
element-ui

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注