在某些地方我们并不希望把组件都注册到router通过路由访问,或者多个小组件在一次引入,这个时候动态加载便有了用处
vue3有了新的异步加载组件的方法 defineAsyncComponent
采用原来的import方法(在vite某些版本中会出现警告)
解决这个报错 请看 解决方法
下面是动态组件加载方案
<!-- 动态加载某个组件 -->
<template>
<component v-if="VIEW" :is="VIEW" :query="query"></component>
<div v-else>
now Loading......
</div>
</template>
<script setup>
import { shallowRef, defineAsyncComponent } from 'vue';
// 让组件支持mvvm
const VIEW = shallowRef(null)
// 参数传递
const props = defineProps({
// 需要加载的组件路径 从views/开始 例子:views/page/index.vue
path: {
type: String,
default: ''
},
// 需要再次给组件传递的参数 可以按照需要替换成其他参数
query: {
type: Object,
default: {}
}
})
// 尝试加载的地址是否可以获取组件 获取成功则赋值,失败就到错误页面
loader(props.path).then(() => { VIEW.value = defineAsyncComponent(() => loader(props.path)) }).catch(() => { VIEW.value = defineAsyncComponent(() => loader('views/err/index.vue')) })
// 加载器
function loader(path) {
// 这里只能使用../的模式,具体多少个../需要看这个组件的位置需要几级才能才能访问到你需要加载的组件
return import(`../../${path}`)
}
</script>
<style lang="scss" scoped></style>
采用vite推荐方法
<template>
<component v-if="VIEW" :is="VIEW" :query="query"></component>
<div v-else>
now Loading......
</div>
</template>
<script setup>
import { shallowRef, defineAsyncComponent } from 'vue';
// 让组件支持mvvm
const VIEW = shallowRef(null)
// 获取可能用到的组件 据说说vite提供的新方法
// 使用vite新方法开始
const modules = import.meta.glob("../../views/**/**.vue")
// 使用vite新方法结束
// 参数传递
const props = defineProps({
// 需要加载的组件路径 从views/开始 例子:views/page/index.vue
path: {
type: String,
default: ''
},
// 需要再次给组件传递的参数 可以按照需要替换成其他参数
query: {
type: Object,
default: {}
}
})
// 调用加载
loader()
// 加载器
function loader() {
// 这里只能使用../的模式,具体多少个../需要看这个组件的位置需要几级才能才能访问到你需要加载的组件
VIEW.value = modules[`../../${props.path}`] ? defineAsyncComponent(modules[`../../${props.path}`]) : defineAsyncComponent(modules[`../../err/index.vue`])
}
</script>
<style lang="scss" scoped></style>
调用组件
<template>
<loadView :path="'views/normalTool/components/cupInterval.vue'" :query="{}"/>
</template>
<script setup>
import loadView from '@/components/public/loadView.vue'
</script>
<style lang="scss" scoped></style>