您的位置:

{{ keyword }}在Vue3父子组件传值的实现方式

在Vue3中,父子组件是常见的组件通信方式,而实现父子组件传值则是其中比较重要的一种应用场景。本文将从以下几个方面来详细介绍Vue3中实现父子组件传值的几种方式。

一、props

在Vue3中,props依然是一个非常重要的属性,通过在子组件中设置props选项,可以让父组件向子组件传递数据:

// 父组件传递数据到子组件
<template>
  <child-component :message="parentMessage">
  </child-component>
</template>

<script>
import ChildComponent from './ChildComponent';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent component'
    };
  }
}
</script>

// 子组件接收props数据
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: String
  }
}
</script>

此时,父组件向子组件传递了一个字符串类型的message数据,而子组件接收到该数据并直接在页面中渲染出来。

二、依赖注入provide/inject

在Vue3新增了provide/inject选项,用于实现父组件向子孙组件传递数据,使用方式如下:

// 父组件提供数据
<template>
  <child-component>
  </child-component>
</template>

<script>
import { provide } from 'vue';
import ChildComponent from './ChildComponent';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const parentMessage = 'Hello from parent component';
    provide('message', parentMessage);
  }
}
</script>

// 子组件接收provide中的数据
<template>
  <grandchild-component></grandchild-component>
</template>

<script>
import { inject } from 'vue';
import GrandchildComponent from './GrandchildComponent';

export default {
  components: {
    GrandchildComponent
  },
  setup() {
    const message = inject('message');
    return {
      message
    }
  }
}
</script>

// 孙子组件中使用父组件提供的数据
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  setup(props, { attrs, slots, emit }) {
    // 这里也可以使用inject来获取到父组件提供的数据
  }
}
</script>

在父组件中使用provide来提供数据,而在子孙组件中使用inject来获取父组件提供的数据。需要注意的是,provide/inject是依赖底层组件实例的引用来实现的,所以不能在setup函数外使用。

三、$attrs/$listeners

在Vue3中,$attrs/$listeners是一种新的组件属性,前者获取父组件传递过来的非prop属性,后者获取父组件传递过来的非prop事件,使用方式如下:

// 父组件向子组件传递非prop属性和事件
<template>
  <child-component title="Hello World" @click="doSomething"></child-component>
</template>

// 子组件中使用$attrs和$listeners来访问父组件传递过来的数据
<template>
  <div :title="$attrs.title" @click="$listeners.click"></div>
</template>

<script>
export default {
  inheritAttrs: false // 必须设置,否则会将所有的非prop属性透传到根元素上
}
</script>

这里子组件中使用$attrs.data来访问title属性,$listeners.click来访问click事件。

四、$emit

在Vue3中,$emit是一种子组件向父组件传递数据的方法,使用方式如下:

// 子组件向父组件传递数据
<template>
  <div @click="sendMessage"></div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('message', 'Hello from child component');
    }
  }
}
</script>

// 父组件接收子组件传递过来的数据
<template>
  <child-component @message="handleMessage"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleMessage(message) {
      console.log(message);
    }
  }
}
</script>

子组件中通过$emit来传递数据,而父组件则通过@message来监听message事件,并在回调函数中获取到子组件传递过来的数据。

五、ref/$refs

在Vue3中,ref/$refs是一种组件引用方式,可以在父组件中通过ref属性来获取到子组件实例,从而可以调用子组件中的方法和属性,使用方式如下:

// 父组件中获取子组件实例
<template>
  <child-component ref="child"></child-component>
</template>

<script>
import { ref } from 'vue';
import ChildComponent from './ChildComponent';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const childRef = ref(null);
    return {
      childRef
    }
  },
  mounted() {
    console.log(this.$refs.child); // 这里也可以获取到子组件实例
  }
}
</script>

// 子组件中可以通过this.$emit来向父组件传递数据
<template>
  <div></div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('message', 'Hello from child component');
    }
  }
}
</script>

在父组件中,可以通过ref来获取到子组件的实例,在子组件中则可以通过this.$emit来向父组件传递数据。

通过以上五种方式,我们可以在Vue3中实现父子组件之间的数据传递和通信。需要根据实际场景来选择不同的实现方式,以达到更好的应用效果。