组件学习:

子组件:

<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>
            <template v-slot:fallback>
                <h2>子组件加载中</h2>
            </template>
        </Suspense>
       
    </div>
    
</template>

<script lang="ts" setup>
import { defineAsyncComponent, provide, ref, Suspense } from 'vue'//定义异步组件
const child=defineAsyncComponent(()=> import ('../components/child.vue'))//异步加载组件
//import child from '../components/child.vue'//同步加载组件

let n=ref(100);
provide("n",n)
</script>

<style scoped>
.father{
    padding: 20px;
    background: lightseagreen;
}
</style>

 

keepAlive学习
子组件:
 
keep1.vue
<template>
    <div class="bgk">
        <h3>组件一</h3>
    </div>
</template>

<script lang="ts">
import { defineComponent, onActivated, onDeactivated, onMounted, ref } from 'vue';
export default defineComponent({
  name: "keep1", //名称
  setup() { 
    
  },
});
//初始渲染
onMounted(()=>{
    console.log("渲染了组件一")
})

//组件不是重新渲染时激活时调用的方法
onActivated(()=>{
    console.log("激活了组件一的方法!")
})

//组件消失后调用的方法
onDeactivated(()=>{
    console.log("组件消失了")
})
</script>

<style scoped>
.bgk{
    padding: 20px;
    background: lightcyan;
}
</style>

 

keep2.vue
<template>
    <div class="bgk">
        <h3>组件二</h3>
    </div>
</template>

<script lang="ts" >
import { defineComponent, onActivated, onDeactivated, onMounted, ref } from 'vue';
export default defineComponent({
  name: "keep2", //名称
  setup() { 
    
  },
});
//初始渲染
onMounted(()=>{
    console.log("渲染了组件二")
})
</script>

<style scoped>
.bgk{
    padding: 20px;
    background: lemonchiffon;
}
</style>

 

keep3.vue
<template>
    <div class="bgk">
        <h3>组件三</h3>
    </div>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue';
export default defineComponent({
  name: "keep3", //名称
  setup() { 
    
  },
});
//初始渲染
onMounted(()=>{
    console.log("渲染了组件三")
})
</script>

<style scoped>
.bgk{
    padding: 20px;
    background: lightsalmon;
}
</style>

 

父组件:
<template>
    <!-- 把调用过的组件存在缓存中,下次在调用相同组件就不用再次重新渲染 -->
    <!-- include 只缓存指定的组件 -->
    <!-- exclude 对指定的组件不进行缓存 -->
    <!-- :max指定缓存的上限 -->
    <KeepAlive :max="1">
        <component :is="components[componentName]"></component>
    </KeepAlive>
    <input type="text" v-model="componentName">
</template>

<script lang="ts">
import { ref } from 'vue';
import keep1 from '../components/keep_1.vue'
import keep2 from '../components/keep_2.vue'
import keep3 from '../components/keep_3.vue'
export default ({
    setup() {
        let componentName = ref();
        let components = {
            "keep1": keep1,
            "keep2": keep2,
            "keep3": keep3,
        }
        return { componentName,components}
    },
    components: { keep1, keep2, keep3 }
})


</script>

<style scoped>

</style>

 

posted on 2022-11-11 08:48  最帅爸爸  阅读(115)  评论(0)    收藏  举报