窥探Vue.js 2.0
title: 窥探Vue.js2.0
date: 2016-09-27 10:22:34
tags: vue
category: 技术总结
窥探Vue.js2.0
令人兴奋的Vue.js 2.0正式版发布了。新的VUE框架有重大的改进,添加了一些新的特性,比如 Virtual-DOM,Server Side Rendering(服务端渲染),支持 JSX/Hyperscript 语法等,并去掉了一些已有的方法。
新的特性
Virtual DOM
虚拟DOM 是一个真正DOM的抽象、轻量级版本。
它主要作用是让你操控虚拟DOM,来代替直接操控真是DOM。之后虚拟DOM和真是DOM比较,把两者差异的部分再渲染到页面上。
这比直接操作DOM的速度要快的多,因为DOM操作是非常耗时的,加入虚拟DOM对比之后减少不必要DOM操作花的时间比进行DOM和虚拟DOM对比的时间要多,所以采用虚拟DOM是更有优势的。更多关于 什么是Virtual Dom?什么是DOM ?
Server Side Rendering
我们知道 JavaScript 除了可以在浏览器上运行,也可以在服务器端运行,比如 Node.js 平台。JavaScript在服务端生成HypetText或者HTML文件发送给客户端的浏览器。
服务器端渲染(SSR)有几个特点:
- 服务器端渲染可以让搜索引擎更容易读取页面的meta信息以及其他SEO相关信息,大大增加网站在搜索引擎中的可见度。
- 更快的来生成内容和相对比较慢的来进行数据交互。
- 首次加载页面的速度加快。客户端渲染的一个缺点是,当用户第一次进入站点,此时浏览器中没有缓存,需要下载代码后在本地渲染,时间较长。而服务器渲染则是,用户在下载的已经是渲染好的页面了,打开速度比本地渲染快。
- 服务器端多更多的事情,让客户端做尽量少的事,从而可以照顾(不抛弃)那些手机或电脑性能比较特别差又想上网的用户。
现在已有的后台服务端框架都可以实现如 Meteor ,Express ,Sails。
JSX (Javascript XML syntax transform)
JSX是使用XML语法编写Javascript的一套解析工具,X代表XML。这不是要由引擎或浏览器中实现,它的目的是通过各种预处理程序(transpilers),将这些标记转换成标准的ECMAScript。实质上也就是说JSX是一个语法糖,每一个XML标签都会被JSX转换工具转换成纯Javascript代码。如:
// Using JSX to express UI components.
let dropdown =
<Dropdown>
A dropdown list
<Menu>
<MenuItem>Do Something</MenuItem>
<MenuItem>Do Something Fun!</MenuItem>
<MenuItem>Do Something Else</MenuItem>
</Menu>
</Dropdown>;
render(dropdown);
Hyperscript
Hyperscript是JavaScript创建超文本(HTML)的语法。客户端、服务器端都支持。
如下代码及其输入
var h = require('hyperscript')
h('h1.fun', {style: {'font-family': 'Comic Sans MS'}}, 'Is Guybrush a French name?')

