Vue3 + TS + Vite 父子组件间如何通信?

更新日期: 2022-07-27阅读: 1.4k标签: 组件

组件之间传值,大家都很熟悉,涉及到 vue3 +TS 好多同学就无从下手了,所以分享这篇文章,希望看完后提起 VUE3+TS 能够不慌不忙。

平时使用的函数如:ref、reactive、watch、computed 等需要先引入才能使用,但是本篇文章介绍的 defineProps、withDefaults、defineEmits、defineExpose 都是开箱即用的函数,无需引入。


父向子传值:defineProps

在父组件内给子组件传值时,通过 v-bind 绑定一个数据,然后子组件使用 defineProps 接收数据。

可以传递的数据有两种:字符串类型 和 非字符串类型。字符串类型不需要 v-bind,非字符串需要使用 v-bind,可以简写成冒号(:)。

/* 父组件代码 */
<template> 父组件
<child-com title="父组件向子组件传值" :list="list"></child-com>
</template>
<script lang="ts" setup>
import ChildCom from './component/ChildCom.vue'
const list: Array < number > = [1, 2, 3, 4, 5]
</script>

子组件接收的时候使用 defineProps,需要注意的是我们使用 TS 需要加类型限制,如果不是 TS 的可以直接使用。

TS 语法使用:

defineProps<{title: string;  data: number[]}>()

非 TS 语法使用:

defineProps({title: {    default: "",    type: string  },  list: Array})

对应上边父组件传值,使用 TS 语法接收的子组件代码为:

<template> 子组件 {{ title }} {{ list }}</template>
<script lang="ts" setup>
interface DefineProp {
title: string list: Array < number >
}
defineProps < DefineProp > ()
</script>


默认值:withDefaults

在非 TS 语法中,default 可以设置默认值,在 TS 语法中,如何设置默认值呢?

withDefaults 是一个无需引入开箱即用的函数,可以接收两个参数,第一个用于defineProps 接收参数,第二个参数是一个对象用于设置默认值。

使用方式1:分离模式

type Props = {title?: string;  list?: number[]}
withDefaults(defineProps<Props>(), {title: "默认值",  list: () => [1, 2]})

使用方式2:组合模式

widthDefault(defineProps<{ title?: string, list?: number[] }>(),  {title: "默认值",  list: () => [1, 2]})

给上边的子组件添加默认值代码如下:

<template> 子组件 <br /> {{ title }} <br /> {{ list }}</template>
<script lang="ts" setup>
interface DefineProp {
title ? : string list ? : Array < number >
}
withDefaults(defineProps < DefineProp > (), {
title: '设置title默认值',
list: () => [1, 2],
})
</script>

将父组件中传的值删除掉之后,发现设置的默认值就展示出来了。


子向父传值:defineEmits

子组件给父组件进行传值时,都是通过派发事件,去触发父组件中的事件并接收值。

在子组件绑定一个 @click 事件,然后通过 defineEmits 注册自定义事件,当点击 @click 事件时触发 emit 去调用注册事件,然后传递参数。

非 TS 声明语法

// clickname 父组件自定义事件名
let emit = defineEmits([ 'clickname' ])
const postV = () => {emit('clickname', '传递的值或变量')}

TS 声明语法

// clickname 父组件自定义事件名
let emit = defineEmits<{(e: 'clickname', str: string): void}>()
const postV = (str: string): void => {emit('clickname', str)}

如果是多个自定义事件,写法如下:

type Person = {
name: string age: number
}
let emit = defineEmits < {(e: 'clickname', str: string): void(e: 'getData', per: Person): void} > () const postV = (str: string): void => {
emit('clickname', str)
}
const postVData = (per: Person): void => {
emit('getData', per)
}

我们在子组件内,使用 defineEmits 添加派发事件:

<template> 子组件 <button @click="postV">子向父传值</button> <button @click="postVal('传递字符串')">子向父传data</button></template>
<script lang="ts" setup>
import { reactive } from 'vue' // 子向父传值
type Person = {name: string age: number}
const per = reactive < Person > ({ name: 'qq', age: 18,}) const emit = defineEmits < {(e: 'clickname', per: Person): void(e: 'getData', data: string): void } > () const postV = (per: Person): void => {
emit('clickname', per)
}
const postVal = (data: string): void => {
emit('getData', data)
}
</script>

