Vue 2.7.0 Naruto 体验

avatar
Ctrl+C、V工程师 @豌豆公主

最近发布了 Vue 2.7.0,可能是因为 Vue 3 的推进有些大,因此在 Vue2.x 的基础上新增加了一个 2.7 版本,给大家的迁移腾出了一些时间。在 2.7 中其实已经支持了3中比较重要的API。

监听机制

Vue 2.7中,Vue 的响应式实现的原理并没有发生变化,依然采用的是Object.defineProperty,说是为了继续兼容浏览器(IE),与proxy还是有一些区别的。

兼容的API

  • Composition API( ref, reactive, toRefs, toRaw 等)。
  • <script setup>
  • CSS v-bind color: v-bind('fontColor')
  • 支持defineComponent()
  • h()useSlot()useAttrs()useCssModules()
  • set()del()nextTick() 在 ESM 构建中也作为命名导出提供。
  • Vue 2.7 还支持在模板表达式中使用 ESNext。

与Vue3的差异

Object.definePropertyproxy

因为在Vue 2.7中,实现响应式的方法还是 Object.defineProperty ,所以会出现这个情况

let foo = {
  a: 1
};
console.log('--------- 1 --------');
console.log(reactive(foo));
console.log(ref(foo));
// 在浏览器中展示会发现,他俩不是proxy对象
console.log(reactive(foo) == foo);
console.log(ref(foo) == foo, ref(foo).value == foo); // false, true
// 这里需要注意的是,他俩之所以相同,是因为引用了同一个对象foo
console.log('--------- 2 --------');
console.log(reactive({a : 1}) == reactive({a : 1})); // false

createApp()

Vue 2.7 中不适用,因为2中实际上用的是 Vue.extends 的方式。

readOnly

Vue 2.7 中, readOnly 创建了一个单独的对象,,而不是通过 proxy 代理的同一个对象。

const fooReadOnly = readonly(reactive(foo));
console.log('--------- 修改会报错 --------');
fooReadOnly.a = 2;
console.log('--------- 创建的新对象 --------');
console.log('fooReadOnly', fooReadOnly, reactive(foo)); // fooReadOnly 不等于 reactive(foo)

reactive

reactive root 的值如果是数组会报错,原因是没有属性可以访问数组。

Reactivity APIs

Reactivity APIs 忽略带有 symbol 的属性。

<script setup>

Vue 2.7 中,我们无法使用顶层 await

expose的区别

Vue 2.7 中,我们只能通过 setup 支持 expose(),defineExpose()

export default {
  setup(props, { expose }) {
    const count = ref(0);
    const increment = () => ++count.value;
    const cutDown = () => --count.value;
    expose({
      increment,
      count
    });
    return () => h('div', count.value);
  }
}
// <script setup> 的方式
<script setup>
import { ref } from 'vue';
const a = ref(1);
const b = 2;
defineExpose({
  a,
  b
});
</script>

模板表达式TypeScript

Vue 2.7 中不支持表达式中使用TS,主要还是因为解析器不支持。

Reactivity transform

这个地方因为还在实验阶段,就先不说了。具体涉及到的内容可以看 Reactivity transform

如何升级

这里我只尝试了vue-cli的方式,所以只提供一个方案。其他的大家可以看 升级方案

升级vue-cli

我们需要把vue-cli升级到

  • v4版本 => 4.5.18
  • v5版本 => 5.0.6

升级vue

npm i vue@2.7.0

升级eslint-plugin

因为我们在使用 <script setup> 的时候,会出现一些未定义的变量,会报错,因此需要升级一下,让开发体验尽量与 Vue3 保持一致。因为很多时候我们用一个函数,比如 defineExpose 是不需要声明的,所以正常情况下会报错。

npm i eslint-plugin-vue@9.x

体验感受

  • Vue3 的区别真的不大(日常业务开发),常用的API也都有了。
  • 在写码的时候,对于刚接触 Vue3 的同学非常友好,因为你依然可以用 Object.defineProperty 的思维方式来处理。
  • 对于抽象组件会更加更加方便,比如一个 Dialog 组件,你完全可以通过 expose 的方式去抛出API与数据。
  • 这个还真不是舔....我觉得对于一个组件库,帮大家做了这个兼容方案,很贴心,看来他们是真的很想推Vue3呀,哈哈哈。
  • 综上,去用吧!