舍弃和修改的部分
接下来我将用一个实例演示vue这两个版本间的一些不同的地方。主要包括:
- events
- .sync 依赖的弃用
- vm.$set() 方法的弃用
- component 组件的模板
- 一些其他的变化
.sync 修饰符
当父子组件传参的时候我们肯能会想到把.sync修饰符用于子组件的prop上,以实现数据的双向绑定。从现在起,props 就只有单项绑定了。如果当一个组件需要修改他作用域外的数据的时候,它只能emit一个事件(vm.$emit(event,[..args])事件)让监听器回调,而不是再依赖于之前的隐士绑定了。
去掉这个修饰符的目的是为了防止子组件在父组件的范围内所引发的副作用。这样,当你阅读一个组件的代码的时候,就更加容易理解它做了什么以及是如何影响其他部分的。
vue 版本的比较
为了尽可能阐述清楚这两版本的差异,我用一个实例来解释吧。比如
这有个用户可以购买宝石的页面,其中有个Vue实例和一个购物车组件。在购物车组件里,用户选择了要购买多少个然后这个购物车组件把这个变化反映给它的父组件。
用vue 1.0.*
用vue1.0.* 的话,要实现这个功能是显而易见的。我们创建一个变量,来存储所选择的数量,我们把它传递给购物车组件,等待选择数量来更改它的值,在父组件上在写一个computed属性来计算总价格。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.23/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<meta charset="utf-8">
<title>Gem Market</title>
</head>
<body>
<div class="container">
<h1>Gem Market</h1>
<cart :quantity.sync="quantity"></cart>
<hr>
<div>
<h3>You have to pay <strong>{{ gold }}</strong> pieces of gold.</h3>
</div>
</div>
<template id="cart-template">
<h2>How many gems would you like to buy?</h2>
<p>1 emerald costs 100 pieces of gold.</p>
<input v-model="quantity" class="form-control" number>
</template>
</body>
<script type="text/javascript">
Vue.component('cart', {
template: "#cart-template",
props: { quantity : 0 }
});
new Vue({
el: '.container',
data : function () {
return {
quantity: 0
};
},
computed:{
gold: function(){
return this.quantity * 100
}
}
})
</script>
</html>

用vue 2.0
如果切换到vue 2.0,运行上面的代码,我们会得到以下警告。
[Vue warn]: Component template should contain exactly one root element.
为了去掉这个警告我们在 template内部加上一个Div元素。
<template id="cart-template">
<div>
<h2>How many gems would you like to buy?</h2>
<p>1 emerald costs 100 pieces of gold.</p>
<input v-model="gems" class="form-control" number>
</div>
</template>
刷新浏览器,发现这个警告消失。
当我们改变这个变量的时候,我们得到这个警告。
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “gems” (found in component: )
这是因为在vue2中,直接修改prop是被视作反模式的。由于在新的渲染机制中,每当父组件重新渲染时,子组件都会被覆盖,所以应该把props看做是不可变对象 [1]。
不能更改 quantity prop使其和父组件同步 , 而是让应该这个组件提交个事件给父组件,可以 watch quantity 变量,如果变量发生改变就emit事件,所以这里压根不需要 prop。
由于 vm.$dispatch 和 vm.$broadcast 被弃用了,我们用一个集中式事件集线器触发事件 来实现组件间的通讯。建议阅读 升级提示。
因为在Vue实例中已经实现了事件发射器接口emit,实际开发中可以用空的Vue实例作为事件发射器。
让我们看回这个例子,创建一个emitter,重构一下Cart组件。
let bus = new Vue()
Vue.component('cart', {
template: "#cart-template",
data () {
return {quantity : 0 }
},
watch: {
'quantity': function (quantity, oldQuantity) {
console.log('quantity changed from %s to %s', oldQuantity, quantity)
bus.$emit('quantity-changed', quantity)
}
}
});
检查下浏览器控制台,会发现每次改变quantity的值,都会在控制台上打印出变化前后的值。

