本系列文章目录
四、3.x跟2.x的其他差异
ctx属性
对于网上一些其他文档使用
ctx.$router
、ctx.$store
访问router和store的应该小心避坑,注意开发环境和生产环境的差别
vue3.x 开发环境 ctx
开发环境的ctx
,可以看到$router
、$store
、声明的变量和方法等
vue3.x 生产环境 ctx
生产环境的ctx
,$router
、$store
没有了,其他属性也都没有了,不能通过ctx.$router
、ctx.$store
访问router和store,因此ctx可以说对我们没有用,应该避免在代码中使用ctx
执行顺序
vue3.x中会先执行setup
方法,再执行兼容2.x的其他方法,比如data
、computed
、watch
等,
并且在setup
执行过程中,无法访问data
中定义的属性,因为此时还未执行到data
方法
mount挂载
使用mount
挂载的时候
2.x会使用挂载元素的outerHTML
作为template,并替换挂载元素
3.x会使用挂载元素的innerHTML
作为template,并且只替换挂载元素的子元素
this.$el、reactive refs、template refs
2.x可以在组件挂载之后通过this.$el
访问组件根元素
3.x去掉this,并且支持Fragment,所以this.$el
没有存在的意义,建议通过refs
访问DOM
当使用组合式 API 时,reactive refs
和 template refs
的概念已经是统一的。为了获得对模板内元素或组件实例的引用,我们可以像往常一样在 setup()
中声明一个 ref
并返回它
使用reactive refs和template refs
<template>
<div ref="root"></div>
</template>
<script> import { ref, onMounted, getCurrentInstance } from 'vue' export default { setup() { const vm = getCurrentInstance() const root = ref(null) onMounted(() => { // 在渲染完成后, 这个 div DOM 会被赋值给 root ref 对象 console.log(root.value) // <div/> console.log(vm.refs.root) // <div/> console.log(root.value === vm.refs.root) // true }) return { root } } } </script>
在v-for中使用
<template>
<div v-for="(item, i) in list" :key="i" :ref="el => { divs[i] = el }">
{{ item }}
</div>
</template>
<script> import { ref, reactive, onBeforeUpdate } from 'vue' export default { setup() { const list = reactive([1, 2, 3]) const divs = ref([]) // 确保在每次变更之前重置引用 onBeforeUpdate(() => { divs.value = [] }) return { list, divs } } } </script>
setup返回普通对象
setup
返回普通对象的时候,会跟reactive
对象一样,具备响应式,执行下面这段代码后会发现普通对象obj1.cnt
也具有响应式了,虽然这样可以行得通,但是为了可读性,防止不了解这个特性的同学误解为非响应式的,建议还是通过reactive
包一下。
<template>
<div>{{ obj1.cnt }}</div>
<div>{{ obj2.cnt }}</div>
</template>
<script> import { reactive } from 'vue' export default { setup () { // 普通对象 const obj1 = { cnt: 1 } // 代理对象 const obj2 = reactive({ cnt: 1 }) setInterval(() => { obj1.cnt++ obj2.cnt++ }, 5000) return { obj1, obj2 } } } </script>
directive指令
vue3.x对指令的生命周期钩子进行了改造,改造后更像3.x普通vue组件的钩子,更方便记忆
// vue2.x
export default {
name: 'YourDirectiveName',
bind(el, binding, vnode, oldVnode) {},
inserted(...) {},
update(...) {},
componentUpdated(...) {},
unbind(...) {}
}
// vue3.x
export default {
beforeMount(el, binding, vnode, oldVnode) {},
mounted(...) {},
beforeUpdate(...) {},
updated(...) {},
beforeUnmount(...) {},
unmounted() {...}
}
render方法修改
vue、react都提供了render
方法渲染html模板,直接使用render
方法的还是比较少,毕竟有template
和JSX
,对于确实需要自定义render
方法渲染模板内容的,具体变动如下:
// vue2.x
export default {
render(h) {
return h('div')
}
}
// vue3.x
import { h } from 'vue'
export default {
render() {
return h('div')
}
}
3.x中移除的一些特性
取消KeyboardEvent.keyCode
在vue3.x中,给keyup
事件配置一个指定按钮的keyCode
(数字)将不会生效,但是依然可以使用别名,例如:
// 无效
<input @keyup.13="handler" />
// 有效
<input @keyup.enter="handler" />
移除
off 和 $once方法
在Vue2.x中可以通过EventBus
的方法来实现组件通信
// 声明实例
var EventBus = new Vue()
Vue.prototype.$globalBus = EventBus
// 组件内调用
this.$globalBus.$on('my-event-name', callback)
this.$globalBus.$emit('my-event-name', data)
在vue3.x中移除了 $on
、$off
等方法,而是推荐使用mitt
方案来代替:
// 声明实例
import mitt from 'mitt'
const emitter = mitt()
// 组件内调用
// listen to all events
emitter.on('*', (type, e) => console.log(type, e))
emitter.on('my-event-name', callback)
emitter.emit('my-event-name', data)
// clearing all events
emitter.all.clear()
移除filters
在vue3.x中,移除了组件的filters
项,可以使用methods
的或者computed
来替代
移除inline-template
在Vue2.x中,在父组件引入子组件时,会用到inline-template
来使子组件的内容也得到展示,参考这里,例如:
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
在Vue3中,这个功能将被移除,目前inline-template
使用的并不多,这里就不再过多讲解
后话
虽然vue3.0已经进入rc版本,但是就算vue3.0正式版出来了,3.0相关的生态更新肯定需要一段时间,比如element-ui
、ant-design
、iview
等框架,还有其他开源组件,如果想在正式项目使用的话还是要仔细评估风险,个人建议对vue开源没有依赖的可以先上手vue3.0,有依赖的还是再等一段时间,等生态都支持vue3.0了再去升级,另外对现有项目升级还需要评估工作量。
参考文章
composition-api.vuejs.org/zh/api.html
本系列文章目录
今天的文章Vue3.0全家桶最全入门指南 – 3.x跟2.x的其他差异 (4/4)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13418.html