会报错,这时候用is:
步骤1:写TableCell组件(TableCell.vue)
<template>
<div class="table-cell">
<p>我是自定义表格单元格,内容可以很灵活~</p>
</div>
</template>
<style scoped>
.table-cell {
background: #f5f5f5;
padding: 10px;
}
</style>
步骤2:在页面里用is渲染
<template>
<table border="1">
<tr>
<!-- 关键:用<td is="TableCell" /> 代替 <my-cell> -->
<td is="TableCell"></td>
</tr>
</table>
</template>
<script setup>
import TableCell from './components/TableCell.vue'
</script>
这样写,浏览器会把
识别为自定义组件,既保证HTML结构合法,又能渲染组件内容和样式~
用is时容易踩的坑,怎么避?
新手用is时,这几个问题很常见,提前避坑能省不少debug时间:
组件“找不到”:未注册或导入
如果控制台报Failed to resolve component: xxx ,先检查两点:
- 组件有没有
import 进来?
-
里的xxx,是不是真的指向组件(比如别写成字符串'xxx',除非组件在全局注册过)?
解决:确保组件在当前脚本里import ,is绑定的是组件对象(不是字符串,除非用全局注册+字符串匹配)。
路由参数变了,组件却没刷新
比如路由从/product?type=normal 跳到/product?type=seckill ,但组件还是原来的,这是因为Vue Router的同一路由组件复用机制,导致组件实例没销毁重建,computed也没触发更新?
解决:用watch 监听路由变化,或者把路由参数通过props 传给组件,再用watch 监听props变化,前面案例里用computed 绑定route.query.type,其实已经是响应式的,只要路由参数变,computed会自动重新计算,组件也会刷新~
样式“不听话”:scoped导致的布局问题
如果自定义组件用了<style scoped> ,在 | 里可能出现样式不生效(比如组件内的margin、padding被父级table样式覆盖)。
解决:可以给组件加个唯一class,用深度选择器(比如>>> 或/deep/ )穿透scoped;或者把公共样式放到全局样式文件里。
异步组件加载失败:白屏或报错
如果用is结合异步组件(比如defineAsyncComponent ),网络差时可能加载失败,页面直接白屏。
解决:给异步组件加错误处理,
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent({
loader: () => import('./AsyncComp.vue'),
errorComponent: () => import('./ErrorComp.vue'), // 加载失败时显示的组件
timeout: 3000 // 3秒没加载完就算失败
})
这样即使加载失败,也能给用户友好提示~
实际项目里的高阶玩法
掌握基础后,这些进阶技巧能让你更“丝滑”地用is+Vue Router:
结合缓存组件状态
如果动态切换的组件需要保留状态(比如表单输入内容),可以用包裹
<template>
<keep-alive>
<component :is="currentComp" />
</keep-alive>
</template>
这样切换组件时,组件实例不会销毁,状态就能保留~
路由守卫里控制组件渲染
比如某些页面需要权限,没权限时用is渲染“权限不足”组件,可以在beforeRouteEnter 守卫里判断:
// 在组件内写导航守卫
import { onBeforeRouteEnter } from 'vue-router'
onBeforeRouteEnter((to, from, next) => {
const hasPermission = checkPermission() // 自定义权限检查函数
if (hasPermission) {
next(vm => {
vm.currentComp = NormalComp // 有权限渲染正常组件
})
} else {
next(vm => {
vm.currentComp = NoPermissionComp // 没权限渲染提示组件
})
}
})
动态组件+路由元信息(meta)
在路由配置里加meta字段,标记该路由该渲染哪个组件:
routes: [
{
path: '/admin',
name: 'Admin',
component: AdminLayout,
meta: { targetComp: 'AdminDashboard' } // 标记要渲染的组件名
}
]
然后在AdminLayout里用is动态渲染:
<template>
<component :is="metaComp" />
</template>
<script setup>
import { useRoute } from 'vue-router'
import AdminDashboard from './AdminDashboard.vue'
const route = useRoute()
const metaComp = route.meta.targetComp === 'AdminDashboard' ? AdminDashboard : DefaultComp
</script>
这种方式让路由配置和组件渲染逻辑解耦,维护更方便~
看完这些,你应该对“vue router里的is”从概念到用法都有了清晰认知,简单总结下:is是Vue动态组件的“开关”,和Vue Router结合后,能解决组件动态渲染、HTML结构限制、性能优化等问题,实际项目里多练几个场景(比如动态tab、权限控制页),就能彻底掌握这个实用技巧~如果还有疑问,评论区留言,咱们继续唠~
版权声明
本文仅代表作者观点,不代表Code前端网立场。 本文系作者Code前端网发表,如需转载,请注明页面地址。
|