Vue 2.6尝鲜

昨天Vue 2.6 "Macross" 发布了,同时也是Vuejs五周年~

在这篇文章中,将会介绍新版本的新特性, 比如 slots的新语法, Vue.observable()等等

1. Scoped slots(作用域插槽)的新语法

这是一个比较重大的改变,包含的有:

  • v-slot新指令,结合了 slotslot-scope的功能
  • scoped slots的简写

之前Vue@2.5.22中是这样使用 scoped-slots的:

<template>
   <TestComponent>
     <! - 默认 scoped slot ->
     <div slot-scope="{message}">
       {{`Default slot with message: ${message}`}}
     </ div>
     <! - 具名 scoped slot ->
     <div slot="text" slot-scope="{text}">
       {{`Named slot with text: ${text}`}}
     </ div>
   </ TestComponent>
</ template>

现在是这样的:

<template>
   <TestComponent>
     <! - 默认 scoped slot ->
     <template v-slot="{message}">
       <div>
         {{`Default slot with message: ${message}`}}
       </ div>
     </ template>
     <! - 具名 scoped slot ->
     <template v-slot:text="{text}">
       <div>
         {{`Named slot with text: ${text}`}}
       </ div>
     </ template>
   </ TestComponent>
</ template>

默认插槽:

<template>
   <! - v-slot is used directly on the parent ->
   <TestComponent v-slot="{message}">
     <div>
       {{`Default slot with message: ${message}`}}
     </ div>
   </ TestComponent>
</ template>

具名插槽:

<template>
   <TestComponent>
     <! - # 简写: ->
     <template #text="{text}">
       <div>
         {{`Named slot with text: ${text}`}}
       </ div>
     </ template>
   </ TestComponent>
</ template>

新版中,可以不使用任何作用域插槽变量,但是仍然可以通过父组件的 $scopedSlots去引用到

2. 动态参数指令

如果我们想在 v-bind or v-on中使用动态变量,在Vue@2.5.22中:

<div v-bind="{ [key]: value }"></div>
<div v-on="{ [event]: handler }"></div>

但是这个例子有几个缺点:

  • 不是所有人都知道在 v-bind/v-on中可以使用动态变量名
  • vue-template-compiler 生成了低效的代码
  • v-slot没有类似的使用对象的语法

为了解决这些问题, Vue@2.6.0引入了一个新语法:

<div v-bind:[key]="value"></div>
<div v-on:[event]="handler"></div>

举个例子:

<template>
   <div>
     <! - v-bind 动态key ->
     <div v-bind:[key]="value"> </ div>

     <! - 简写 ->
     <div :[key]="value"> </ div>

     <! - v-on 动态事件,event变量 ->
     <div v-on:[event]="handler"> </ div>

     <! - 简写 ->
     <div @[event]="handler"> </ div>

     <! - v-slot 动态名字 ->
     <TestComponent>
       <template v-slot:[name]>
         Hello
       </ template>
     </ TestComponent>

     <! - 简写 ->
     <TestComponent>
       <template #[name]>
         Cool slot
       </ template>
     </ TestComponent>
   </ div>
</ template>

3. 使用Vue.observable()创建一个响应对象

之前,创建一个响应对象,必须在一个Vue实例中配置。现在我们可以在Vue实例外部,通过使用 Vue.observable(data)创建,如下:

import vue from vue;
const state = Vue.observable ({
   counter: 0,
});
export default {
   render () {
     return (
       <div>
         {state.counter}
           <button v-on:click={() => {state.counter ++; }}>
           Increment counter
         </ button>
       </ div>
     );
   },
};

4. server端获取数据

在新的升级版本中, vue-server-renderer改变了SSR的数据加载策略。

之前,我们推荐使用 asyncData()router.getMatchedComponents()方法中获取的组件中,获取数据。

新版本中有一个特别的组件方法: serverPrefetch() 。vue-server-renderer会在每个组件中调用它,它会返回一个promise。

<template>
   <div v-if="item">
     {{item.name}}
   </ div>
</ template>
<script>
export default {
   // Call on the server
   async serverPrefetch () {
     await this.fetchItem();
   },
   computed: {
     item () {
       return this.$store.state.item;
     },
   },
   // Call on client
   mounted () {
     if (!this.item) {
       this.fetchItem();
     }
   },
   methods: {
     async fetchItem () {
       await this.$store.dispatch('fetchItem');
     },
   },
};
</ script>

serverPrefetch()执行之后,我们需要知道应用在什么时候渲染完成,在server render 上下文中,我们可以使用 rendered()钩子方法。

/ * Simplified entry-server.js * /
import {createApp} from './app';
export default context => new Promise ((resolve, reject) => {
   const {app, router, store} = createApp();
   const {url} = context;
   router.push(url);
   router.onReady(() => {
     context.rendered = () => {
       context.state = store.state;
     };
     resolve (app);
   }, reject);
});

5. 改进的错误输出

render方法中编译html, vue-template-compiler可能会产生错误。在之前,Vue会产生一个没有位置的错误描述。新版本中会展示这个错误出现在哪里,比如:

<template>
  <div>
    <template key="test-key">
      {{ message }}
    </template>
  </div>
</template>

vue-template-compiler@2.5.22中:

Error compiling template:
<div>
    <template key="test-key">
      {{ message }}
    </template>
  </div>
- <template> cannot be keyed. Place the key on real elements instead.

vue-template-compiler@2.6.0中:

Errors compiling template:
<template> cannot be keyed. Place the key on real elements instead.
1  |
2  |  <div>
3  |    <template key="test-key">
   |              ^^^^^^^^^^^^^^
