Comparison Between Vue 1 and Vue 2

模板语法

插值

  • Vue 2 提供了 v-once 指令进行一次插值,替代了 Vue 1 的 {{ * msg }}
  • Vue 2 提供了 v-html 插入纯 HTML 文本,替代了 Vue 1 的 {{{ rawHTML }}}�
  • Vue 2 取消了在元素属性中直接使用 Mustache 语法的做法,所有的元素属性都要用 v-bind 进行绑定。
  • Vue 2 为模板表达式添加了白名单,在模板中只能访问白名单内的全局变量。

过滤器

  • 在 Vue 2 中,过滤器只能在 mustache 绑定和 v-bind 表达式中使用,对于更复杂的数据变换应当使用计算属性

Class 与 Style 绑定

绑定 HTML Class

  • Vue 2 允许 v-bind:class 与普通的 class 属性共存。
  • Vue 2 中,在一个定制的组件上用到 class 属性的时候,这些类将被添加到根元素上面,这个元素上已经存在的类不会被覆盖。

条件渲染

v-if

  • Vue 2 添加了 v-else-if

  • Vue 2 中,可以使用 key 管理 v-if 上不可复用的元素( key 必须唯一 ):

    <template v-if="loginType === 'username'">
      <label>Username</label>
      <input placeholder="Enter your username" key="username-input">
    </template>
    <template v-else>
      <label>Email</label>
      <input placeholder="Enter your email address" key="email-input">
    </template>
    

    没有添加 key 属性的元素仍然会被复用。

v-show

  • Vue 2 完全放弃了 v-show 中的 v-else 语法,同时 v-show 也不支持 <template> 语法。

v-for

  • Vue 2 添加了对象迭代 v-for

    • 可以用 v-for 通过一个对象的属性来迭代。

      <ul id="repeat-object" class="demo">
        <li v-for="value in object">
          {{ value }}
        </li>
      </ul>
      
      new Vue({
        el: '#repeat-object',
        data: {
          object: {
            FirstName: 'John',
            LastName: 'Doe',
            Age: 30
          }
        }
      })
      
    • 也可以提供第二个参数为键名,第三个参数为索引。

      <div v-for="(value, key) in object">
        {{ key }} : {{ value }}
      </div>
      
      <div v-for="(value, key, index) in object">
        {{ index }}. {{ key }} : {{ value }}
      </div>
      
  • Vue 2 还提供了整数迭代 v-for

    <div>
      <span v-for="n in 10">{{ n }}</span>
    </div>
    
  • Vue 2 还提供了组件 v-for 。但是组件 v-for 不能自动传递数据到组件里,因为组件有自己的独立作用域,要使用 props 传递。

    <my-component
      v-for="(item, index) in items"
      v-bind:item="item"
      v-bind:index="index">
    </my-component>
    

key

  • 从 Vue 2 开始,Vue 不再需要用户显式使用 Vue 1 提供的 track-by="$index" 语法,而是提供了一套类似的“就地复用”策略。但是这个策略只适用于不依赖子组件状态或者临时 DOM 状态(例如:表单输入值)的列表渲染输出。

  • 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,要为每项提供一个唯一 key 属性。理想的 key 值是每项都有唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以要用 v-bind 来绑定动态值。

    <div v-for="item in items" :key="item.id">
      <!-- 内容 -->
    </div>
    
  • 建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。(通常情况下,所有自定义组件和依赖于临时 DOM 状态的组件都应当绑定 key 属性。)

事件处理器

事件修饰符

  • Vue 2 相比 Vue 1 提供了更丰富的事件修饰符:

    <!-- 阻止单击事件冒泡 -->
    <a v-on:click.stop="doThis"></a>
    <!-- 提交事件不再重载页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
    <!-- 修饰符可以串联  -->
    <a v-on:click.stop.prevent="doThat"></a>
    <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
    <!-- 添加事件侦听器时使用事件捕获模式 -->
    <div v-on:click.capture="doThis">...</div>
    <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
    <div v-on:click.self="doThat">...</div>
    <!-- 2.14 新增:点击事件将只会触发一次 -->
    <a v-on:click.once="doThis"></a>
    

    .once 修饰符还能被用到自定义的组件事件上。

按键修饰符

  • Vue 2 相比 Vue 1 提供了更丰富的按键别名。

  • 全部按键别名

  • Vue 2 修改了自定义按键修饰符别名的方式 - 使用 Vue.config.keyCodes

    // 可以使用 v-on:keyup.f1
    Vue.config.keyCodes.f1 = 112
    

表单控件绑定

修饰符

  • Vue 2 修改了绑定修饰符的方法:

    <input v-model.number="age" type="number"> // type="number" 是原生 DOM 属性。
    
  • Vue 2 添加了 .trim 修饰符,用于去掉输入字符串首尾的空格。

    <input v-model.trim="msg">
    

v-model 与组件

  • 可以说 Vue 2 实现的 v-model 才是真正的 v-model
  • Vue 2 的组件系统允许你创建一个具有自定义行为可复用的 input 类型,这些 input 类型甚至可以和 v-model 一起使用!要了解更多,请参阅自定义 input 类型

组件

使用组件

  • 在 Vue 2 中,对 DOM 模板的验证放宽了。对于一些 HTML 有限制的元素,在下列环境下将不受限制:

    • <script type="text/x-template">
    • JavaScript 内联模板字符串
    • .vue 组件
  • data 必须是函数:在 Vue 2 中,data 被强制要求成了函数。

Prop

  • 在 Vue 2 中使用字符串模板时,不需要将 camelCase 转换成 kebab-case
  • Vue 2 不允许在子组件内部改变 prop,即便使用双向绑定也不行。应当通过子组件触发 event 由父组件捕获,或者其他方式更改 prop
    • 在 JavaScript 中对象和数组是引用类型,指向一个内存空间。所以如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

