来公司以后就一直在用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:
  1. 定义一个局部的data属性,将props的初始值作为局部数据的初始值传入:
       props: {
            navs: {         // 从父级传来的navs
                type: Array
                , default: function(){
                    return {}
                }
            }
        }
        , data: function(){
            return {    // 这里利用传来的navs来设置初始值cur
                cur: this.navs[0].en_name
            }
        }  
  2. 定义一个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改版的内容,我也不好闲着,写完我也去看看。。。同志们共同进步呀~