Vue v2.5 调整和更新不完全问题
近日,vue v2.5 发布,除了对 typescript 的更好的支持外,还有一些功能和语法的调整,你需要了解。本文,不谈 typescript,只对一些主要的调整进行说明。
本来,对 vue 的版本升级不怎么敏感,所以没有太关注最近的 v2.5 的发布。今天,在重新下载 vue 构建项目的时候,发现有好几个警告提示。
看警告提示,知道是因为使用了 v2.5 的 vue,scoped slot 的语法进行了调整,然后去 github 上查看了 v2.5 的 release 才知道,v2.5 中已经不建议使用 scope 属性了,推荐使用 slot-scope 属性来设置上下文。
将代码中的 scope=”scope”
修改为 slot-scope=”scope”
。如下图。
进入正题,下面列一写 vue v2.5 中的主要更新和调整。
使用 errorcaptured 钩子来处理组件内异常
在 v2.5 之前,可以用个全局的 config.errorhandler 设置来为应用提供一个处理未知异常的函数,也可以设置 rendererror 组件来处理 render 函数内的异常。但是,这些都不能提供一个完整的机制来处理一个单独组件内的异常。
v2.5 中,组件内提供了一个新的钩子函数 errorcaptured,可以捕获该组件内所有子组件树中(不含自身)产生的所有的异常(包括异步调用中的异常),这个钩子函数接收的参数和 errorhandler 一样,可以让开发者更加友好地处理组件内异常。
如果你了解 react 的话,会发现这个特性和 react v16 中引进的“异常边界(error boundary)”的概念非常相似,都是为了更好的处理和展示单个组件在渲染的过程中异常。本公众号和知乎专栏之前的文章有专门介绍 react 的异常边界的概念,点击传送门进行查看。
要利用 errorcaputerd,可以封装一个通用组件,来包含其他的业务组件,来捕获业务组件内的异常,并做对应的展示处理。下面列一个官方给的简单示例,封装一个通用组件(errorboundary)来包含和处理其他业务组件(another component)的异常。
vue.component('errorboundary', { data: () => ({ error: null }), errorcaptured (err, vm, info) { this.error = `${err.stack}\n\nfound in ${info} of component` return false }, render (h) { if (this.error) { return h('pre', { style: { color: 'red' }}, this.error) } // ignoring edge cases for the sake of demonstration return this.$slots.default[0] } }) <error-boundary> <another-component /> </error-boundary>
errorcaputed 的传递行为特性
- 如果定义了全局的 errorhandler,所有的异常还是会传递给 errorhadnler,如果没有定义 errorhandler,这些异常仍然可以报告给一个单独的分析服务。
- 如果一个组件上通过继承或父组件定义了多个 errorcapured 钩子函数,这些钩子函数都会收到同样的异常信息。
- 可以在 errorcapured 钩子内 return false 来阻止异常传播,表示:该异常已经被处理,可忽略。而且,也会阻止其他的 errorcapured 钩子函数和全局的 errorhandler 函数触发这个异常。
单文件组件支持“函数式组件”
通过 vue-loader v13.3.0 或以上版本,支持在单文件组件内定义一个“函数式组件”,且支持模板编译、作用域 css 和 热部署等功能。
函数式组件的定义,需要在 template 标签上定义 functional 属性来声明。且模板内的表达式的执行上下文是 函数式声明上下文,所以要访问组件的属性,需要使用 props.xxx 来获取。简单例子见下:
<template functional> <div>{{ props.msg }}</div> </template>
ssr 环境
使用 vue-server-renderer 来构建 ssr 应用时,默认是需要一个 node.js 环境的,使得一些像 php-v8js 或 nashorn 这样的 javascript 运行环境下无法运行。v2.5 中对此进行了完善,使得上述环境下都可以正常运行 ssr 应用。
在 php-v8js 和 nashorn 中,在环境的准备阶段需要模拟 global 和 process 全局对象,并且需要单独设置 process 的环境变量。需要设置 process.env.vue_env 为 “server”,设置 process.env.node_env 为 “development” 或 “production”。
另外,在 nashorn 中,还需要用 java 原生的 timers 为 promise 和 settimeout 提供一个 polyfill。
官方给出了一个在 php-v8js 中的使用示例,如下:
<?php $vue_source = file_get_contents('/path/to/vue.js'); $renderer_source = file_get_contents('/path/to/vue-server-renderer/basic.js'); $app_source = file_get_contents('/path/to/app.js'); $v8 = new v8js(); $v8->executestring('var process = { env: { vue_env: "server", node_env: "production" }}; this.global = { process: process };'); $v8->executestring($vue_source); $v8->executestring($renderer_source); $v8->executestring($app_source); ?> // app.js var vm = new vue({ template: `<div>{{ msg }}</div>`, data: { msg: 'hello' } }) // exposed by vue-server-renderer/basic.js rendervuecomponenttostring(vm, (err, res) => { print(res) })
v-on 修饰符
键值 key 自动修饰符
在 vue v2.5 之前的版本中,如果要在 v-on 中使用没有内置别名的键盘键值,要么直接使用 keycode 当修饰符(@keyup.13=”foo”),要么需要使用 config.keycodes 来为键值注册别名。
在 v2.5中,你可以直接使用合法的键值 key 值(参考mdn中的 keyboardevent.key)作为修饰符来串联使用它。如下:
<input @keyup.page-down="onpagedown">
上述例子中,事件处理函数只会在 $event.key === ‘pagedown' 时被调用。
注意:现有键值修饰符仍然可用。在ie9中,一些键值(.esc 和 方向键的 key)不是一致的值,如果要兼容 ie9,需要按 ie9 中内置的别名来处理。
.exact 修饰符
新增了一个 .exact 修饰符,该修饰符应该和其他系统修饰符(.ctrl, .alt, .shift and .meta)结合使用,可用用来区分一些强制多个修饰符结合按下才会触发事件处理函数。如下:
<!-- 当 alt 或 shift 被按下也会触发处理函数 --> <button @click.ctrl="onclick">a</button> <!-- 只有当 ctrl 被按下,才会触发处理函数 --> <button @click.ctrl.exact="onctrlclick">a</button>
简化 scoped slots 的使用
之前,如果要在 template 标签上使用 scope 属性定义一个 scoped slot,可以像下面这样定义:
<comp> <template scope="props"> <div>{{ props.msg }}</div> </template> </comp>
在 v2.5 中,scope 属性已被弃用(仍然可用,但是会爆出一个警告,就像本文文首的那样),我们使用 slot-scope 属性替代 scope 属性来表示一个 scoped slot,且 slot-scope 属性除了可以被用在 template 上,还可以用在标签元素和组件上。如下:
<comp> <div slot-scope="props"> {{ props.msg }} </div> </comp>
注意:这次的调整,表示 slot-scope 已经是一个保留属性了,不能再被单独用在组件属性上了。
inject 新增了默认值选项
本次调整中,injections 可以作为可选配置,并且可以声明默认值。也可以用 from 来表示原属性。
export default { inject: { foo: { from: 'bar', default: 'foo' } } }
与属性类似,数组和对象的默认值需要使用一个工厂函数返回。
export default { inject: { foo: { from: 'bar', default: () => [1, 2, 3] } } }
总结
以上所述是小编给大家介绍的vue v2.5 调整和更新不完全问题,希望对大家有所帮助
上一篇: 从0系统学Android--3.6 RecyclerView
下一篇: 搞笑漫画图片。神人奇才。