子组件:
1、模板部分
和vue2 没有任何差别
<template>
<div class="analysis-card" :cardData="cardData" @click='handleClick' >
</div>
</template>
2、 props实现父传子
先在props配置项中定义props传递的数据,再将props传入setup()函数,如下:
export default{
props:{
cardData:{
type:Object
},
},
setup(props){
let cardData = props.cardData;
return{cardData};
}
}
</script>
3、&emit实现事件传递
emits:['EvnentName']// 数组写法
emits:{}//对象写法
export default {
props:{
cardData:{
type:Object
},
},
emits:['onClick'],
setup(props,{emit}){
const handleClick = () => {
emit('customEvent', 'Hello from child!');
};
return {
handleClick
};
}
4、插槽slot
只讲条件插槽,最好用
①条件插槽:结合使用 $slots 属性与 v-if 来实现
可以自定义插槽name,通过条件插槽可以根据插槽是否存在来渲染某些内容,当我在父组件不想渲染这个插槽的时候,我直接不使用就可以不渲染(推荐使用)
可以在slot标签内写默认模板,如果父组件没有设置新的模板,则会由默认模板填充,如果父组件设置新的模板则会替代
<div v-if="$slots.header" class="card-header">
<slot name="header" ></slot>
</div>
②在插槽中实现数据传递
a.普通数据传递:用{{}}包裹就可以实现数据渲染
b.传递图片路径:用:src绑定数据名,这里利用字面量实现,不能用{{}}
示例代码如下:
<div v-if="$slots.footer" class="card-footer" >
<slot name="footer">
<div class="card-footer">
<span class="card-footer-text">{{cardData.leftName}}</span>
<img
v-if="cardData.leftIcon !== ''"
:src="`${cardData.leftIcon}`"
class="card-footer-icon"
alt=""
/>
<span class="card-footer-num">{{cardData.leftNumber}}</span>
</div>
</slot>
</div>
父组件:
1、引入\注册组件:
通过import引入后,在components配置项中注册组件
<script>
import analystCard from './components/AnalystCard.vue'
export default{
components:{
analystCard
},
</script>
2、父组件数据传递至子组件:
利用:data="data"传递
<analyst-card :cardData="cardDataFirst">
注意点:
变量在setup()函数中定义,由于数据类型为对象,因此最好用reactive实现响应式,并且在setup()函数中所有变量一定要return才能被模板获取
setup(){
const cardDataFirst = reactive({
leftName:'周同比',
leftNumber:'12%',
leftIcon:'/src/assets/images/visual/icon_content_arrow_red.svg',
rightName:'日同比',
rightNumber:'11%',
rightIcon:'/src/assets/images/visual/icon_content_arrow_green.svg',
});
return {cardDataFirst}
}
3、父组件监听子组件事件:
可以使用 v-on
指令(或简写为 @
)来监听子组件发出的自定义事件
<analyst-card @onClick="handleEvent">
export default {
/*引入部分省略*/
setup(){
function handleEvent(message) {
console.log(message);
}
return{handleEvent}
}
4、插槽slot:
插槽用<template #name>定义,一个插槽一个模板,由于之前的代码header、title、chart都只设置了空插槽,而插槽footer中有设置默认插槽,并且涉及数据传递,因此父组件的数据直接传递到插槽footer中,此时footer插槽没有编写任何代码,页面会使用子组件中的默认插槽