学完component
是怎麽传递之後,看似完美,如果某天PM丢出一个需求,初步了解状况後,发现有很多地方都可以组成元件来重复使用,但其实没有这麽简单,看起来一样的区块,其实里面有很多结构不一样,这时就可以针对里面的小区域去做修改。
Slot
Vue
官网翻译Slot
为插槽,我联想到线上游戏的武器,也会有各种插槽,用这个方式去想会比较容易理解:
你的人物角色就像是外部元件,你的名刀不知火就是内元件,游戏系统有卡片功能,卡片可以插在你的道具上面(内元件),卡片就是你想要的从外部放入的文字,但前提是道具要打洞
成插槽:
<div id="app">
<h3> {{ text }} </h3>
<out-text>
<p>打洞成功</p>
</out-text>
<out-text>
</out-text>
</div>
const app = Vue.createApp({
data() {
return {
text: "外层元件",
product: {
name: "名刀不知火",
price: 200000,
}
}
}
});
app.component("outText",{
template: `
<div class="box">
<h3> {{ text }} </h3>
<div class="header">header</div>
<div class="main">
<slot> 预设值!</slot>
</div>
<div class="footer">footer</div>
</div>
`,
data() {
return {
text: "内部元件",
num: 3,
};
}
});
app.mount("#app");
内层元件的模板某区块如果要由外层元件定义时,子元件一定要加上slot
,外层元件的模板打洞成功
才能正常显示。
如果外层元件的模板,没有任何元素时,就会显示<slot> 预设值!</slot>
,可以观察两个子元件画面渲染的差异。
slot
具名插槽一把武器只有一个插槽那怎麽够啊!那我要四个该怎麽做呢?
这种情况握紧拳头是没有用的,在建立四个插槽需要先了解slot
有个属性:name
,可以使用它来为插槽命名,子元件模板则使用v-slot
让外层传递到子元件:
<div id="app">
<h3> {{ product.name }} </h3>
<out-text>
<template v-slot:header>波利卡片</template>
<template v-slot:main>疯兔卡片</template>
<template v-slot:default></template>
<template v-slot:footer>秃鹰卡片</template>
</out-text>
</div>
const app = Vue.createApp({
data() {
return {
text: "外层元件",
product: {
name: "名刀不知火",
price: 200000,
}
}
}
});
app.component("outText",{
template: `
<div class="box">
<div class="header">
<slot name="header"></slot>
</div>
<div class="main">
<slot name="main"></slot>
<div>
<slot>未插卡!</slot>
</div>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
`,
data() {
return {
text: "内部元件",
num: 3,
};
}
});
app.mount("#app");
v-slot:header
可以改为#header的写法较为简洁,v-slot:default
预设如果主元件没有值,就会由<slot>未插卡!</slot>
来代替。
slot
作用域先来观察这段程序码,并猜想画面会是什麽呢?
<div id="app">
<h3> {{ product.name }} </h3>
<out-text>
<p> {{ product.name }} </p>
</out-text>
</div>
const app = Vue.createApp({
data() {
return {
text: "外层元件",
product: {
name: "名刀不知火",
price: 200000,
}
}
}
});
app.component("outText",{
template: `
<div class="box">
</div>
`,
data() {
return {
text: "内部元件",
product: {
name: "+9 猎人之弓",
price: 100000,
}
};
}
});
app.mount("#app");
。
。
。
。
答案是只会显示外层元件data
里的product.name
,因为两个元件虽然都有一样product
,但各自元件有属於自己的data
与作用域,两个product
是不同的属性。
<out-text><p> {{ product.name }} </p></out-text>
会无法显示,是因为Vue
在编译时,会以元件模板定义内容为主,会忽略掉{{ product.name }}
,除非在子元件模板加上slot
。
官网补充:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
template
记得打洞变成slot
。name
v-slot:插槽名称
,可缩写为#
插槽名称。以上如有错误,欢迎指教,下一篇讲解slot
的资料传递。
<<: JavaScript Day 27. AJAX、Request、Response
Q: 今天是教师节呢,怎麽没有放假? A: 认真上课黑!本篇是可能实用,但更可能杀光脑细胞的ste...
Spring 初探 (二) Spring初探(二) ...
这篇要来介绍 React router v5 加入的几个 hook,包括 useParams、use...
昨天打完程序码後,出现下面的Bug: Assets/LineRendererSetting.cs(5...
前几篇介绍了 Vuex 管理资料状态,以及在生命周期或导航守卫发送 API 的时机点,再次回到专案范...