元件的概念大概有了部分的了解,同一个元件可以重复利用,但这句话好像有个问题,不同页面使用相同架构的元件内容肯定需要做替换,这时候就是slot要出场啦!
编译作用域的意思就是「变数的作用范围」。
<h1>{{msg}}</h1>
<my-component>{{msg}}</my-component>
const app = Vue.createApp({
data() {
return {
msg: 'Parent'
}
}
});
app.component('my-component', {
template: `<h2>Hello!</h2>`,
data() {
return {
msg: 'Child'
}
},
})
当内外层都有data
时,画面会出现
my-component
内的msg
不是出现Child而是template
的内容,这表示元件在编译的时候会直接忽略内容物,直接放入template
中的模板。
对子元件钻洞,让外层元件的资料可以放入。
app.component('my-component', {
template: `
<h2>Hello!
<slot></slot>
</h2>`,
data() {
return {
msg: 'Child'
}
},
})
将slot放入template中,可以得出这样的结果
为什麽slot
内容物不是Child???
slot
特性是保留一个空间可以从外部传入内容,而子元件本身对slot
并没有控制权。 ——重新认识 Vue.js
若想要给予子元件一个「预设内容」,可以直接在slot
中放上预设内容。
<my-component></my-component>
app.component('my-component', {
template: `
<h2>Hello!
<slot>预设内容</slot>
</h2>`,
data() {
return {
msg: 'Child'
}
},
})
上面的范例是当只有一个内容物需要做变更的情况,当template内有很多需要换内容的时候就需要帮他们命名,让资料换到对应的位置。
<light-box>
<template v-slot:header>
<h1>这是header</h1>
</template>
<div>
没有给名字的slot
</div>
</light-box>
const app = Vue.createApp({
data() {
}
});
app.component('light-box', {
template: `
<div class="lightbox">
<div class="modal-mask" :style="modalStyle">
<div class="modal-container" @click.self="toggleModal">
<div class="modal-body">
<header>
<slot name="header">Default header</slot>
</header>
<hr>
<main>
<slot>Default body</slot>
</main>
<hr>
<footer>
<slot name="footer">Default footer</slot>
</footer>
</div>
</div>
</div>
<button @click="isShow = true">Click</button>
</div>`,
data: () => ({
isShow: false
}),
computed: {
modalStyle() {
return {
'display': this.isShow ? '' : 'none'
}
}
},
methods: {
toggleModal() {
console.log('click')
this.isShow = !this.isShow
}
}
})
方法其实和昨天的is
差不多,在这边的写法改为v-slot:[]
,可以自己选择位置放入更新内容。
<label v-for="opt in options">
<input type="radio" :value="opt" v-model="dynamic_slot_name">{{opt}}
</label>
<light-box>
<template v-slot:[dynamic_slot_name]>
<h1>更新後内容</h1>
</template>
</light-box>
const app = Vue.createApp({
data() {
return {
options: ['header', 'footer', 'default'],
dynamic_slot_name: 'header'
}
}
});
slot资料都是由父层提供,若希望子元素的data也可以显示就可以用到以下方式
:hello="helloString[lang]"
绑定子元素资料v-slot:default=""{hello}
接收并吐值给下面的{{hello}}
<p>
请选择
<select v-model="lang">
<option v-for="n in langOptions" :value="n.val">
{{n.name}}
</option>
</select>
</p>
<light-box :lang='lang'>
<!-- 写法一 -->
<template v-slot:default="props">
{{langOptions.find(d=>d.val===lang)['name']}}
{{props.hello}}
</template>
<!-- 写法二(解构) -->
<template v-slot:default="{hello}">
{{langOptions.find(d=>d.val===lang)['name']}}
{{hello}}
</template>
</light-box>
const app = Vue.createApp({
data: () => ({
langOptions: [{
name: '繁体中文',
val: 'tw'
}, {
name: 'Deutsch',
val: 'de'
}, {
name: 'English',
val: 'en'
}],
lang: 'tw'
})
});
app.component('light-box', {
template: `
<div class="lightbox">
<div class="modal-mask" :style="modalStyle">
<div class="modal-container" @click.self="toggleModal">
<div class="modal-body">
<slot name="default" :hello="helloString[lang]"></slot>
</div>
</div>
</div>
<button @click="isShow = true">Click</button>
</div>`,
props: {
lang: {
type: String,
default: 'tw'
}
},
data: () => ({
helloString: {
'tw': '哈罗',
'de': 'Hallo',
'en': 'Hello'
},
isShow: false
}),
computed: {
modalStyle() {
return {
'display': this.isShow ? '' : 'none'
}
}
},
methods: {
toggleModal() {
console.log('click')
this.isShow = !this.isShow
}
}
})
这部分的内容有点复杂,所以再次改部分名称看看到底是怎麽传资料的。
:hello="helloString[lang]"
中的:hello传出值後只是个属性的名称,所以换成abc也可以{{prop.abc}}
就可以看到值出现,或是用解构方式v-slot:default="{abc}"
控制元件选染的位置,像是上面的范例,因为元件的父层不是body
,所以灰底的遮罩盖不到整的页面,teleport to="body"
就可以把她挂载到body
上
<div class="lightbox">
<teleport to="body">
<div class="modal-mask" :style="modalStyle">
<div class="modal-container" @click.self="toggleModal">
<div class="modal-body">
<slot name="default" :abc="helloString[lang]"></slot>
</div>
</div>
</div>
</teleport>
<button @click="isShow = true">Click</button>
</div>
复用元件的好帮手:Vue Slots(v-slot、Scoped Slots)
https://medium.com/unalai/复用元件的好帮手-vue-slot-v-slot-scoped-slots-5364a0048ab7
<<: 部署 Kolla-Ansible 使用 External Ceph
前面用TiUP安装时,也已经将Grafana监控的部分一并安装完成。 在监控这部分大致上分为几个分类...
前情提要 昨天带各位用 Selenium 写了自动发留言的 Discord 机器人,可以在指定的文字...
9. Palindrome Number(easy) Given an integer x, ret...
今天就接续来讲中部地区的制作吧! 资料夹建立 lib/scareens/food_Middle/fo...
Tag:随意刷-[50-100] LeetCode Problem Source: 54. Spir...