然后,就是要更新父Vue的实例来监听,并更新相应的数据。
new Vue({
el: '.container',
data : function () {
return {
quantity: 0
};
},
created: function () {
// store this to use with Vue.set
var temp = this;
bus.$on('quantity-changed', function (quantity) {
// vm.$set deprecated
Vue.set(temp, 'quantity', quantity)
})
},
computed:{
gold: function(){
return this.quantity * 100
}
}
})
注意
vm.$set() 被弃用了,所以我们用全局方法 Vm.set()。
因为不能使用prop去同步,所以我们这样引用购物车组件:<cart></cart>’lazy’ 和 ’number’ 修饰符更改了,所以我们这样修改下 购物车组件里的Input
// Vue 1
<input v-model=”quantity” class=”form-control” number>
// Vue 2
<input v-model.number=”quantity” class=”form-control”>
好了,这就是所有的了,你可以查看最终代码,然后自己把玩一番吧 JSFiddle。
其他资源
下面列出的资源清单强烈建议你去看下:
- Vue2官方公告
- Vue 2 LiveStream 在线看 Evan You 演示的一些新特性和弃用的部分。
- Vue 2 Features查看所有新功能,弃用和其他的变化。
本文参考
- Why is React's concept of Virtual DOM said to be more performant than dirty model checking?
- https://dotdev.co/peeking-into-vue-js-2-part-1-b457e60c88c6#.yksm6uco2
在面向对象和函数式编程,不可变对象的状态在创建后不能修改 ↩︎
窥探Vue.js 2.0的更多相关文章
- 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?
引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...
- Vue.js 2.0 参考手册.CHM下载
下载地址 Vue.js 2.0 参考手册.CHM下载链接: http://pan.baidu.com/s/1kVbhd4b 密码: wxfh
- Vue.js 2.0版
Vue.js 2.0版升级,更改了好多方法或指令 new Vue({ el:'#demo', data:{ msg:"vue2.0" } }) v-model lazy numbe ...
- Vue.js 2.0 和 React、Augular
Vue.js 2.0 和 React.Augular 引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那 ...
- 基于Vue.js 2.0 + Vuex打造微信项目
一.项目简介 基于Vue + Vuex + Vue-router + Webpack 2.0打造微信界面,实现了微信聊天.搜索.点赞.通讯录(快速导航).个人中心.模拟对话.朋友圈.设置等功能. 二. ...
- vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍
这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...
- flask 与 vue.js 2.0 实现 todo list
实现了后端与前端分离,后端提供 RESTful api. 后端 flask 与前端 vue 的数据传输都是 json. 本文使用 vue.js 2.0 对前一个例子:flask, SQLAlchemy ...
- vue.js 2.0实现的简单分页
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- 使用 Vue.js 2.0+ Vue-resource 模仿百度搜索框
使用 Vue.js 2.0 模仿百度搜索框 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...
随机推荐
- Visual Studio Code 代理设置
Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...
- 0-1背包问题蛮力法求解(java版本)
sloves: package BackPack; public class Solves { public int[] DecimaltoBinary(int n,int m) { int ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- spring注解源码分析--how does autowired works?
1. 背景 注解可以减少代码的开发量,spring提供了丰富的注解功能.我们可能会被问到,spring的注解到底是什么触发的呢?今天以spring最常使用的一个注解autowired来跟踪代码,进行d ...
- P2V之后的磁盘扩容新思路
背景: 原先的物理机环境多是若干块物理磁盘经过RAID卡进行了RAID5之后的虚拟磁盘组,这样我们在操作系统内看到的也就是一块完整的磁盘.我们会在上面进行分区,然后格式化后以便使用. Figure 1 ...
- CSS 3 学习——transform 3D转换渲染
以下内容根据官方规范翻译,没有翻译关于SVG变换的内容和关于矩阵计算的内容. 一般情况下,元素在一个无景深无立体感的平面(flat plane)上渲染,这个平面就是其包含块所处的平面.同时,页面上的其 ...
- peer not authenticated的终极解决方案
一.前述 使用httpclient发起https请求时,可能会遇到如下异常: javax.net.ssl.SSLPeerUnverifiedException: peer not authentica ...
- STM32F429 LCD程序移植
STM32F429自带LCD驱动器,这一具有功能给我等纠结于屏幕驱动的程序员带来了很大的福音.有经验的读者一定有过这样的经历,用FSMC驱动带由控制器的屏幕时候,一旦驱动芯片更换,则需要重新针对此驱动 ...
- gulp批量打包文件并提取公共文件
gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器. browseriyf是模块化打包工具. 一般情况下,Browserify 会把所有的模块打包成单个文件.单个文件在大多数情况下是 ...
- Linux常用命令
命令格式与目录处理命令 ls 命令格式与目录处理命令 ls 命令格式:命令 [-选项][参数] 例:ls -la /etc 说明: 1)个别命令使用不遵循格式 2)当有多个选项时,可以写在一起 3)简 ...