在这篇文章中,将会介绍新版本的新特性, 好比slots
的新语法,Vue.observable()
等等javascript
这是一个比较重大的改变,包含的有:html
slot
和 slot-scope
的功能scoped slots
的简写以前在Vue@2.5.22中是这样使用scoped-slots
的:vue
<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>
复制代码
如今是这样的:java
<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>
复制代码
默认插槽:api
<template>
<! - v-slot is used directly on the parent ->
<TestComponent v-slot="{message}">
<div>
{{`Default slot with message: ${message}`}}
</ div>
</ TestComponent>
</ template>
复制代码
具名插槽:promise
<template>
<TestComponent>
<! - # 简写: ->
<template #text="{text}">
<div>
{{`Named slot with text: ${text}`}}
</ div>
</ template>
</ TestComponent>
</ template>
复制代码
新版中,能够不使用任何做用域插槽变量,可是仍然能够经过父组件的$scopedSlots
去引用到浏览器
若是咱们想在v-bind
or v-on
中使用动态变量,在Vue@2.5.22中:app
<div v-bind="{ [key]: value }"></div>
<div v-on="{ [event]: handler }"></div>
复制代码
可是这个例子有几个缺点:异步
不是全部人都知道在v-bind / v-on
中可使用动态变量名async
vue-template-compier
生成了低效的代码
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>
复制代码
以前,建立一个响应对象,必须在一个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>
);
},
};
复制代码
在新的升级版本中,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);
});
复制代码
在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>
复制代码
如今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"
复制代码
新版本中,增长了一个vue.esm.browser.js。它是为了支持ES6 Modules的浏览器设计的。
特性:
举例:
<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> 复制代码
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>
复制代码
规则很简单:若是重写了对象的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!
复制代码
在新版本中,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>
复制代码