組件學習: 子組件: <template> <div :title="msg">{{title}}</div> <div>{{cnData}}</div> <div>{{user}}</div> </template> <!-- <script lang="ts"> import { defineC ...
組件學習:
子組件:
<template>
<div :title="msg">{{title}}</div>
<div>{{cnData}}</div>
<div>{{user}}</div>
</template>
<!-- <script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "over",
setup() {
},
props: ["title", "data"],
});
</script> -->
<script lang="ts" setup>
import { ref } from 'vue';
//let title = ref("無敵的電腦")
//對象定義
let props = defineProps({
title:{
type: String, //類型
required: false, //是否必填
default:"無敵的小強",
validator:(v:string)=>v.length<=10,
},
msg: {
type: String, //類型
required: false, //是否必填
default:"無敵的小強",
validator:(v:string)=>v.length<=10,
},
cnData: { type: Array },
user: { type: Object },
});
</script>
<!-- //ts定義
// type PropType={
// title?:string;
// cntData?:number[];
// user:object;
// }
//定義屬性類型
//withDefaults(defineProps<PropType>(),{
//title:"預設名稱",
//cntData:()=>[9,10,11]
//})
//數組定義
// let props=defineProps(["title","cntData","user"]);
// console.log(props); -->
父組件:
<template>
<over msg="父傳子"
:cnData="data"
:user="{a:123,b:456}"
>
</over>
</template>
<script lang="ts" >
import { reactive, ref } from "vue";
import over from "../components/1103.vue";
export default {
setup() {
let data =reactive([1,2,3])
return { data };
},
components: {
over,
},
};
</script>
<!-- <script lang="ts" setup>
import over from "../components/1103.vue";
let data = new Date().toLocaleTimeString
</script -->
動態組件:
子組件:Section1 Section2 Section3
父組件:
<template>
<input type="text" v-model="componentName">
<!-- component動態組件 渲染那個組件受is影響 -->
<component :is="components[componentName]" @onEmit="section2"></component>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import Section1 from '../components/Section1.vue'
import Section2 from '../components/Section2.vue'
import Section3 from '../components/Section3.vue'
let componentName = ref("Section1");
let components = {
"Section1":Section1,
"Section2":Section2,
"Section3":Section3,
};
function section2(msgsection:any){
componentName.value=msgsection
}
</script>
插槽學習:
子組件:
<template>
<div class="bgc">
<slot name="bgc"></slot>
</div>
<div class="bgc2">
<div v-for="(u,i) in users">
<slot name="bgc2" :data="u"></slot>
</div>
</div>
<div class="bgc3">
<slot name="bgc3" :data="array"></slot>
</div>
<!-- 動態插槽 -->
<div class="bgc4">
<slot name="bgc4"></slot>
</div>
<!-- 匿名插槽 -->
<!-- <slot></slot> 定義插槽,父容器中使用該組件時,
在該組件放的內容都會丟到子組件匿名插槽中 -->
<slot :data="array"></slot>
</template>
<script lang="ts" setup>import { reactive, ref } from 'vue';
let n = ref(100)
//子組件暴露給數據給父組件
defineExpose({ n, a: 200, c: 1000 })
let array=[1,2,3,4,5,6,7,8]
let users=reactive([
{id:1,name:123},{id:2,name:234},
{id:3,name:345},{id:4,name:456}
])
type User={
id:number;
name:string;
}
</script>
<style scoped>
.bgc {
height: 40px;
background-color: antiquewhite;
}
.bgc2 {
height: 240px;
background-color: lightcyan;
}
.bgc3 {
height: 40px;
background-color: lightseagreen;
}
.bgc4 {
height: 40px;
background-color: lightsalmon;
}
</style>
父組件:
<template>
<demo ref="demo3">
<!-- v-slot只能用於組件或<template>標記 -->
<!-- <h2 v-slot:bgc></h2> 報錯!!! -->
<!-- 插槽不能重覆名稱 -->
<!-- <template v-slot:bgc></template> 報錯!!!-->
<!-- #bgc1是v-slot:bgc1的簡寫 -->
<template #bgc1>
具名插槽
</template>
<template v-slot:bgc2="{data}">
簡寫具名插槽,{{data}}
</template>
<template v-slot:bgc3="{data}">
具名插槽,{{data}}
</template>
<template #[refs]>
動態插槽
</template>
<!-- 匿名插槽 -->
<template v-slot="{data}">匿名插槽,{{data}}</template>
</demo>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import demo from '../components/1104_2.vue'
let demo3=ref<{a:number,c:number}>()
let refs=ref("bgc4")
onMounted(()=>{
console.log(demo3.value?.a)
})
//在setup中並不能直接訪問子組件暴露的成員
</script>
teleport,Suspense,非同步組件學習 子組件: son.vue
<template>
<div class="son">
<h2>這是孫子組件</h2>
<h2>父組件傳遞過來的數據{{n}}</h2>
<button @click="n++" class="btncss">n++</button>
<button @click="btn=!btn" class="btncss">{{btn==true ? "關閉對話框" : "彈出對話框"}}</button>
</div>
<!-- teleport 見將容器中的東西傳送到指定位置 to -->
<teleport to="body">
<template v-if="btn==true">
<div id="body_box">
<div class="body_item">
<div @click="btn=false" id="body_item_text">x</div>
<h3 style="text-align:center">內容</h3>
<h4 style="text-align:center">Hello Vue3 teleprot</h4>
</div>
</div>
</template>
</teleport>
</template>
<script lang="ts" setup>
import { inject, ref } from 'vue';
let n=inject("n");
let btn=ref(false)
</script>
<style scoped>
.son{
padding: 20px;
background: lightcoral;
}
#body_box{
width: 100%;
height: 100%;
position:absolute;
overflow-x: hidden;
top:0px;
background: rgb(9,9,9,0.5);
}
.body_item{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
height: 400px;
width: 300px;
background: #fff;
}
#body_item_text{
text-align: right;
cursor: pointer;
font-size: 20px;
margin: 12px 22px 0 10px;
}
</style>
child.vue
<template>
<div class="child">
<h2>這是子組件</h2>
<son></son>
</div>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'//定義非同步組件
const son=defineAsyncComponent(()=> import ('../components/son.vue'))//非同步載入組件
//import son from '../components/son.vue'//同步載入組件
</script>
<style scoped>
.child{
padding: 20px;
background: lightgreen;
}
</style>
父組件:
<template>
<div class="father">
<h2>這是父組件</h2>
<h2>父組件的數據{{n}}</h2>
<!-- Suspense等待非同步組件時渲染一些額外內容,讓應用有更好的用戶體驗 -->
<Suspense>
<template v-slot:default>
<child></child>
</template>
<templa