Vue面试之组件通信的方式总结(上篇)

Vue面试之组件通信的方式总结

  • props父子组件传参
    • props父组件向子组件传参
      • 数组形式
      • 对象的简单形式
      • 对象的复杂形式
    • props子组件向父组件传参
      • 通过传递方法的形式
      • 通过传递事件的形式
  • 插槽
    • 默认插槽
    • 具名插槽
    • 作用域插槽

    最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容,会不断进行整理~

    在Vue框架中,提供了多种组件通信方式:props父子组件传参、插槽传参、Event Bus方式、vuex方式传参等,本篇先对前两种方法进行总结~

props父子组件传参

props父组件向子组件传参

props算是vue中比较简单的语法,通过在标签中定义属性的方式实现父组件对子组件的信息传递,关于传参的限定有三种方式:
需要注意的是,props是单向数据流传递,因此对接收到的props只是使用,不能修改!

数组形式

该方式是最为简单的方式,只需在接收prop的组件中以数组的形式备案要使用的props参数名即可,如下示例:

export default {
	name: 'xxx',
	props: [
		'name', 'age', 'sex'
	]
}

对象的简单形式

如果想要指定接收props参数的类型,可通过此种方式进行简单限定,如:

export default {
	name: 'xxx',
	props: {
		name: String,
		age: Number,
		sex: String
	}
}

对象的复杂形式

如果还要对参数进行进一步的限制,如是否必输、默认值等,可采用此种方式进行限定:

export default {
	name: 'xxx',
	props: {
		name: {
			type: String,
			required: false,
			default: '小红'
		},
		age: {
			type: Number,
			required: true,
			default: 12
		},
		sex: {
			type: String,
			required: false
		}
	}
}

如果传递prop时没有满足对应限制,则会在控制台上报错。

props子组件向父组件传参

props也可实现子组件向父组件传递数据,即利用父组件向子组件传递事件/方法的形式,通过这种方式,在子组件使用父组件传过来的方法时,就可利用参数传递的方式,将参数传递给父组件,真是妙~

通过传递方法的形式

/* parent组件 * /
<Son :something="doSomething">Son> // 将doSomething方法进行传递
export default {
  name: "Parent",
  components: {
    Son,
  },
  methods: {
    doSomething(name) {
      console.log(name, '这就是由子组件传递过来的name值');
    },
  },
};
// Son组件
<template>
  <button @click="do">点击触发方法</button>
</template>
<script>
import Son from './Son.vue';
export default {
	name: 'Son',
	props: ['something']
}
do() {
  this.something('小明') // 将子组件的参数传递给父组件
}
</script>

通过传递事件的形式

上述方法也可以通过$emit方法来调用父组件方法,从而将子组件参数传递给父组件,修改如下:

// 父组件
<template>
	<Son @doSomething="something"></Son>
</template>
<script>
import Son from './Son.vue';
	export default {
		name: 'Parent',
		components: {
			Son
		}
		methods: {
			something(params) {
				console.log('拿到子组件传递过来的参数', params)
			}
		}
	}
</script>
// 子组件
<template>
	<Button @click="do"></Button>
</template>
<script>
	export default {
		name: 'Son',
		methods: {
			do() {
				this.$emit('doSomething', '小红') 
				// 触发父组件的doSomething事件,并将'小红'传递出去
			}
		}
	}
</script>

插槽

Vue提供了插槽机制,所谓插槽是指我现在这块地方要写一些内容,但是内容还不确定,因此我在此处用插槽占上位置,等后续在别处补充好了内容,就可以在此处展现出来效果。插槽用slot标签表示,有默认插槽具名插槽以及作用域插槽三种;而插槽的内容要写在组件标签之间,如

<A>此处即为插槽内容A>

插槽的官方说法如下:

插槽作为组件的内容分发出口。它允许在父组件中,将任意子组件的内容“插入”到组件模板中的特定位置,以便在不同的场景下展示不同的内容。插槽提供了一种灵活的方式来组合父组件和子组件的内容,并允许创建更灵活、可复用的组件。

默认插槽

默认插槽是最简单的一种,形如:

<slot><slot>
<template>
	<div>这是Parent组件</div>
	<Son>插槽内容</Son>
</template>
<script>
import Son from './Son.vue';
	export default {
		name: 'Parent',
		components: {
			'B'
		}
		...
	}
</script>
<template>
	<div>这是Son组件</div>
	<slot></slot> // 插槽中的内容就会替换到这里
</template>
<script>
	export default {
		name: 'Son',
		...
	}
</script>

具名插槽

见名之意,就是为不同插槽起不同的名字,用于区分不同插槽;通过在slot标签中设置name属性即可;

<template>
	<header>
		<slot name="header">slot>
	header>
	<main>
		<slot name="main">slot>
	main>
	<footer>
		<slot name="footer">slot>
	footer>
template>

在向具名插槽提供内容时,可通过template标签设置slot指令指定其名称,如:

<template>
	<div>这是Parent组件</div>
	<Son>
		<template slot="header">这是标题内容.....</template>
		<template slot="main">这是主要内容.....</template>
		<template slot="footer">这是底部内容.....</template>
	</Son>
</template>
<script>
	export default {
		name: 'Parent',
		components: {
			'B'
		}
		...
	}
</script>

作用域插槽

如果想要将父组件访问子组件数据,此时可以使用作用域插槽方法,简单来说,就是在子组件slot标签上定义要传递的参数prop,这样在父组件中就可以通过slot-scope属性定义;

作用域插槽(或称为具名插槽的插槽内容作用域)允许子组件将数据传递给父组件,并且在父组件中可以直接访问和使用这些数据。

// Son组件
<template>
	<div>
		<div>son组件div>
		<slot :obj="obj">slot> // 利用prop将obj数据传出去
	div>
template>
// Parent组件
<template>
	<div>
		<div>parent组件div>
		<template slot-scope="data">
			{{data.obj}} 
			// 这里就可以拿到传递过来的数据obj,data可以随便定义
		template>
	div>
template>

以上示例皆是基于Vue2版本,在Vue3中,使用v-slot代替了slot-scope,在使用具名插槽和作用域插槽时要注意区分~

你可能感兴趣的:(前端面试,vue.js,面试,前端)