前端学习总结(二十一)Vue.js——博采众长的后起之秀
2016-08-18 20:37
579 查看
Vue概述
实质:构建数据驱动的 web 界面的库目标:通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件
特点:
只聚焦于视图层,简单易于学习,容易与其它库或已有项目整合。
在与相关工具和支持库一起使用时,能完美地驱动复杂的单页应用。
Vue和其他技术的对比
VS Angular:
1.比 Angular 简单得多,可以快速掌握2.更加灵活开放,允许以希望的方式组织应用程序,而不是任何时候都遵循 Angular 的规则。仅仅是一个视图层,可以嵌入到一个现有页面而不一定要做成一个庞大的单页应用。
配合其他库方面有更大的的空间,但相应的也需要做更多的架构决策。如,Vue.js 核心默认不包含路由和 Ajax 功能,并通常假定在应用中使用一个模块构建系统。
3.Angular 使用双向绑定,Vue 也支持双向绑定,默认为单向绑定,数据从父组件单向传给子组件。在大型应用中使用单向绑定让数据流易于理解。
4.Vue中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑。在 Angular 中两者有不少相混的地方。
5.Vue有更好的性能,且非常容易优化,因为它不使用脏检查。*Angular,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环可能要运行多次*。
Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。Vue.js 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步列队更新,所有的数据变化都是独立地触发,除非它们之间有明确的依赖关系。唯一需要的优化是在 v-for 上使用 track-by。
而Angular 2 和 Vue 用相似的设计解决了一些 Angular 1 中存在的问题。
VS React
同:都提供数据驱动、可组合搭建的视图组件。异:
1.内部实现本质不同。React 的渲染建立在 Virtual DOM 上——一种在内存中描述 DOM 树状态的数据结构。当状态发生变化时,React 重新渲染 Virtual DOM,比较计算之后给真实 DOM 打补丁。
2.Virtual DOM 提供了函数式的方法描述视图,它不使用数据观察机制,每次更新都会重新渲染整个应用,因此从定义上保证了视图与数据的同步。它也开辟了 JavaScript 同构应用的可能性。
3.Vue.js 不使用 Virtual DOM 而是使用真实 DOM 作为模板,数据绑定到真实节点。Vue.js 的应用环境必须提供 DOM。但是,相对于常见的误解——Virtual DOM 让 React 比其它的都快, Vue.js 实际上性能比 React 好,而且几乎不用手工优化。而* React,为了最优化的渲染需要处处实现 shouldComponentUpdate 和使用不可变数据结构*。
4.在 API 方面,React(或 JSX)的一个问题是,渲染函数常常包含大量的逻辑,最终看着更像是程序片断而不是界面的视觉呈现。对于部分开发者来说,他们可能觉得这是个优点,但对那些像我一样兼顾设计和开发的人来说,模板能让我们更好地在视觉上思考设计和 CSS。JSX 和 JavaScript 逻辑的混合干扰了我将代码映射到设计的思维过程。相反,Vue.js 通过在模板中加入一个轻量级的 DSL (指令系统),换来一个依旧直观的模板,且能将逻辑封装进指令和过滤器中。
5.React 的另一个问题是:DOM 更新完全交给 Virtual DOM,想要自己控制 DOM 时就比较棘手。如果应用需要特别的自定义 DOM 操作,特别是复杂时间控制的动画,这个限制就很讨厌。在这方面,Vue.js 更灵活。
React的函数式特质,可以很好地使用函数式编程模式。但是对于初级开发者和初学者这也导致较大的学习难度。Vue 更易学习和开发。
对于大型应用,React 社区已经创造了大量的状态管理方案,如 Flux/Redux。Vue 本身不解决这个问题,但是可以轻松地修改状态管理模式,实现一个类似的架构。Vue 有自己的状态管理方案 Vuex,而且 Vue 也可以与 Redux 一起用。
Vue 的 单文件组件 在把 CSS 封装到组件模块的同时仍然允许你使用喜欢的预处理器。
Vue 实例
创建Vue实例:
每个 Vue 应用的起步都是通过构造函数 Vue() 创建 Vue 的根实例:var vm = new Vue({ // 选项 })
一个 Vue 实例是一个ViewModel (MVVM 模式) 。
在实例化 Vue 时,要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。
Vue实例的属性与方法
1.数据属性每个 Vue 实例都会代理其 data 对象里所有的属性:
var data = { a: 1 } var vm = new Vue({ el:'id1', //el:绑定id data: data //data:绑定数据 }) vm.a === data.a // -> true vm实例的数据与其data所绑定的对象的数据是保持一致的
只有这些被代理的属性是响应的。在实例创建之后添加新的属性到实例上不会触发视图更新。
注意只有这些被代理的属性是响应的。如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。我们将在后面详细讨论响应系统。
2.其他属性与方法
除了data属性代理数据,Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $ ,如:
var data = { a: 1 } var vm = new Vue({ el: '#example', data: data }) vm.$data === data // Vue实例对象.$data 绑定了数据 vm.$el === document.getElementById('example') // .$el绑定了id // $watch 是一个实例方法,当Vue实例的某属性改变后触发回调函数 vm.$watch('a', function (newVal, oldVal) { // 这个回调在 `vm.a` 改变后调用 })
Vue实例的生命周期
Vue 实例在创建时有一系列初始化步骤,它也将调用一些生命周期钩子,给自定义逻辑提供运行机会。例如 created 钩子在实例创建后调用:var vm = new Vue({ data: { a: 1 }, created: function () { //注意这个函数 // `this` 指向 vm 实例 console.log('a is: ' + this.a) } })
也有一些其它的钩子,在实例生命周期的不同阶段调用,如 compiled、 ready 、destroyed。钩子的 this 指向调用它的 Vue 实例。Vue.js 没有“控制器”的概念。组件的自定义逻辑可以分割在这些钩子中。
数据绑定
Vue拥抱数据驱动的视图概念。即:在普通 HTML 模板中用特殊语法将 DOM “绑定”到底层数据。一旦创建绑定,DOM 将与数据保持同步。每当修改数据,DOM 便相应地更新。这样我们应用中的逻辑就几乎都是直接修改数据了,不必与 DOM 更新搅在一起。这让我们的代码更容易撰写、理解与维护。<!--1. 这是 View,即html--> <div id="example-1"> Hello {{ name }}! </div>
// 2.这是 Model,即数据量或数据对象 var exampleData = { name: 'Vue.js' } // 3.这是Vue 实例(作为ViewModel) // 它连接 View 与 Model // 通过new Vue()创建,el绑定视图的id,data绑定data的数据 var exampleVM = new Vue({ el: '#example-1', data: exampleData })
DOM 会自动响应数据的变化。
Vue.js 模板通过一些特殊的特性做了html的增强。Vue 模板因而从根本上不同于基于字符串的模板。
绑定值
1.文本(双大括号绑定显示)<span>Message: {{ msg }}</span>
每当这个属性变化时标签中显示的值也会更新。
如果只处理单次插值,今后的数据变化不想再引起插值更新,就在{{后加 *。
2.原始的 HTML
为输出 HTML 字符串,需要用{{{ }}}。
在网站上动态渲染任意 HTML 很危险,容易导致 XSS 攻击。记住,只对可信内容使用 HTML 插值,永不用于用户提交的内容。
3.HTML 特性
{{}}也可以用在 HTML 特性内:
<div id="item-{{ id }}"></div>
注意: Vue.js 指令和特殊特性内不能用插值。
绑定 JS 表达式
用{{JS 表达式}},如:{{ message.split('').reverse().join('') }}
每个绑定只能包含单个表达式,且不能绑定js语句。
过滤器
{{ message | 过滤器 }} //可接多个 | 过滤器
过滤器接受参数:
{{ message | filterA 'arg1' arg2 }}
过滤器函数始终以表达式的值作为第一个参数。后面跟的参数作为第2,3,…个参数。带引号的参数视为字符串,而不带引号的参数按表达式计算。
指令
指令带有前缀 v-,以指示它们是 Vue.js 提供的特殊特性,它们会对绑定的目标元素添加响应式的特殊行为。指令的值限定为绑定表达式,因此上面提到的 JavaScript 表达式及过滤器规则在这里也适用。
如:v-if
<div id="example-2"> <p v-if="greeting">Hello!</p> </div>
var exampleVM2 = new Vue({ el: '#example-2', data: { greeting: true } })
指令绑定参数
有些指令可以名称后带一个“参数”,中间用冒号隔开。如,v-bind 指令用于响应地更新 HTML 特性:<a v-bind:href="url"></a>
这里 href 是参数,它告诉 v-bind 指令将元素的 href 特性跟表达式 url 的值绑定。用特性插值 href=”{{url}}” 能获得同样的结果。
再如 v-on 指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">
这里参数是被监听的事件的名字。
修饰符
修饰符以半角句号 . 开始的特殊后缀,用于表示指令应当以特殊方式绑定。例如 .literal 修饰符告诉指令将它的值解析为一个字面字符串而不是一个表达式:<a v-bind:href.literal="/a/b/c"></a>
指令缩写
Vue.js 为两个最常用的指令 v-bind 和 v-on 提供特别的缩写:(1)v-bind缩写为冒号(:)
<!-- 完整语法 --> <button v-bind:disabled="someDynamicCondition">Button</button> <!-- 缩写 --> <button :disabled="someDynamicCondition">Button</button>
(2)v-on: 缩写为 @
<!-- 完整语法 --> <a v-on:click="doSomething"></a> <!-- 缩写 --> <a @click="doSomething"></a>
这些缩写用的多了还是能够提高编码效率的。
过渡
Vue指令不仅可以绑定 DOM 文本到数据,也可以绑定 DOM 结构 到数据。而且,Vue提供一个强大的过渡效果系统,可以在 Vue 插入/删除元素时自动应用过渡效果。通过 Vue.js 的过渡系统,可以在元素从 DOM 中插入或移除时自动应用过渡效果。Vue.js 会在适当的时机为你触发 CSS 过渡或动画,你也可以提供相应的 JavaScript 钩子函数在过渡过程中执行自定义 DOM 操作。
为应用过渡效果,需要在目标元素上使用 transition 特性:
<div v-if="show" transition="my-transition"></div>
transition 特性可以与下面资源一起用:
v-if;
v-show;
v-for (只在插入和删除时触发,使用 vue-animated-list 插件);
动态组件 ;
在组件的根节点上,并且被 Vue 实例 DOM 方法(如 vm.$appendTo(el))触发;
当插入或删除带有过渡的元素时,Vue 将:
尝试以 ID “my-transition” 查找 JS 过渡钩子对象——通过 Vue.transition(id, hooks) 或 transitions 选项注册。如果找到,将在过渡的不同阶段调用相应的钩子。
自动嗅探目标元素是否有 CSS 过渡或动画,并在合适时添加/删除 CSS 类名。
如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作(插入/删除)在下一帧中立即执行。
事件处理
用 v-on 指令监听 DOM 事件(v-on:事件名=“事件处理方法名”),如:<div id="example"> <button v-on:click="greet">Greet</button> </div>
这里的greet是事件处理器绑定的事件处理方法,在 Vue 实例中定义这个方法:
var vm = new Vue({ el: '#example', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // 方法内 `this` 指向 vm alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 alert(event.target.tagName) } } }) // 也可以在 JavaScript 代码中调用方法 vm.greet() // -> 'Hello Vue.js!'
除了直接绑定到一个方法,也可以在v-on 指令的值中使用内联 JavaScript 语句。
<div id="example-2"> <button v-on:click="say('hi')">Say Hi</button> <button v-on:click="say('what')">Say What</button> </div>
new Vue({ el: '#example-2', methods: { say: function (msg) { alert(msg) } } })
这里的say(‘hi’)就直接使用了js语句,并传入了参数。
组件
组件系统是 Vue的一个重要概念,它提供一种抽象,让我们可以用独立可复用的小组件构建大型应用。它是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
一个典型的用 Vue 构建的大型应用可以抽象为一个组件树。
Vue.js 组件非常类似于 自定义元素—— Web 组件规范(即WebComponents)的一部分。Vue.js 的组件语法参考了该规范,但有几个关键的不同:
Web 组件规范仍远未完成,且没有浏览器实现。而Vue.js 组件不需要任何补丁,并且在所有支持的浏览器下表现一致。
Vue.js 组件提供了原生自定义元素所不具备的一些重要功能,比如组件间的数据流,自定义事件系统,以及动态的、带特效的组件替换。
注册组件
可以用 Vue.extend() 创建一个组件构造器:var MyComponent = Vue.extend({ // 选项... })
要把这个构造器用作组件,需要用 Vue.component(tag, constructor) 注册 :
// 全局注册组件,tag 为 my-component Vue.component('my-component', MyComponent)
注:对于自定义标签名,最好遵循 W3C 规则(小写,并包含一个短杠)。
组件在注册之后,便可以在父实例的模块中以自定义元素 如: 的形式使用:
<div id="example"> <my-component></my-component> </div>
// 定义 var MyComponent = Vue.extend({ template: '<div>A custom component!</div>' }) // 注册 Vue.component('my-component', MyComponent) // 创建根实例 new Vue({ el: '#example' })
渲染的时候回渲染为:
<div id="example"> <div>A custom component!</div> </div>
组件的模板会自动替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项 replace 决定是否替换。
相关文章推荐
- Vue.js基本规则提炼总结及计算属性学习
- 前端框架学习总结之Angular、React与Vue的比较详解
- 前端学习总结(二十三)——前端框架天下三分:Angular React 和 Vue的比较
- Vue.js学习(五):vue+axios+php+mysql 实现前端界面数据动态更新
- vue.js总结学习
- 前端框架vue.js 学习
- Vue.js 学习要点总结(二)
- 自己总结前端web知识学习——太多太多(html/css/js/php)
- vue.js学习总结
- web前端学习日记32-----vuejs相关学习
- Vue.js 学习总结
- 前端开发工具vue.js开发实践总结
- Vue.js学习总结思维导图(一)
- 前端框架学习总结之Angular、React与Vue的比较详解
- 前端学习总结(七)Angular.js——以数据交互为核心的前端框架
- vue.js做前端工程总结
- Vue.js 学习要点总结(一)
- vue.js学习笔记(三)--父子组件通信总结
- Vue.js总结学习(指令、计算属性、数据绑定)
- 【学习点滴-js】js学习总结。