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)有几个特点:

  1. 服务器端渲染可以让搜索引擎更容易读取页面的meta信息以及其他SEO相关信息,大大增加网站在搜索引擎中的可见度。
  2. 更快的来生成内容和相对比较慢的来进行数据交互。
  3. 首次加载页面的速度加快。客户端渲染的一个缺点是,当用户第一次进入站点,此时浏览器中没有缓存,需要下载代码后在本地渲染,时间较长。而服务器渲染则是,用户在下载的已经是渲染好的页面了,打开速度比本地渲染快。
  4. 服务器端多更多的事情,让客户端做尽量少的事,从而可以照顾(不抛弃)那些手机或电脑性能比较特别差又想上网的用户。

现在已有的后台服务端框架都可以实现如 MeteorExpressSails

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

其他资源

下面列出的资源清单强烈建议你去看下:

本文参考


  1. 在面向对象和函数式编程,不可变对象的状态在创建后不能修改 ↩︎

窥探Vue.js 2.0的更多相关文章

  1. 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?

    引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...

  2. Vue.js 2.0 参考手册.CHM下载

    下载地址 Vue.js 2.0 参考手册.CHM下载链接: http://pan.baidu.com/s/1kVbhd4b 密码: wxfh

  3. Vue.js 2.0版

    Vue.js 2.0版升级,更改了好多方法或指令 new Vue({ el:'#demo', data:{ msg:"vue2.0" } }) v-model lazy numbe ...

  4. Vue.js 2.0 和 React、Augular

    Vue.js 2.0 和 React.Augular 引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那 ...

  5. 基于Vue.js 2.0 + Vuex打造微信项目

    一.项目简介 基于Vue + Vuex + Vue-router + Webpack 2.0打造微信界面,实现了微信聊天.搜索.点赞.通讯录(快速导航).个人中心.模拟对话.朋友圈.设置等功能. 二. ...

  6. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  7. flask 与 vue.js 2.0 实现 todo list

    实现了后端与前端分离,后端提供 RESTful api. 后端 flask 与前端 vue 的数据传输都是 json. 本文使用 vue.js 2.0 对前一个例子:flask, SQLAlchemy ...

  8. vue.js 2.0实现的简单分页

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  9. 使用 Vue.js 2.0+ Vue-resource 模仿百度搜索框

    使用 Vue.js 2.0 模仿百度搜索框 <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...

随机推荐

  1. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  2. 通往全栈工程师的捷径 —— react

    腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...

  3. HTML DOM 介绍

    本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...

  4. C++中的const

    一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...

  5. OpenGL超级宝典笔记----框架搭建

    自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...

  6. Asp.net Core 初探(发布和部署Linux)

    前言 俗话说三天不学习,赶不上刘少奇.Asp.net Core更新这么长时间一直观望,周末帝都小雨,宅在家看了下Core Web App,顺便搭建了个HelloWorld环境来尝尝鲜,第一次看到.Ne ...

  7. ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由

    原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...

  8. [原创]关于Hibernate中的级联操作以及懒加载

    Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...

  9. Java 程序优化 (读书笔记)

    --From : JAVA程序性能优化 (葛一鸣,清华大学出版社,2012/10第一版) 1. java性能调优概述 1.1 性能概述 程序性能: 执行速度,内存分配,启动时间, 负载承受能力. 性能 ...

  10. Angular (SPA) WebPack模块化打包、按需加载解决方案完整实现

    文艺小说-?2F,言情小说-?3F,武侠小说-?9F long long ago time-1-1:A 使用工具,long long A ago time-1-2:A 使用分类工具,long long ...