窥探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 ...
随机推荐
- Unity3d入门 - 关于unity工具的熟悉
上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...
- 当忘记mysql数据库密码时如何进行修改
因为长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件 ...
- HTML DOM 介绍
本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...
- Git命令总结
本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- 【Machine Learning】机器学习及其基础概念简介
机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- springmvc+mybatis+spring 整合 bootstrap html5
A 调用摄像头拍照,自定义裁剪编辑头像 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技 ...
- SharePoint2016安装的过程的”Microsoft.SharePoint.Upgrade.SPUpgradeException”错误解决方法
前提 在windows server 2012的服务器上运行安装sharepoint2016出现如下错误: Could not load file or assembly ‘Microsoft.Dat ...
- Android Studio开发RecyclerView遇到的各种问题以及解决(二)
开发RecyclerView时候需要导入别人的例子,我的是从github导入的,下载下github的压缩包之后解压看你要导入的文件是priject还是Module.(一般有app文件夹的大部分是pro ...
- 编译器开发系列--Ocelot语言2.变量引用的消解
"变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ...