全局组件
使用频率非常高的组件可以搞成全局组件,无需再组件中再次import引入
在main.ts 注册
import Card from './components/Card/index.vue'createApp(App).component('Card',Card).mount('#app')
使用方法
直接在其他vue页面 立即使用即可 无需引入
<template><card></card>
</template>
批量注册全局组件
可以参考element ui 其实就是遍历一下然后通过 app.component 注册
局部组件
在组件内部使用import引入的
<template><div class=""></div><son></son><son2 :title="'父组件传来的title'"></son2>
</template><script setup lang="ts">
import son from "./components/son_eight.vue";
import son2 from "./components/son_eight2.vue";
</script>
配置递归组件
原理跟我们写js递归是一样的 自己调用自己 通过一个条件来结束递归 否则导致内存泄漏
案例递归树
在父组件配置数据结构 数组对象格式 传给子组件
<script setup lang="ts">
<template><h2>递归组件案例--</h2><Tree @emit="get" :data="data"></Tree></template><script setup lang="ts">
import {ref,reactive,markRaw,shallowRef,shallowReactive,
} from "vue";
import Tree from "./components/nine_tree.vue";type TreeList = {name: string;icon?: string;children?: TreeList[] | [];
};
const data = reactive<TreeList[]>([{name: "no.1",children: [{name: "no.1-1",children: [{name: "no.1-1-1",},],},],},{name: "no.2",children: [{name: "no.2-1",},],},{name: "no.3",},
]);let get = (name) => {console.log("父组件接收的值", name);
};
</script>
TreeItem.vue子组件 直接使用组件名字
<template><divstyle="margin-left: 40px":key="index"@click.stop="send(item)"v-for="(item, index) in data"><div>{{ item.name }}</div><!--@emit="send" 组件需要再次派发 这里是细节的地方控制台输出以下内容let obj = {name: ''}obj.children // undefinedobj.children.length // 直接报错obj.children?.length // undefinedobj.children?.length ?? 1 // 1null ?? 1 // 1false ?? 1 // false ,?? 只处理左边undefined 和null 的情况--><TreeItem@emit="send"v-if="item?.children?.length":data="item.children"></TreeItem></div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
type TreeList = {name: string;icon?: string;children?: TreeList[] | []; // 代表children可以不传 也可以传但是接收的同样是TreeList类型 也可以传空数组
};
type Props = {data?: TreeList | []; // 这里处理很细节
};
defineProps<Props>();let emit = defineEmits(["emit"]);
let send = (item) => {emit("emit", item);
};
</script>
或者再次添加个script
<script lang="ts">
export default {name:"TreeItem"
}
</script>
效果图:
动态组件
父组件
<template><h3>动态组件案例--</h3><!-- 不能是两个动态的 最多只支持一个动态和一个静态 --><div:class="[active == index ? 'active' : '']"v-for="(item, index) in comList":key="index"><button @click="switchTab(item)">{{ item.tab }}</button></div><component :is="current.name"></component><h3>字符串的方式</h3><component is="C"></component>
</template><script setup lang="ts">
import {ref,reactive,markRaw,shallowRef,shallowReactive,
} from "vue";
import A from "./components/nine_A.vue";
import B from "./components/nine_B.vue";
import C from "./components/nine_C.vue";// 动态组件
// vue2中是通过组件的name做渲染,vue3中setup是通过组件的实例来做渲染type Com = {tab: string;name: string;
};
type Cur = Pick<Com, "name">; // Pick 从Com中提取出name 作为字面量泛型
let comList = reactive<Com[]>([{tab: "我是A组件",name: shallowReactive(A),// name: "A", // 警告是由于reactive做了代理proxy 导致组件也做了代理,组件代理是没必要的所以节省开销我们使用 ShallowReactive, ShallowReactive,show},{tab: "我是B组件",name: shallowReactive(B),},
]);let active = ref<number>(0);let current = reactive<Cur>({name: comList[0].name, // 默认展示第一个组件
});
let switchTab = (item, index) => {current.name = item.name;active.value = index;console.log(current.name.value);
};
</script><script lang="ts">
export default {components: {C,},
};
</script><style lang="scss" scoped>
.active {background: pink;
}
</style>
A.vue
<template><div class="">aaaaaaaaaaaaaa</div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
</script><style lang="sass" scoped></style>
B.vue
<template><div class="">bbbbbbbb</div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
</script><style lang="sass" scoped></style>
C.vue
<template><div class=""><h3>vue3 第二种动态组件的方式使用</h3></div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
</script><style lang="sass" scoped></style>
效果图:
11 vue3之插槽全家桶-CSDN博客11 vue3之插槽全家桶。https://blog.csdn.net/qq_37550440/article/details/142326456?sharetype=blogdetail&sharerId=142326456&sharerefer=PC&sharesource=qq_37550440&spm=1011.2480.3001.8118