Vue3组件注册变化
Vue3在组件注册方面进行了多项改进,包括全局注册、局部注册和异步组件的调整,同时引入了组合式API带来的新变化。下面从不同角度详细分析这些改动。
全局组件注册的变化
Vue3中全局组件注册方式从Vue.component()
改为app.component()
,这是为了适应新的应用实例创建方式。创建应用实例后,所有全局组件都挂载到该实例上:
// Vue2写法
Vue.component('my-component', {
/* 选项 */
})
// Vue3写法
const app = Vue.createApp({})
app.component('my-component', {
/* 选项 */
})
这种变化使得多个Vue应用可以共存而不会相互影响。例如在一个页面中同时运行两个独立的应用:
const app1 = Vue.createApp({})
app1.component('comp-a', { /* ... */ })
const app2 = Vue.createApp({})
app2.component('comp-b', { /* ... */ })
// 两个应用的组件互不干扰
局部组件注册的改进
局部组件注册语法保持相似,但在组合式API中有了更灵活的使用方式。Vue3允许直接在setup()
中使用组件:
// 选项式API
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
// 组合式API
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
setup() {
return {}
},
components: {
ComponentA,
ComponentB
}
}
在单文件组件中,Vue3还支持更简洁的局部注册方式:
<script setup>
import ComponentA from './ComponentA.vue'
</script>
<template>
<ComponentA />
</template>
异步组件的新写法
Vue3重构了异步组件的API,使用defineAsyncComponent
方法定义:
// Vue2写法
const AsyncComponent = () => ({
component: import('./MyComponent.vue'),
loading: LoadingComponent,
error: ErrorComponent,
delay: 200,
timeout: 3000
})
// Vue3写法
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000,
suspensible: false
})
新API提供了更明确的配置项命名,并增加了suspensible
选项用于控制是否与<Suspense>
组件协同工作。
组件命名约定的变化
Vue3推荐使用PascalCase命名组件,这与大多数现代前端工具链保持一致:
// 推荐
app.component('MyComponent', {
/* ... */
})
// 仍然支持但不推荐
app.component('my-component', {
/* ... */
})
在模板中使用时,两种命名方式都可以正常工作:
<template>
<MyComponent />
<my-component />
</template>
动态组件的调整
Vue3中动态组件的is
属性用法有所调整,现在需要明确区分动态组件和原生HTML元素:
<!-- Vue2中可以直接使用 -->
<component :is="currentComponent" />
<!-- Vue3中需要添加前缀区分 -->
<component :is="currentComponent" /> <!-- 组件 -->
<component is="div" /> <!-- 原生元素 -->
对于保留元素(如table
的子元素),需要使用v-is
指令:
<table>
<tr v-is="'my-row-component'"></tr>
</table>
函数式组件的变更
Vue3中函数式组件需要通过函数显式定义,不再支持functional
选项:
// Vue2写法
Vue.component('functional-comp', {
functional: true,
render(h, context) {
return h('div', context.props.msg)
}
})
// Vue3写法
import { h } from 'vue'
const FunctionalComp = (props, context) => {
return h('div', props.msg)
}
组件v-model的升级
Vue3中v-model经历了重大改进,支持多个v-model绑定和自定义修饰符:
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
<!-- 等价于 -->
<ChildComponent
:title="pageTitle"
@update:title="pageTitle = $event"
:content="pageContent"
@update:content="pageContent = $event"
/>
组件内部的处理方式:
export default {
props: ['title', 'content'],
emits: ['update:title', 'update:content'],
setup(props, { emit }) {
const updateTitle = (newVal) => {
emit('update:title', newVal)
}
const updateContent = (newVal) => {
emit('update:content', newVal)
}
return { updateTitle, updateContent }
}
}
自定义元素交互的改进
Vue3提供了更明确的方式来处理自定义元素(Web Components):
const app = Vue.createApp({
compilerOptions: {
isCustomElement: tag => tag.includes('-')
}
})
这样配置后,所有包含连字符的标签名都会被当作自定义元素处理,不会尝试解析为Vue组件。
组件继承的调整
Vue3中移除了$listeners
和.native
修饰符,改为统一的v-on
处理:
<!-- Vue2中需要.native监听原生事件 -->
<my-component @click.native="handleClick" />
<!-- Vue3中统一处理 -->
<my-component @click="handleClick" />
组件内部需要通过emits
选项声明触发的事件:
export default {
emits: ['click'],
setup(props, { emit }) {
const handleInternalClick = () => {
emit('click', payload)
}
return { handleInternalClick }
}
}
组件实例属性的变化
Vue3中组件实例的某些属性发生了变化,需要特别注意:
// Vue2
this.$children // 访问子组件
this.$scopedSlots // 访问作用域插槽
// Vue3
setup(props, { slots, attrs, emit }) {
// 通过context参数访问
}
递归组件的处理
Vue3中递归组件需要显式命名,不能依赖文件名:
// 必须命名
export default {
name: 'RecursiveComponent',
setup() {
// ...
}
}
组件样式作用域的优化
Vue3改进了scoped
样式的工作方式,使用PostCSS的新实现:
<style scoped>
/* 生成的属性选择器更高效 */
.example {
color: red;
}
</style>
组件类型支持的增强
在TypeScript项目中,Vue3提供了更好的组件类型支持:
import { defineComponent } from 'vue'
export default defineComponent({
name: 'TypeSafeComponent',
props: {
message: {
type: String,
required: true
}
},
setup(props) {
props.message // 类型推断为string
}
})
组件性能优化相关
Vue3的组件注册机制在性能方面有所优化:
- 全局组件注册不再影响所有应用实例
- 局部组件注册在编译时进行更多静态分析
- 函数式组件创建开销显著降低
// 性能优化的函数式组件示例
import { defineComponent } from 'vue'
const OptimizedComponent = defineComponent(() => {
// 轻量级的渲染函数
return () => h('div', 'Hello')
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:更小的运行时体积
下一篇:ECharts简介与发展历史