思考:
- 父组件给子组件传值如何操作?
通过vue的prop组件属性可以实现父组件给子组件传值。 - 父组件如何给子组件传递html内容?
法一:使用prop将父组件想要传的
值传到子组件,然后在子组件中写一堆代码把父组件传的html内容接收过来。
法二(推荐使用):使用slot插槽,可以直接将父组件中写的html文本直接传递给子组件。 - 什么是slot插槽?
父组件为了给子组件传递内容而定义的。(写在父组件中的内容在子组件中显示)
案例:
4. 将苹果和橘子通过prop由父组件传递给子组件实现
5. 将苹果和橘子通过slot由父组件中写html内容,在子组件中显示。
总结:
- slot是在子组件中写入的,一旦走进组件标签(父组件中引入的子组件)内部,其显示内容的顺序就由组件标签(父组件中引入的子组件)决定。
这就是为什么会有:【在组件标签内再展示一些内容,默认是不会生效的,需要加上才生效。】这种情况。 - slot插槽显示的内容由父组件进行控制;插槽显示不显示和显示顺序由子组件控制。
具体代码解释:
- 匿名插槽
父组件:父组件在引入的子组件里又放了一堆内容,这堆内容的显示将会依照在子组件内部的顺序依次执行显示。
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<p>第三个显示的</p>
<p>第四个显示的</p>
<chilchildren></chilchildren>
<p>第五个显示的</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
</script>
子组件:此组件放了两个匿名插槽,意味着将在父组件里引入的子组件内部的内容显示两次。
<template>
<div class="slotOne">
<p>第二个显示的</p>
<slot></slot>
<p>第六个显示的</p>
<!-- 注意这里又放了一个匿名插槽,意味着将在父组件里面引入的子组件内部的内容显示两次 -->
<slot></slot>
<p>第七个显示的</p>
</div>
</template>
效果:
2. 具名插槽
父组件:使用v-slot或者#(v-slot的语法糖)或者slot(vue 3.0已废弃此中写法)来对应子组件的某个插槽。
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<!-- <template v-slot:one> v-slot和#只能在template中写入-->
<template #one>
<p>第三个显示,因为对应子标签name为one的slot</p>
</template>
<p>
特别注意:因为在子标签没有对应的匿名slot,故这下此内容和下面的子子标签就不会显示了
</p>
<chilchildren></chilchildren>
<p slot="two">第五个显示,因为对应子标签name为two的slot</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
</script>
子组件:使用name属性来区分各个插槽,方便在父组件中调用。
<template>
<div>
<p>第二个显示的</p>
<slot name="one"></slot>
<p>第四个显示的</p>
<slot name="two"></slot>
</div>
</template>
效果:
父组件:
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<template slot="one">
<p>第三个显示,因为对应子标签name为one的slot</p>
</template>
<p>
第五个显示的,特别注意:因为在子标签有了相对应的匿名slot,故这下此内容和下面的子子标签就显示了
</p>
<chilchildren></chilchildren>
<p slot="two">第七个显示</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
子组件:
<template>
<div>
<p>第二个显示的</p>
<slot name="one"></slot>
<p>第四个显示的</p>
<slot></slot>
<slot name="two"></slot>
</div>
</template>
效果:
3. 作用域插槽:
此时就映射到slot-scope="scope"了
有时让插槽内容能够访问子组件中才有的数据是很有用的。比如我们在使用ant-design-vue的表格控件时,
<a-table-column title="注释" dataIndex="comment" >
<template slot-scope="text, record">
<rx-textbox v-model="record.comment" ></rx-textbox>
</template>
</a-table-column>
这里从控件传递数据到父组件,我们在使用组件的时候可以根据我们的需要显示需要的效果,表格控件并不需要关心如何实现数据的展示~
父组件用slot-scope来接收子组件的值,此时slot-scope的名字可以为任意,它默认是一个对象,会拿到子组件data中的所有的数据。
父组件:
<template>
<div class="hello">
<Children>
<!-- anyName默认可以随便起名字,它默认是一个对象,获取到的是Children组件中的data总数据,用它anyName.importData取出user数据 -->
<template slot-scope="anyName">
<p v-for="(item, index) in anyName.importData" :key="index">
{{ item }}
</p>
</template>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
export default {
components: {
Children,
},
}
</script>
子组件:
<template>
<div>
<!-- importData待会父组件就可以用它来获得到user数据 -->
<slot :importData="user"></slot>
</div>
</template>
<script>
export default {
components: {},
name: '',
data() {
return {
user: [
{ name: '小小', age: 18 },
{ name: '大大', age: 18 },
{ name: '呼呼', age: 18 },
],
}
}
</script>
效果: