Vue3 setup组件的传参--父传子,子传父(语法糖)

302 阅读4分钟

一. 前言

vue3的组件传参(父传子,子传父)有两种方式:

  1. setup参数(juejin.cn/post/743219…)

2. 语法糖:setup语法糖,帮我们自动return

与vue2组件的传参有相似,不详细的地方可先看vue2的传参方式(vue2父传子,vue2子传父)

二.准备工作--组件的引入

setup语法糖与setup写法区别挺大的.在js中写入setup语法糖

<script lang="ts" setup>
</script>

1.引入组件并注册(语法糖中不需要单独注册)

import son from "./son.vue";

2.使用子组件

<son></son>

三.开始传参

1.父传子

(1) 在父组件中定义变量

直接在js中写即可

<script lang="ts" setup>
    let msg1 = ref("我是父组件中的msg1")
    let msg2 = ref("我是父组件中的msg2")
</script>

(2) 传参

方法一:给子组件绑定自定义属性,defineProps

在父组件中,给子组件绑定自定义属性

<son :msg1="msg1" :msg2="msg2"></son>

在子组件中去接收数据.

首先设置语法糖,引入组合式api(defineProps),然后跟props一样

<script lang="ts" setup>
// 引入组合式api
import { defineProps } from 'vue'

// defineProps()相当于setup中第一个参数,用于接收父传子数据

// 相当于props
defineProps({
  msg1:{
    type:String
  }
})
</script>
方法二:v-model:自定义名称

在父组件中写个变量

let count = ref("我是父组件中的count")

在子组件写绑定v-model:自定义名称="变量"

<son v-model:count1="count"></son>

在子组件中接受数据

<script lang="ts" setup>
// 引入组合式api
import { defineProps } from 'vue'

// defineProps()相当于setup中第一个参数,用于接收父传子数据

// 相当于props
defineProps({
  // 接收v-model
  count1:{
    type:String
  }
})
</script>
方法三:useAttrs

引入组合式api(useAttrs)

<script lang="ts" setup>
// 引入组合式api
import { useAttrs } from 'vue'

// useAttrs相当于setup中第二个参数中的attres

// 相当于attrs
const attrs = useAttrs()
console.log(attrs.msg2);
</script>

渲染到页面直接 {{attrs.msg2}}即可

2.子传父

(1) 给父组件中的子组件绑定自定义方法

    <son @handleA="handleA" @handleB="handleB"></son>

(2) 在父组件中定义变量

直接在js中写即可

<script lang="ts" setup>
    let str1=ref("我是大儿子")
    let str2=ref("我是二儿子")
</script>

(3) 传参 defineEmits

1 子组件发送数据

引入组合式api(defineEmits)

<script lang="ts" setup>
  // 引入组合式api
  import { defineEmits } from 'vue'

  // defineEmits相当于setup中第二个参数中的emit

  // 相当于emit defineEmits(['自定义语法名'])
  const emit = defineEmits(["handleA","handleB"])
  // 自定义方法名,传递数据
  emit("handleA",str1.value)
  emit("handleB",str2.value)
</script>
2 父组件接收数据
<script lang="ts" setup>
// 1 引入组件并注册
import son from "./son.vue";
// 引入组合式api
import { ref } from 'vue';

// 子传父开始
let str1 = ref('')
let str2 = ref('')
let handleA = (val:any)=>{
  // 将子传父传过来的值赋值给str1
  str1.value=val
}
let handleB = (val:any)=>{
  // 将子传父传过来的值赋值给str2
  str2.value=val 
}
// 子传父结束

</script>

渲染数据

    <!-- 渲染子传父 -->
    <p>子传父:{{ str1 }} --- {{ str2 }}</p>

四.代码

父组件

<template>
  <div class="father">
    <h1>父组件</h1>
    <p>msg1:{{ msg1 }}</p>
    <button @click="handleClick">点击</button>
    <!-- 2 使用组件 -->
    <son :msg1="msg1" :msg2="msg2" v-model:count1="count" @handleA="handleA" @handleB="handleB"></son>

    <!-- 渲染子传父 -->
    <p>子传父:{{ str1 }} --- {{ str2 }}</p>
  </div>
</template>
<!-- setup语法糖,帮我们自动return -->
<script lang="ts" setup>
// 1 引入组件并注册
import son from "./son.vue";
// 引入组合式api
import { ref } from 'vue';

let msg1 = ref("我是父组件中的msg1")
let msg2 = ref("我是父组件中的msg2")
let count = ref("我是父组件中的count")
let handleClick = ()=>{
  // console.log(msg1,msg2);
  msg1.value+="+"
}
// 子传父开始
let str1 = ref('')
let str2 = ref('')
let handleA = (val:any)=>{
  // 将子传父传过来的值赋值给str1
  str1.value=val
}
let handleB = (val:any)=>{
  // 将子传父传过来的值赋值给str2
  str2.value=val 
}
// 子传父结束

</script>

<style lang="scss" scoped>
  .father{
    padding: 20px;
    background: rgb(207, 79, 101);
  }
</style>

子组件

<template>
  <div class="son">
    <h1>子组件</h1>
    <p>
      defineOptions:{{ list }}
    </p>
    <p>接收父组件中参数:{{ msg1 }} -- {{ attrs.msg2 }}---{{ count1 }}</p>
    <button @click="handleClick">点击子传父</button>
  </div>

</template>
<script lang="ts" setup>
// 引入组合式api
import { ref, defineOptions, defineProps,useAttrs,defineEmits } from 'vue'

// defineProps()相当于setup中第一个参数,用于接收父传子数据
// defineOptions()方法里面可以写vue2语法
// useAttrs相当于setup中第二个参数中的attres
// defineEmits相当于setup中第二个参数中的emit
defineOptions({
  data() {
    return {
      list: [11, 22, 3, 4, 5]
    }
  }
})
// 相当于props
let props=defineProps({
  msg1:{
    type:String
  },
  // 接收v-model
  count1:{
    type:String
  }
})
// 访问msg1
console.log(props.msg1,"asdfuohisudfghiusgfdiuasgdfiagsdf");

// 相当于attrs
const attrs = useAttrs()
console.log(attrs.msg2);

// 子传父开始
let str1=ref("我是大儿子")
let str2=ref("我是二儿子")
// 相当于emit defineEmits(['自定义语法名'])
const emit = defineEmits(["handleA","handleB"])
const handleClick = ()=>{
  // 自定义方法名,传递数据
  emit("handleA",str1.value)
  emit("handleB",str2.value)
}
// 子传父结束

</script>

<style lang="scss" scoped>
.son {
  padding: 20px;
  background: yellow;
}
</style>