请详细说一下Vue中的组件传值

前端面试题

Vue中的组件传值分哪几种情况,分别如何实现?

  • 父子传值
  • 子父传值
  • 插槽
  • 订阅

父子传值->父传子接

关键词:props

父组件:

<template>
    <child :hobby="myHobby"></child>
</template>

<script>
import Child from './children/child'
export default {
    data(){
        return{
            myHobby:['抽烟','喝酒','烫头','敲代码'],
        }
    },
    components:{
        Child,
    }
}
</script>

<style scoped>
</style>

子组件:

<template>
   <div (index,hobby)in hobby :key="index">{{hobby}}</div> 
</template>

<script>
export default {
    props:['hobby']
}
</script>

<style scoped>
</style>

这么一来子组件就能接到父组件定义的hobby
记住谁有props谁就是子组件
格式:

		父组件:
             <子组件 :绑定的属性="初始化的值"></子组件>
        格式1:    
             子组件 
	         props:['绑定的属性']
        格式2:
             子组件
             props:{
                绑定的属性:数据类型,
                绑定的属性2:数据类型
             }

             数据类型:Number Array Object Function Boolean
             注意不能传递标签
        格式3:
             props:{
                  绑定的属性:{
                      type:数据类型,
                      required:是否需要设置数据类型
                  }
             }


子父传值->子传父接

关键词:$emit,我们已自定义事件来说明这个问题

父组件:

自定义事件 @customize

<template>
    <child :hobby="myHobby" @customize="deleteNode"></child>
</template>

<script>
import Child from './children/child'
export default {
    data(){
        return{
            myHobby:['抽烟','喝酒','烫头','敲代码'],
        }
    },
    methods:{
        deleteNode(index){
            //待写
        }
    },
    components:{
        Child,
    }
}
</script>

<style scoped>
</style>

现在父组件需要的index 需要子组件传过来 看子组件

子组件

<template>
  <div (index,hobby)in hobby :key="index">
    <span>{{ hobby }}</span>
    <span class="text-muted" @click="dele(index)" style="cursor: pointer"
      >删除</span
    >
  </div>
</template>

<script>
export default {
  props: ["hobby"],
  methods: {
    dele(index) {
      /* this.$emit('父组件中的自定义事件',要传递的值) */
      this.$emit("customize", index);
    },
  },
};
</script>

<style scoped>
</style>

$emit登场用来讲子组件的一个事件和父组件自定义事件绑定在一块,并且把index传过去,
那么完善父组件代码就可以了 如下

<template>
    <child :hobby="myHobby" @customize="deleteNode"></child>
</template>

<script>
import Child from './children/child'
export default {
    data(){
        return{
            myHobby:['抽烟','喝酒','烫头','敲代码'],
        }
    },
    methods:{
        deleteNode(index){
            //删除
            this.hobbies.splice(index,1)//index通过子组件拿到了
        }
    },
    components:{
        Child,
    }
}
</script>

<style scoped>
</style>

ok子父传值就这些东西

插槽

插槽也是用于父传子接的传值方式,不过与上面不一样的是它可以传String
比如 重来两个.vue文件

父组件

<template>
  <div>
    <child>
      <!-- 插头 -->
      <h1 class="page-header" slot="customize">{{ title }}</h1>
    </child>
  </div>
</template>

<script>
import Child from "./children/child";
export default {
  data() {
    return {
      title: "面板",
    };
  },
  components: {
    Child,
  },
};
</script>

<style scoped>
</style>

子组件:

<template>
 <div>
     <slot name ="customize"></slot><!-- 插线板 -->
 </div>
</template>

<script>
export default {
};
</script>

<style scoped>
</style>

插槽的规则👇

slot插槽分发内容(父子标签+数据)
	A:用于父组件向子组件传递 标签和数据
	B:数据必须初始化在父组件中
	父组件:插头
	<子组件>
	     <tagName slot="插槽名"></tagName>
	</子组件>
	
	子组件:插线板
	<slot name="插槽名"></slot>

任意组件传值–>订阅和发布

PubSubJs(任意组件数据)
	A:用来实现非父子组件之间的通信,使用PubSubJs进行消息发布与订阅模式,来进行数据传递
	B:必须安装
	  npm install pubsub-js   
	C:由于是第三方插件,必须使用箭头函数
	  
	订阅:
	PubSub.subscribe('订阅的事件',(event,传递的数据)=>{
         
     })
     发布:
     PubSub.publish('订阅的事件',传递的数据)

把上面父子组件拿过来改一改就有了下面的代码

发布组件(发):

<template>
    <div>
        <child :hobby="myHobby" @customize="deleteNode"></child>
    </div>
</template>

<script>
import Child from './children/child'
export default {
    data(){
        return{
            myHobby:['抽烟','喝酒','烫头','敲代码'],
        }
    },
    methods:{
        deleteNode(index){
            //发布
            PubSub.publish('changNum',1)
        }
    },
    components:{
        Child,
    }
}
</script>

<style scoped>
</style>

发布组件的自定义事件被触发会发布(publish)内容 向changNum这个订阅内容发送一个数字1

订阅组件(收):

<template>
  <div (index,hobby)in hobby :key="index">
    <span>{{ hobby }}</span>
    <span class="text-muted" @click="dele(index)" style="cursor: pointer"
      >删除</span
    >
  </div>
</template>

<script>
export default {
  props: ["hobby"],
  data() {
    return {
      delNum: 0,
    };
  },
  methods: {
    dele(index) {
      /* this.$emit('父组件中的自定义事件',要传递的值) */
      this.$emit("customize", index);
    },
  },
  created() {
    /* 订阅 */
    PubSub.subscribe("changNum", (event, num) => {
      this.delNum = this.delNum + num;
    });
  },
};
</script>

<style scoped>
</style>

订阅(subscribe) changeNum内容的组件会第一时间接收到发布组件发布的event或者num 接下来你就可以执行你需要的操作

  • 订阅和发布不局限于父子组件之间

总结

组件传值这一块内容相对比较繁杂,在开发中因为有Vuex,用的相对不多,所以大家理一理思路能忽悠面试官就足够了,喜欢可以点赞加关注欢迎转载,会持续更新 么么哒~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

商朝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值