4  |      {{ message }}
5  |    </template>

6. 捕捉异步错误

现在Vue可以在生命周期方法钩子和事件方法中捕捉到异步错误异常。比如:

/ * TestComponent.vue * /
<template>
   <div @click="doSomething()">
     Some message
   </ div>
</ template>
<script>
export default {
   methods: {
     async doSomething () {
       await this.$nextTick ();
       throw new Error ('Another Error');
     },
   },
   async mounted () {
     await this.$nextTick ();
     throw new Error ('Some Error');
   },
};
</ script>

mount后错误:

[Vue warn]: Error in mounted hook (Promise/async): "Error: Some Error"

点击事件后错误:

[Vue warn]: Error in v-on handler (Promise/async): "Error: Another Error"

7. ESM 浏览器中的新版构建

新版本中,增加了一个vue.esm.browser.js。它是为了支持ES6 Modules的浏览器设计的。

特性:

  • 在render函数中,包含HTML编译器
  • 使用ES6模块语法
  • 包含非副本代码(non-transcript)

举例:

<html lang="en">
   <head>
     <title> Document </ title>
   </ head>
   <body>
     <div id="app">
       {{message}}
     </ div>
     <script type="module">
       import Vue from 'path/to/vue.esm.browser.js';
       new Vue {{
         el: '#app',
         data () {
           return {
             message: 'Hello World!',
           };
         },
       });
     </ script>
   </ body>
</ html>

8. v-bind.prop简写

v-bind指令有一个特殊的修饰符--- .prop。你可以在文档中查看具体用法。我自己从没使用过,暂时也想不到在什么时候使用。

现在有一个简写方式,对于 v-bind:someProperty.prop="foo", 可以写成 .someProperty="foo"

Vue@2.5.22中:

<template>
   <div>
     <div v-bind:textContent.prop="'Important text content'" />
     <! - 简写版本 ->
     <div: textContent.prop="'Important text content'" />
   </ div>
</ template>

Vue@2.6.0:

<template>
  <div .textContent="'Important text content'" />
</template>

9. 支持自定义toString()

规则很简单:如果重写了对象的 toString()方法,显示的时候,Vue将使用它,而不是 JSON.stringify()

举例:

/ * TestComponent.vue * /
<template>
   <div>
     {{message}}
   </ div>
</ template>
<script>
export default {
   data () {
     return {
       message: {
         value: 'qwerty',
         toString () {
           return 'Hello Habr!';
         },
       },
     };
   },
};
</ script>

Vue@2.5.22中显示:

{ "value": "qwerty" }

Vue@2.6.0:

Hello Habr!

10. v-for和可迭代对象

在新版本中, v-for可以遍历任何实现了[iterable 协议]的对象,比如Map, Set

2.X版本中,Map和Set, 不支持数据响应。

举例:

/ * TestComponent.vue * /
<template>
   <div>
     <div
       v-for="item in items"
       :key="item"
     >
       {{item}}
     </ div>
   </ div>
</ template>
<script>
export default {
   data () {
     return {
       items: new Set([4, 2, 6]),
     };
   },
};
</ script>

本文分享自微信公众号 - 前端知否(qianduanzhifou),作者:QETHAN

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue.js render函数那些事儿

    大多时候,我会使用template, vue单文件去渲染组件。虽然知道Vue中有个render函数,但却很少在项目中去主动使用它。使用最多的地方是在使用一些UI...

    前端知否
  • 如何在Vuejs中实现页面空闲超时检测

    您是否需要检查用户在Vue应用程序中的不活跃状态?如果用户在一段时间内处于非活动状态,则要自动注销该用户或显示一个计时器。通常,具有机密数据的系统(如银行)通常...

    前端知否
  • Vue.js中的延迟加载和代码拆分

    虽然现在网络环境和电子设备变得越来越好,但是保持应用程序快速加载变得越来越困难。在本系列中,我将深入研究我们在实践中使用的Vue性能优化技术,并且您可以在Vue...

    前端知否
  • 一天带你入门到放弃vue.js(三)

    自己新建的标签赋予特殊功能的是组件,而指定是在标签上使用类似于属性,以v-name开头,v-on,v-if...是系统指令! v-是表示这是vue的指令if,f...

    用户1518699
  • 一天带入门到放弃vue.js(三)

    自己新建的标签赋予特殊功能的是组件,而指定是在标签上使用类似于属性,以v-name开头,v-on,v-if...是系统指令! v-是表示这是vue的指令if,f...

    十月梦想
  • CSS基础

    CSS 语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明。 1 2 3 4 5 6 7 8 9 ''' ...

    用户1214487
  • Oracle常见错误集锦

    1、ORA-12560:TNS:协议适配器错误 OracleService<SID>服务没有启动 2、 ORA-12541:TNS:无监听程序 Oracle<...

    陈树义
  • EMR(弹性MapReduce)入门之EMR集群的基础排障(五)

    前面四节已经向大家介绍完,EMR集群的概括和搭建以及集群内的一些操作,在实际的生产过程中,又会出现各式各样的故障。接着就为大家介绍一些常见的故障已经解决方法。

    小司机带你入门EMR
  • 自定义 Discuz 样式

    discuz根目录——》template——》default——》forum——》discuz.htm

    阳光岛主
  • 谷歌发布Poly API,直接在VR中寻找3D资源

    Poly是一个免版税的3D对象和“场景”库,开发者可以将相关内容应用至VR或增强现实应用,游戏和其他程序。谷歌希望为创作者提供填充世界的3D对象,从而提高他们的...

    BestSDK

扫码关注云+社区

领取腾讯云代金券