一. 前言
vue3的组件传参(父传子,子传父)有两种方式:
- 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>