最近发布了 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.defineProperty
与 proxy
因为在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呀,哈哈哈。
- 综上,去用吧!