vue3 setup syntactic sugar parent-child component pass value, let girlfriend see clearly

foreword

Recently, I want to build a cloud project. I found a template project on gitee. The front end uses vue3 + typeScript. I recently used vue3 to pass values ​​between parent and child components . By the way, I will learn it and summarize it here. , I hope the big guys can point it out.
Vue3 official website: https://cn.vuejs.org/

1. Passing values ​​from parent to child component

Parent component passing parameters

<template>
    <div>
        <!-- 子组件 参数:num 、nums -->
        <child :num="nums.num" :doubleNum="nums.doubleNum" @increase="handleIncrease"></child>
    </div>
</template>

<script setup lang="ts">
 import child from './child.vue';
  import {
      
       ref,reactive } from 'vue';
  // 对象默认
  const nums = reactive({
      
      
    num: 0,
    doubleNum: 0
  });
  // 点击事件
  const handleIncrease = () => {
      
      
    // 每次+1
    nums.num++
    // 每次+2
    nums.doubleNum += 2
  };
</script>

Subcomponents receive parameters

defineEmits: The defineEmits() macro is limited to the syntax sugar of setup, and is used to declare the events to be triggered by the component.

<template>
    <div>
        <span>点击次数:{
   
   { props.num }}</span><br/>
        <span>双倍次数:{
   
   { props.doubleNum }}</span><br/>
        <el-button @click="handelClick">点击</el-button>
    </div>
</template>

<script setup lang="ts">
  import {
      
       ref } from 'vue';
  // 声明组件要触发的事件
  const emits = defineEmits(['increase']);
  // 声明接收参数
  const props = defineProps({
      
      
    num: String,
    doubleNum: String
  });
  //  点击事件
  const handelClick = () => {
      
      
    console.log('触发子组件点击')
    // 触发父组件事件
    emits('increase')
  };
</script>

Parent component small optimization

Official document: https://cn.vuejs.org/guide/components/props.html#prop-passing-details

<template>
    <div>
        <!-- 子组件 参数:对象 -->
        <child v-bind="nums" @increase="handleIncrease"></child>
    </div>
</template>

This is actually equivalent to:

<template>
    <div>
        <!-- 子组件 参数:num 、nums -->
        <child :num="nums.num" :doubleNum="nums.doubleNum" @increase="handleIncrease"></child>
    </div>
</template>

achieve effect

insert image description here
insert image description here

Second, the child passes the value to the parent component

Subcomponents pass parameters

<template>
    <div>
        <el-input v-model="dataForm.name" placeholder="请输入我的名字" style="width: 120px"/>
        <br />
        <el-input v-model="dataForm.age" placeholder="请输入我的年龄" style="width: 120px"/>
        <br />
        <el-button @click="handelClick">完成</el-button>
    </div>
</template>

<script setup lang="ts">
  import {
      
       ref, reactive } from 'vue';
  const emits = defineEmits(['increase']);
  // 对象
  const dataForm = reactive({
      
      
    name: '',
    age: ''
  })
  const handelClick = () => {
      
      
    console.log('触发子组件点击', dataForm.name, ' ', dataForm.age)
    // 传递对象
    emits('increase',dataForm)
  };
</script>

The parent component receives parameters

<template>
    <div>
        <!-- 子组件 触发事件:handleIncrease -->
        <child @increase="handleIncrease"></child>
        <br />
        我是父组件,我接收到的参数:<span v-if="data.name">姓名:{
   
   {data.name}}</span> <span v-if="data.age">, 年龄:{
   
   {data.age}}</span>
    </div>
</template>

<script setup lang="ts">
 import child from './child.vue';
  import {
      
       ref,reactive } from 'vue';
  // 接收对象封装
  const data = reactive({
      
      
    name: '',
    age: ''
  });
  // 点击事件
  const handleIncrease = (val : any) => {
      
      
    data.name = val.name
    data.age = val.age
  };
</script>

achieve effect

insert image description here
insert image description here

3. defineExpose method (commonly used)

Overview: This is the way I see it used in the clone project template, and it is also the most commonly used way.

Pass value from parent to component

<template>
    <div>
        <!-- 子组件 ref:data -->
        <child  ref="data"></child>
        <br />
        <span>我是父组件</span>
         // 输入姓名
        <el-input v-model="name" placeholder="请输入我的姓名" style="width: 120px"/>
        // 点击完成
        <el-button @click="handelClick()">完成</el-button>
    </div>
</template>

<script setup lang="ts">
  import child from './child.vue';
  import {
      
       ref,reactive } from 'vue';
  // 绑定的data
  const data = ref()
  // 姓名事件
  const name = ref('' as string)
  // 点击完成事件
  const handelClick = () => {
      
      
      console.log('name:', name.value)
      // 初始化
      data.value.init(name.value)
      console.log('data: ', data.value)
  }
</script>

The subcomponent receives the value

<template>
    <div>
        <span>我是子组件</span>
        <el-input v-model="dataForm.name" placeholder="请输入我的名字" style="width: 120px"/>
        <br />
        <el-input v-model="dataForm.age" placeholder="请输入我的年龄" style="width: 120px"/>
        <br />
    </div>
</template>

<script setup lang="ts">
  import {
      
       ref, reactive } from 'vue';
  // 组件对应的数据
  const dataForm = reactive({
      
      
    name: '',
    age: ''
  })
  // 假设后端返回list
  const listDate: Array<object> = [{
      
      name: "lanys", age: 23}]
  // 初始化方法 name 指的就是父组件传过来的name
  const init = (name : string) => {
      
      
    if (name) {
      
      
      listDate.forEach((val : any) => {
      
      
        // 如果name 相同就 渲染 就类似更新功能
        if (val.name === name) {
      
      
          dataForm.name = val.name
          dataForm.age = val.age
        }
      })
    }
  }
  // 暴露组件
  defineExpose(
    {
      
      init}
  )
</script>

achieve effect

insert image description here
Enter lanys in the parent component
insert image description here
and click Finish
insert image description here

What are the benefits of such a design?

It can be seen from the project that the new and updated functions can be used universally, saving development time and cost. The project is designed like this,
in the subcomponent init (initialization)

const init = (id?: number) => {
    
    
	// id 存在则为修改
	if (id) {
    
    
		getUser(id)
	}
   // 获取下面的列表数据 可以忽略
	getOrgList()
	// 忽略
	getPostList()
	// 忽略
	getRoleList()
}
// 暴露组件
defineExpose({
    
    
	init
})

New module (no need to pass id)

insert image description here

Update module (pass id)

insert image description here

Guess you like

Origin blog.csdn.net/qq_44697754/article/details/128632501