56-61 組件插槽、動態組件,異步組件
- 插槽的基本使用
- 具名插槽--v-slot
- 渲染作用域、作用域插槽
- 渲染作用域
- 作用域插槽--使用子組件的資料
- 動態組件
- 異步組件-適用于大型專案加載時
插槽的基本使用

先寫一個組件,然后將按鈕注釋,改為插槽,其中插槽可以撰寫默認內容,在應用組件時,將自定義元素寫在組件中,就會替換slot的標簽,十分靈活
<body>
<div id="app">
<lk-box><button>點我</button></lk-box>
<lk-box><input type="text" placeholder="輸入名字"></lk-box>
</div>
<template id="box">
<div style="background-color: red; width: 200px; height: 200px;margin:20px;">
<h2>hhhh</h2>
<p>like it</p>
<!-- <button>點我</button> -->
<!-- 預留插槽 -->
<slot></slot>
</div>
</template>
<script>
const LkBox = {
template: '#box',
};
const app = Vue.createApp({
data() {
return {};
},
components: {
'lk-box': LkBox,
},
methods: {},
}).mount("#app");
</script>
</body>
<div id="app">
<lk-box><button>點我</button></lk-box>
<lk-box><input type="text" placeholder="輸入名字"></lk-box>
</div>

具名插槽–v-slot
當使用多個插槽時,要有具體的命名
先按照上面的方式,寫三個插槽,查看效果,分別渲染了三次很明顯不對
<body>
<div id ="app">
<lk-box>
<h1>頭部</h1>
<h2>主要內容</h2>
<h3>尾部</h3>
</lk-box>
</div>
<template id="box">
<div>
<p>-----</p>
<header>
<!-- 放頭部 -->
<slot name="header">頭部</slot>
</header>
<main>
<!-- 放內容 -->
<slot name="main">內容</slot>
</main>
<footer>
<!-- 放頁腳 -->
<slot name="footer">頁腳 </slot>
</footer>
<p>------</p>
</div>
</template>
<script>
const lkbox={
template:'#box'
};
const app = Vue.createApp({
data() {
return{
}
},
components: {
'lk-box':lkbox
},
methods: {}
}).mount('#app');
</script>
</body>

正確寫法
主要name要一一對應,使用v-slot的指令對應子組件的插槽
<body>
<div id ="app">
<!-- 錯誤呼叫 -->
<!-- <lk-box>
<h1>頭部</h1>
<h2>主要內容</h2>
<h3>尾部</h3>
</lk-box> -->
<!-- 正確的 -->
<lk-box>
<template v-slot:header>
<button>我是頭部</button>
</template>
<template v-slot:main>
<input type="text" placeholder="我是中間">
</template>
<template v-slot:footer>
<button>我是尾部</button>
</template>
</lk-box>
</div>
<template id="box">
<div>
<p>-----</p>
<header>
<!-- 放頭部 -->
<slot name="header">頭部</slot>
</header>
<main>
<!-- 放內容 -->
<slot name="main">內容</slot>
</main>
<footer>
<!-- 放頁腳 -->
<slot name="footer">頁腳 </slot>
</footer>
<p>------</p>
</div>
</template>
<script>
const lkbox={
template:'#box'
};
const app = Vue.createApp({
data() {
return{
}
},
components: {
'lk-box':lkbox
},
methods: {}
}).mount('#app');
</script>
</body>

補充,默認插槽
當其中一個插槽沒有命名,則當外部呼叫組件時,會顯示的子組件中的里的內容
如果要使用外部傳進來的,可以使用v-slot:default,默認對應這一個沒有命名的slot進行替換
這里只黏貼了部分代碼
<template v-slot:default>
<input type="text" placeholder="我是中間">
</template>
組件里的插槽未命名
<template id="box">
<div>
<p>-----</p>
<header>
<!-- 放頭部 -->
<slot name="header">頭部</slot>
</header>
<main>
<!-- 放內容 -->
<slot>內容</slot>
</main>
<footer>
<!-- 放頁腳 -->
<slot name="footer">頁腳 </slot>
</footer>
<p>------</p>
</div>
</template>
效果:

渲染作用域、作用域插槽
渲染作用域

