这是从 vue-element-ui 项目中学习到的很独特的写法。
我们在写前后端分离+权限控制的项目时,常常会使用后端返回的数据来渲染出侧边菜单结构,通常点击最后一级菜单进行路由跳转,但是有时候我这个是一个外部链接,当然可以使用 v-if 进行判断,但是 v-if 写的太多就很繁琐,而且人家这个新写法真的很好,所以在此记录一下!
先定义一个动态组件[官方文档],Link.vue
<template>
<!-- 这里用v-bind主要是为了接收父组件传值后进行动态处理,否则无法主动进行判断并返回 -->
<component :is="type" v-bind="linkProps(to)">
<!-- slot 就是占位,可以自定义内容,如果什么都不写,那么父组件使用这个组件时内部写的东西无效 -->
<slot />
</component>
</template>
<script>
export default {
/* 父组件必须要传值的属性 */
props: {
to: {
type: String,
required: true
}
},
computed: {
// 这里写个简单的判断方法判断传过来的地址是不是一个外部链接
isExternal() {
return this.to === "https://www.baidu.com"
},
/* 这个type的返回值对应到 组件的 is 属性,决定了它本质上是个什么标签 */
type() {
// 外部组件,以 a 标签处理
if (this.isExternal) {
return 'a'
}
// 内部链接,进行路由
return 'router-link'
}
},
methods: {
// 接收到父组件传值后的处理
linkProps(to) {
// 外部链接
if (this.isExternal) {
// 返回 a 标签接收的参数
return {
href: to,
target: '_blank',
rel: 'noopener'
}
}
// 内部链接,返回 router-link 组件接收的参数,相当于 <router-link to=>
return {
to: to
}
}
}
}
</script>
在别的组件中引入它,这里我就不贴完整内容了,等会看看效果即可。
<el-container>
<el-main>
// 使用子组件,根据我们在Link组件中的逻辑,百度会被处理成a标签跳转
// /google 会被作为内部路由,使用 <router-link to="/googel"/> 处理
<link-to to="https://www.baidu.com">百度一下?</link-to>
<link-to to="/google">谷歌谷歌</link-to>
</el-main>
</el-container>
<script>
import LinkTo from "@/components/Link";
export default {
name: "index",
components: {
LinkTo
},
</script>
页面效果
点击 百度一下 ,打开了一个新窗口
点击 谷歌谷歌 ,
因为我们没有配置 /google 的路由跳转,所以被系统的 /404 路由处理。