由于Vue的开发是基于Component,当使用vue进行开发通常会遇到以下问题:组件间的传值要按什么样的方式进行
根据类型一般有父组件向子组件传参数、子组件向父组件传参数。
注意:本博客代码使用Vue组合式开发
一、子组件向父组件传参数
一般用于解决全局组件的状态改变
,父组件获取某个子组件选择后的信息
实现方式包括emit、inject(注入)。
1.emit监听事件
可手动触发事件,通过组件间emit,逐级传播信息(推荐两个组件间,如果相隔太多,使用provide、inject)
这是我项目中做的,选择prompt的use it按钮后,把值传给输入框
按钮添加方法getdetails
<div style="display:flex;justify-content:flex-end;align-items:flex-end;">
<el-button @click="getdetails(index.prompts)">Use it</el-button>
<div>
使用emit发送事件需要先注册,在父组件根据相应名字获取 (父组件监听事件的命名请参考Vue.js的官方文档,有多种命名方式)
const emit = defineEmits(["response"]);
function getdetails(detail: string) {
emit("response", detail);
centerDialogVisible.value = false;
}
父组件设置监听,这里使用@response
<div class="flex flex-1">
<PromptLibrary @response="(msg: string) => textarea += msg" />
</div>
使用prompt成功后,将值传回
2.inject(可修改父组件传来的值)
provide 和 inject : 一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
在App.vue里注册全局变量,使用它控制侧边栏的显示与否
点击开始游戏后,侧边栏隐藏,这里仅介绍退出后,重新显示
<template>
<div class="flex flex-row h-screen">
<SideBar v-if="shouldShowGlobalComponent" />
<RouterView class="w-full p-4 py-8" />
</div>
</template>
<script setup lang="ts">
import { RouterView } from "vue-router";
import SideBar from "@/components/SideBar.vue"
import { provide, ref } from "vue";
const shouldShowGlobalComponent = ref(true);
provide('shouldShowGlobalComponent', shouldShowGlobalComponent)
</script>
这里使用inject获取App.vue传来的参数,并在点击退出后,更改侧边栏显示状态
import { ref, inject, type Ref } from 'vue'
const dialogTableVisible = ref(false)
const shouldShowGlobalComponent = inject('shouldShowGlobalComponent') as Ref<boolean>
function showGlobalComponent() {
shouldShowGlobalComponent.value = true
}
二、父组件向子组件传参数
实现方式:defineProps、provide
1.defineProps
我在该组件里面添加了子组件,在点击下面的选项后,将值传给子组件,来展示数据
...
<Details :jsondataicon="jsondata.icon" :jsondataprompts="jsondata.prompts"
:jsondatabackground="jsondata.background" :jsondataname="jsondata.name"
:jsondatadescription="jsondata.description" v-if="isVisible" @close="isVisible = false"
v-model="isVisible"@usePrompt="(msg: string) => finishChoosePrompt(msg)" />
...
在子组件中直接获取,父组件传来的参数,命名需要一致
<script setup lang="ts">
import { defineProps, reactive } from 'vue';
interface Jsondata {
name: string;
description: string;
prompts: string;
background: string;
icon: string;
}
const props = defineProps({
jsondataicon:String,
jsondataname:String,
jsondatadescription:String,
jsondatabackground:String,
jsondataprompts:String,
});
const myData = reactive<Jsondata>({
name: props.jsondataname as string,
description:props.jsondatadescription as string,
prompts: props.jsondataprompts as string,
background: props.jsondatabackground as string,
icon: props.jsondataicon as string,
});
2.provide
略,同上
项目地址
YACW :https://github.com/yacw-team/