来公司以后就一直在用vue框架,不管是业务代码,还是做vue组件。关于vue有一些点是文档中没有提及的,记录一下以便以后查询~
一、Vue的特点
新一代 Vue.js 框架非常关注如何用极少的外部特性来解决应用程序/视图状态同步问题。
Vue.js 大部分是基于vue实例(var vm = new Vue({ ... }))完成的。Vue.js 负责给浏览器 DOM 中绑定数据。
1、特点 —— 这部分借鉴浅谈Vue.js的几个特点
(1) 简洁 (2) 轻量 (3)快速 (4) 数据驱动 (5) 模块友好 (6) 组件化
2、vue与angularJS的区别
与angularJS1对比
vue很多的语法是借鉴的angular,比如v-if/ng-if、v-model、ng-model等。
复杂性
在API与设计两方面上Vue.js都比Angular1简单得多。vue的源码比angularJS小了将近一半
比如绑定点击事件:v-on:click='doSomething' 可写成 @click='doSomthing'
绑定动态数据:v-bind:href='url' 可写成 :href='url'
数据绑定
angular1使用双向数据绑定,vue在不同组件间强制使用单向数据流。尤其vue2.0中父子间也强制只能父向子传递数据。这使应用中的数据流更加清晰易懂。
而且angularJS绑定数据的代码也不如vue简洁。angular里有什么ng-app/ng-controller等等设置起来比较繁琐
性能
Vue 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。
在 Angular 1 中,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环(digest cycle)可能要运行多次。
Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。
Vue 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步队列更新,所有的数据变化都是独立触发,除非它们之间有明确的依赖关系。
组件与指令
在 Vue 中指令和组件分得更加清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑
但是,在angular中两者有不少相混的地方。
与angularJS2对比
angularjs2实际是一个全新的框架了,而且还用vue一样的思路解决了angularJS1里的一些问题。angular1 面向的是较小的应用程序,angular2 已转移焦点,面向的是大型企业应用。
大小和性能
在性能方面,这两个框架都非常的快。
但目前尚没有足够的数据用例来具体展示。如果你一定要量化这些数据,你可以查看第三方参照,它表明 Vue 2 相比 Angular2 是更快的。
在大小方面,vue还是比angular2小得多
虽然 Angular 2 使用 tree-shaking 和离线编译技术使代码体积减小了许多。但包含编译器和全部功能的 Vue2(23kb) 相比 Angular 2(50kb) 还是要小的多。但是要注意,用 Angular 2 的 App 的体积缩减是使用了 tree-shaking 移除了那些框架中没有用到的功能,但随着功能引入的不断增多,尺寸会变得越来越大。
灵活性
Vue 相比于 Angular 2 则更加灵活
Vue 官方提供了构建工具来协助你构建项目,但它并不限制你去如何构建。有人可能喜欢用统一的方式来构建,也有很多开发者喜欢这种灵活自由的方式。
学习曲线
Vue能够快速上手。你使用的是熟悉的 HTML、符合 ES5 规则的 JavaScript(也就是纯 JavaScript)。有了这些基本的技能,你可以快速地掌握它(指南)并投入开发 。
Angular 2 的学习曲线是非常陡峭的。即使不包括 TypeScript,它的开始指南中所用的就有 ES2015 标准的 JavaScript,18个 NPM 依赖包,4 个文件和超过 3 千多字的介绍,这一切都是为了完成个 Hello World。而Vue’s Hello World就非常简单。甚至我们并不用花费一整个页面去介绍它。
二、使用过程中的一些总结
- 首先要提一下vue父实例中的data属性
写成data:function(){return{...}}的形式:表示的是一个返回数据对象的函数,而不是直接返回数据对象。采用该方法的原因是,你创建了一个可在多个位置重用的组件,你不希望所有类型实例共享data字段,如果它是一个直接对象,上述问题就不可避免。
- 过渡效果的实现
vue2.0也是有改动的,不过我实现过渡效果是用的vue1.0的要求实现的,因为公司原有的部分还是应用的vue1.0。大致写下1.0版本下实现的关键点:
// 在标签中加入transition,配合v-if/v-show改变,就触发过渡的css变化 <div v-if="show" transition='fade'> // 或是写成下面这样,然后在vue父实例的data中定义transitionName: 'XXX' <div v-if="show" transition='transitionName'> // 写CSS样式: .fade-transition {} —— 始终保留在元素上的 .fade-enter {} —— 进入过渡状态的一瞬间的样式,结束后删除 .fade-leave {} —— 离开过渡的结束状态的一瞬间的样式,结束即删除 // 还可以配合hooks使用: Vue.transition('fade',{ beforeEnter: function(el){}, enter: function(el){}, alertEnter: function(el){}, ......具体有哪些需要的时候可以看文档~ })
这里你定义的transitionName是XXX,CSS样式这里就写XXX-transition/enter/leave,要对应!
- 还有就是在使用了v-for后,如果我们要动态的去取每一个的值,比如放在方法内做参数,或是放在style中,如何书写?我总结为大致三种写法:
<div class="recommend_shop" v-for="rshop in recommend_shop"> <div class="group_img" :style="{ backgroundImage: 'url('+ rshop.group_header +')'}"v-on:click="openGroup( rshop.group_id )"> </div> <div class="group_info">成交 {{ rshop.goods_nums }}</div> </div>
这里:style="{ backgroundImage:'url('+ ... +')' }" 和 v-on:click="openGroup( ... )"的写法要注意!
- 如何封装组件?
一开始我写组件,只知道组件就是把一个常用的功能封装起来,具体这个封装体现在哪里?就好比你拿一个转换插头,你不知道里面它有什么逻辑,装了什么乱七八糟的东西,但是你提供了一个插孔和一个插头,这个插孔就是组件要预留出来的可能要传进来的一些数据,插头就是组件最后要传给外部的一些外部需要的数据。
- 还有就是slot的使用,
这个我之前也记录过,我当时理解slot的时候把官方文档的三个例子都写了一遍,盯着看了好一会才懂。。。我也是对自己无语了。。。
三、vue2.0的改变点:
- 1.0里的钩子函数ready废弃了,在2.0使用mounted代替。还移除了beforeCompile(Created代替)、compiled(mounted代替),新增了beforeMount、beforeUpdate、update等(这几个我还没用过哈哈)
- events、$dispatch、$broadcast废弃了。
- 子组件给父组件传递参数,发送事件时原来我们使用$dispatch(),但是2.0删掉了这个方法,但是有它的办法来实现,我总结为以下三个关键点(以做过的一个分页组件部分代码为例):
// 在父实例page.js中定义想要操作的事件
data: function(){
curPage: 1
} methods: { changePage: function(){ this.curPage = cur; } }// 在html的<page>标签上添加v-on:click事件 // 父组件用v-on监听事件 <page :data-num="pagedata.length" :each="eachPageSize" :visiblepage="visiblepage" v-on:change-page="changePage"></page>
// 子组件模板(pages是个数字数组) <li v-for="index in pages" v-bind:class="{ active: curPage == index }"> <a v-on:click="btnClick(index)">{{ index }}</a> </li> // 在子组件page.vue中:点击事件中添加:$emit(),将事件传播到父组件 methods: { btnClick: function(index){ this.curPage = index this.$emit('change-page', index) } }
怎么把点击的是哪个数字传到父组件,使父组件可以使用这个数字去做其他的操作?整体流程是:点击子组件中的点击按钮触发btnClick(index)方法,btnClick中,利用this.$emit('change-page',index)触发change-page事件并且将当前的页码值以index参数的形式传到父组件,父组件利用v-on:change-page='changePage'监听到子组件传来的change-page,调用父组件中的changePage方法,在这里完成 “子组件数据传到父组件” 这件事~ this.curPage = index; 这句就将子组件里的点击的那个数字赋值给curPage了,这个curPage是在父组件的data里定义的~~吼吼,就是这么个过程~~
- v-for循环中常用的$index、$key也不支持了。
- 不支持双向绑定啦~v-bind的.once .sync都删掉啦!props里传进来的data值是不可变的!!而且还需要验证~有两种方式会改变props:
- 定义一个局部的data属性,将props的初始值作为局部数据的初始值传入:
props: { navs: { // 从父级传来的navs type: Array , default: function(){ return {} } } } , data: function(){ return { // 这里利用传来的navs来设置初始值cur cur: this.navs[0].en_name } }
- 定义一个computed属性,里面可以定义一些属性从props的值计算得出:
props: { dataNum: { // 传进来的内容总数 type: Number , default: 100 } , each: { // 单页的个数 type: Number , default: 10 } } , computed: { totalPages: function(){ // 计算得出总页数,根据父组件传进来的值的不同得到不同的页数 return Math.ceil(this.dataNum / this.each) || 0 }
用的多了果然觉得顺手多了。。。还是要继续学习~~~最近终于弄明白了原型、原型链还有闭包,接下来要复习一些算法和基础知识~~~回了学校还要写论文,时间真的是不够用。。。不过想到要回家了还是忍不住小激动~今天把上线的所有需求改完,最近一版的工作就告一段落了,看小哥还在学vue2.0改版的内容,我也不好闲着,写完我也去看看。。。同志们共同进步呀~