<body>
<div id ="app">
<lk-box v-show="isshow"></lk-box>
</div>
<template id="box">
<div style="background-color: red;width: 200px;height: 200px;margin:20px">
<button>點我</button>
</div>
</template>
<script>
const lkbox={
data(){
return{
isshow:false
}
},
template:'#box'
};
const app = Vue.createApp({
data() {
return{
isshow:true
}
},
components: {
'lk-box':lkbox
},
methods: {}
}).mount('#app');
</script>
</body>

作用域插槽–使用子組件的資料
一般傳入的是父組件的資料,因為作用域的問題,父子組件的資料不能隨意呼叫,當插槽中,需要由子組件的資料進行渲染,可采用作用域插槽的方式

<body>
<div id="app">
<lk-box></lk-box>
<p>---------</p>
<lk-box>
<template v-slot:default="slotProps">
<span>{{slotProps}}</span>
<span>{{slotProps.data.join('---')}}</span>
</template>
</lk-box>
</div>
<template id="box">
<div style="background-color: red;width: 200px;height: 200px;margin:20px;">
<slot :data="nameArr">
<ul>
<li v-for="name in nameArr">{{name}}</li>
</ul>
</slot>
</div>
</template>
<script>
const lkbox = {
data(){
return{
nameArr:['張三','李四','王五']
}
},
template: "#box",
};
const app = Vue.createApp({
data() {
return {
msg: "hello",
};
},
components: {
'lk-box':lkbox
},
methods: {},
}).mount("#app");
</script>
</body>
如圖1為正常呼叫,顯示的默認插槽;現在想即呼叫子組件資料,并且也從父組件對插槽進行覆寫
這里slot添加data屬性將子組件的資料傳遞出來
<slot :data="nameArr">
父組件應用時,定義一個slotProps的變數來接受子組件傳過來的陣列,對資料進行操作,添加----
<lk-box>
<template v-slot:default="slotProps">
<span>{{slotProps}}</span>
<span>{{slotProps.data.join('---')}}</span>
</template>
</lk-box>

動態組件

<body>
<div id="app"></div>
<script>
const app = Vue.createApp({
data() {
return {
Citem:'lk-btn'
};
},
methods: {
change(){
if(this.Citem==='lk-btn'){
this.Citem='lk-input'
}else{
this.Citem='lk-btn'
}
}
},
template:
`
<div>
第一種寫法,v-show寫法,控制Citem進行顯示
<lk-btn v-show="Citem==='lk-btn'"></lk-btn>
<lk-input v-show="Citem==='lk-input'"></lk-input>
<p>-----</p>
<button @click="change">切換</button>
</div>
`,
});
app.component("lk-btn", {
template: `<button>點我</button>`,
});
app.component("lk-input", {
template: `<input type="text" />`,
});
app.mount("#app");
</script>
</body>
第一種方式是通過v-show動態切換

第二種是通過vue提供的動態組件,動態系結is屬性取組件,簡便的實作功能,并配合keepalive避免input失活無法保存狀態的問題
template: `
<div>
<keep-alive><component :is="Citem"></component></keep-alive>
<p>-----</p>
<button @click="change">切換</button>
</div>
`,

異步組件-適用于大型專案加載時

參考鏈接1-ES6箭頭函式和普通函式的區別
參考鏈接2-JavaScript Promise 物件
參考鏈接3-ECMAScript 6 簡明教程
參考鏈接4-VUE defineAsyncComponent函式創建異步組件
使用settimeout模擬服務器加載渲染程序,defineAsyncComponent是vue3自帶的函式,用于創建異步函式,
<body>
<div id ="app">
<async-item></async-item>
</div>
<script>
const app = Vue.createApp({
data() {
return{
msg:'hello'
}
},
methods: {}
});
// 注冊一個異步組件
app.component('async-item',Vue.defineAsyncComponent(()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve({
template:`<div style="width:200px;height:200px;background:red;"></div>`
})
},3000)
})
}))
app.mount('#app');
</script>
</body>
效果:隔一段時間加載,模擬服務器渲染
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/305988.html
標籤:其他
上一篇:Vue保姆級入門教程
下一篇:陣列轉物件