自定义组件

  • 在 Vue 2 中,不能用 $on 侦听子组件抛出的事件,必须要在模板里直接用 v-on 绑定。

  • Vue 2 移除了 Vue 选项中的 events 选项。

  • 在 Vue 2 中,如果要在某个组件的根元素上监听原生事件,要使用 .native 修饰 v-on

    <my-component v-on:click.native="doTheThing"></my-component>
    
  • 在 Vue 2 中,v-model 实现了一个语法糖:在自定义的 Input 组件中使用 v-model 进行数据绑定时,组件内要接收一个 value 属性,并在有新的 value 时触发 input 事件。其余的事情 v-model 会自动处理。一个官方示例(使用的是字符串模板):

    <currency-input v-model="price"></currency-input>
    
    Vue.component('currency-input', {
      template: '\
        <span>\
          $\
          <input\
            ref="input"\
            v-bind:value="value"\
            v-on:input="updateValue($event.target.value)"\
          >\
        </span>\
      ',
      props: ['value'],
      methods: {
        // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
        updateValue: function (value) {
          var formattedValue = value
            // 删除两侧的空格符
            .trim()
            // 保留 2 小数位
            .slice(0, value.indexOf('.') + 3)
          // 如果值不统一,手动覆盖以保持一致
          if (formattedValue !== value) {
            this.$refs.input.value = formattedValue
          }
          // 通过 input 事件发出数值
          this.$emit('input', Number(formattedValue))
        }
      }
    })
    
  • Vue 2 取消了 $dispatch$broadcast ,可以使用 bus 替代。

  • 非父子组件通信:

    • Vue 2 给出了一个新的思路用于处理简单场景的组件通信:使用一个空的 Vue 实例当做中央事件总线:

      var bus = new Vue()
      
      // 触发组件 A 中的事件
      bus.$emit('id-selected', 1)
      
      // 在组件 B 创建的钩子中监听事件
      bus.$on('id-selected', function (id) {
        // ...
      })
      

使用 slot 分发内容

  • Vue 2 提供了作用域插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。在子组件中,只需要将数据传递到插槽,就像使用 prop 一样:

    <div class="child">
      <slot text="hello from child"></slot>
    </div>
    

    在父级中,具有特殊属性 scope<template> 元素,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 prop 对象。

    <div class="parent">
      <child>
        <template scope="props">
          <span>hello from parent</span>
          <span>{{ props.text }}</span>
        </template>
      </child>
    </div>
    

    渲染结果:

    <div class="parent">
      <div class="child">
        <span>hello from parent</span>
        <span>hello from child</span>
      </div>
    </div>
    
  • 一个作用域插槽更实用的例子:

    <my-awesome-list :items="items">
      <!-- 作用域插槽也可以在这里命名 -->
      <template slot="item" scope="props">
        <li class="my-fancy-item">{{ props.text }}</li>
      </template>
    </my-awesome-list>
    

    列表组件模板:

    <ul>
      <slot name="item"
        v-for="item in items"
        :text="item.text">
        <!-- fallback content here -->
      </slot>
    </ul>
    // 这边应该定义了一个叫 items 的 prop ,然后父组件 :items="items" 传进去。
    
  • 在 Vue 2 中 keep-alive 变成元素了,而不是一个指令或者参数。

    <keep-alive>
      <component :is="currentView">
        <!-- 非活动组件将被缓存! -->
      </component>
    </keep-alive>
    

杂项

  • Vue 2 修改了 v-ref 的用法,并合并了 v-el ,新的属性叫 ref ,用于访问子组件(访问的方式不变):

    <div id="parent">
      <user-profile ref="profile"></user-profile>
    </div>
    
    var parent = new Vue({ el: '#parent' })
    // 访问子组件
    var child = parent.$refs.profile
    
    • 要注意的是,$refs 只在组件渲染完成后才填充,而且是非响应式的。所以应当避免在模板或计算属性中使用 $refs
  • Vue 2 引入了一种新的定义模板的方式: X-Template

    <script type="text/x-template" id="hello-world-template">
      <p>Hello hello hello</p>
    </script>
    
    Vue.component('hello-world', {
      template: '#hello-world-template'
    })
    
    • 这在有很多模版或者小的应用中有用,否则应该避免使用,因为它将模版和组件的其他定义隔离了。

Render 函数

  • Vue 2 新增了 Render 函数,一个例子:

    Vue.component('anchored-heading', {
      render: function (createElement) {
        return createElement(
          'h' + this.level,   // tag name 标签名称
          this.$slots.default // 子组件中的阵列
        )
      },
      props: {
        level: {
          type: Number,
          required: true
        }
      }
    })
    
    • 需要知道当你不使用 slot 属性向组件中传递内容时, 这些子元素被存储在组件实例中的 $slots.default 中。详见 instance properties API
  • 更详细的内容可以参考官方文档

自定义指令

钩子函数

  • Vue 2 扩充了指令的钩子函数:
    • bind : 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
    • inserted : 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
    • update : 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
    • componentUpdated : 被绑定元素所在模板完成一次更新周期时调用。
    • unbind : 只调用一次, 指令与元素解绑时调用。
  • 有关钩子函数的详细信息可以查看官方文档
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,127评论 0 6
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 4,989评论 0 29
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,916评论 4 129
  • 内购的前提: 有个人开发者账号;开通了银行业务;在开发者后台添加了内购产品;创建了相应的Bundle id 和证书...
    无wu阅读 766评论 0 0
  • 一样的人,爬同一座山,有人到了山顶后返回,有人半路返回。最后结果一样,有些东西却是不一样了。
    秦素素素素素素阅读 294评论 0 0