父组件内使用自定义事件,接收子组件传递来的数据:

<template> 父组件 <child-com @clickname="getChildVal" @getData="getChildData"></child-com></template>
<script lang="ts" setup>
iimport ChildCom from './component/ChildCom.vue'
const getChildVal = (per: {
name: string;age: number
}): void => {
console.log('per:', per)
}
const getChildData = (data: string): void => {
console.log('data', data)
}
</script>


defineExpose

子组件向父组件传值时,除了使用 defineEmits 之后,也可以使用 defineExpose ,它是通过把组件自己的属性暴露出去,父组件先获取到子组件,再获取属性值。

defineExpose 接收一个对象参数,包含需要传递的属性。

defineExpose({name,  count,  ....})

在子组件内,定义和暴露需要传递的属性:

<template>  子组件</template>
<script lang="ts" setup>
  const count: number = 1defineExpose({  count,})
</script>

在父组件内使用 ref 获取到子组件,然后打印属性:

<template> 父组件 <child-com ref="child"></child-com> <button @click="getProp">获取子组件属性</button></template>
<script lang="ts" setup>
import ChildCom from './component/ChildCom.vue'
import { ref } from 'vue'
const child: htmlElement = ref() const getProp = (): void => {
console.log(child.value.count)
}
</script>


链接: https://fly63.com/article/detial/11952

Vuetify基于vue2.0,为移动而生的组件框架

Vuetify 支持SSR(服务端渲染),SPA(单页应用程序),PWA(渐进式Web应用程序)和标准HTML页面。 Vuetify是一个渐进式的框架,试图推动前端开发发展到一个新的水平。

Vue中插槽的作用_Vue组件插槽的使用以及调用组件内的方法

通过给组件传递参数, 可以让组件变得更加可扩展, 组件内使用props接收参数,slot的使用就像它的名字一样, 在组件内定义一块空间。在组件外, 我们可以往插槽里填入任何元素。slot-scope的作用就是把组件内的数据带出来

react 函数子组件(Function ad Child Component)

函数子组件(FaCC )与高阶组件做的事情很相似, 都是对原来的组件进行了加强,类似装饰者。FaCC,利用了react中children可以是任何元素,包括函数的特性,那么到底是如何进行增强呢?

Vue和React组件之间的传值方式

在现代的三大框架中,其中两个Vue和React框架,组件间传值方式有哪些?组件间的传值是灵活的,可以有多种途径,父子组件同样可以使用EventBus,Vuex或者Redux

vue.js自定义组件directives

自定义指令:以v开头,如:v-mybind。bind的作用是定义一个在绑定时执行一次的初始化动作,观察bind函数,它将指令绑定的DOM作为一个参数,在函数体中,直接操作DOM节点为input赋值。

vue中prop属性传值解析

prop的定义:在没有状态管理机制的时候,prop属性是组件之间主要的通信方式,prop属性其实是一个对象,在这个对象里可以定义一些数据,而这些数据可以通过父组件传递给子组件。 prop属性中可以定义属性的类型,也可以定义属性的初始值。

Web组件简介

Web组件由三个独立的技术组成:自定义元素。很简单,这些是完全有效的HTML元素,包含使用一组JavaScript API制作的自定义模板,行为和标记名称(例如,<one-dialog>)。

web组件调用其他web资源

web组件可以直接或间接的调用其他web资源。一个web组件通过内嵌返回客户端内容的另一个web资源的url来间接调用其他web资源。在执行时,一个web资源通过包含另一个资源的内容或者转发请求到另一个资源直接调用。

vue中如何实现的自定义按钮

在实际开发项目中,有时我们会用到自定义按钮;因为一个项目中,众多的页面,为了统一风格,我们会重复用到很多相同或相似的按钮,这时候,自定义按钮组件就派上了大用场,我们把定义好的按钮组件导出,在全局引用,就可以在其他组件随意使用啦,这样可以大幅度的提高我们的工作效率。

Vue子组件调用父组件的方法

Vue中子组件调用父组件的方法,这里有三种方法提供参考,第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法,第二种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!