全局组件、局部组件

// 全局注册组件
import hello from './components/HelloWorld.vue'
app.component('hello',hello)

// 局部注册:在组件中引入即可使用
import hello from "../../components/HelloWorld.vue";
<hello :msg="msg"></hello>

递归组件

在这里插入图片描述

// 父组件
<template>
    <div class="side">
        <Tree :data="data"></Tree>
    </div>
</template>

<script setup lang='ts'>
import Tree from "../components/tree.vue"
const data = reactive([
    {
        title: '01',
        children: [{
            title: '1-1',
            children: [
                {
                    title: '1-1-1',
                }, {
                    title: '1-1-2',
                }, {
                    title: '1-1-3',
                }
            ]
        },
        {
            title: '1-2',
            children: [{
                title: '1-2-1',
            }]
        },
        {
            title: '1-3',
        }
        ]
    },
    {
        title: '02',
        children: [{
            title: '2-1',
            children: [
                {
                    title: '2-1-1',
                }, {
                    title: '2-1-2',
                }
            ]
        },
        {
            title: '2-2',
        },
        {
            title: '2-3',
            children: [{
                title: '2-3-1',
            }]
        }
        ]
    },
    {
        title: '03',
    },
])

</script>
<style lang='less' scoped>
.side {
    min-width: 200px;
    height: calc(100vh - 60px);
    background: rgb(163, 245, 218);
}
</style>
// 子组件
<template>
  <div v-for="item in data" :key="item.title" class="ml-20">
    {{ item.title }}
    <TreeItem v-if="item?.children?.length" :data="item.children">
    </TreeItem>
  </div>
</template>

<script setup lang='ts'>
defineProps({
  data: Object
})
</script>
<script lang="ts">
export default {
  name: 'TreeItem' // 给自己起一个name,递归使用
}
</script>
<style lang='less' scoped>
</style>

动态组件

import A from './A.vue'
import B from './B.vue'
<component :is="A"></component>

==注意事项 ==

  • 在Vue2 的时候is 是通过组件名称切换的, 在Vue3 setup 是通过组件实例切换的
  • 如果你把组件实例放到Reactive, Vue会给你一个警告
runtime-core.esm-bundler.js:38 [Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`. 
Component that was made reactive: 
  • 这是因为reactive 会进行proxy 代理, 而我们组件代理之后毫无用处 ,节省性能开销, 推荐我们使用shallowRef 或者 markRaw 跳过proxy 代理。
const tab = reactive([{
    name: "A组件",
    comName: markRaw(A)
}, {
    name: "B组件",
    comName: markRaw(B)
}])

异步组件(性能优化)

  • 在大型应用中,需要加载的资源较多,导致加载时间过长,所以我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。

  • 而Vue 提供的异步组件就实现了这个功能,使用 Vue 中的工厂函数的方式定义组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染时才会触发该工厂函数,且会把结果缓存起来供未来重渲染。

  • 用webpack提供的import语法,实现文件的分割加载

  • 异步组件打包后会单独打包成一个js文件,从而会减少index…js包的体积,会加快项目首屏加载速度,减少白屏时间,提升用户体验。

  • 静态引入:父组件和子组件会一起渲染,异步引入组件父使用的时候才加载,会减少内存的使用,提升性能。

  • 使用步骤:

  • 异步引入组件

    import {defineAsyncComponent} from 'vue'
    const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
    
  • 使用Suspense包裹组件,并配置好defaultfallback

  • 等待异步组件时渲染一些额外内容,让应用有更好的用户体验

    <template>
    	<div class="app">
    		<h3>我是App组件</h3>
    		<Suspense> //标签里边是异步组件
    			<template v-slot:default>
    				<Child/>
    			</template>
    			<template v-slot:fallback> //组件未加载出来显示
    				<h3>加载中.....</h3>
    			</template>
    		</Suspense>
    	</div>
    </template>
    
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