父传子:
通过setup语法糖的形式传值
新建子组件list,通过defineProps传值 List.vue
<script setup>
defineProps({
msg:{
type:String,
default:"11111"
}
})
</script>
<template>
这是子组件==>{{msg}}
</template>
在父组件中传值 Home.vue
<script setup>
import { ref } from 'vue';
import List from '../components/List.vue'
const msg = ref('这是父传递过去的数据')
</script>
<template>
<list :msg="msg"></list>
</template>
如果父组件不传递msg则子组件中显示默认值11111
另一种方式:
https://www.javascriptc.com/vue3js/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0 因为setup接受2个参数,分别是props和context,如果传递多个值,可以在子组件中通过toRefs解构
<script>
export default{
props:['msg'],
setup(props){
let obj = props.msg
return {obj}
}
}
</script>
<template>
这是子组件==>{{obj}}
</template>
以上写法便于进行计算,加工传过来的数据
子传父
context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构。
在子组件中通过emit给父组件传值
普通模式
List.vue
<script>
import {ref} from 'vue'
export default{
setup(props,{emit}){
let num = ref(100);
const changeNum = ()=>{
emit('fn',num)
}
return {num,changeNum}
}
}
</script>
<template>
这是子组件{{num}}
<button @click="changeNum">点击</button>
</template>
父组件中通过引入子组件,接收 Home.vue
<script>
import List from '../components/List.vue'
export default{
components:{
List
},
setup(){
let changeHome=(n)=>{
console.log(n.value)
}
return {changeHome}
}
}
</script>
<template>
<List @fn="changeHome"></List>
</template>
语法糖形式
使用defineProps等 https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits
子传父,通过在子组件中用defineEmits定义一个父组件要监听的动作,在父组件中通过@(子组件中定义的监听动作名)
来触发
子组件 List.vue:
<script setup>
import {ref} from "vue"
let num = ref(200)
const emits = defineEmits(['increase','emit1','emit2'])
// 声明监听的动作,可声明多个
const changeNum = ()=>{
emits('increase',{params1:num,params2:'2'})
// 定义方法触发的监听,第二个参数为传值,此为触发上面定义的第1个
}
</script>
<template>
这是子组件{{num}}
<button @click="changeNum">点击</button>
</template>
父组件 home.vue:
<script setup>
import List from '../components/List.vue'
const consoleNum = (n)=>{
console.log("子传父",n.params2)
}
</script>
<template>
<List @increase="consoleNum"></List>
</template>
双向绑定
通常,子组件拿到父组件的数据后,不能修改。可以通过v-model实现
在父组件中定义 home.vue
<script setup>
import {ref} from "vue"
import List from '../components/List.vue'
let num = ref(1)
</script>
<template>
<List v-model:num='num'></List>
</template>
在子组件中通过defineEmits修改
<script setup>
import {ref} from "vue"
const props = defineProps({
num:{
type:Number,
default:1111
}
})
const emit = defineEmits(['update:num'])
const btn = ()=>{
emit('update:num',200)
// 第二个参数,要修改的值
}
console.log(props.num)
</script>
<template>
这是子组件{{num}}
<button @click="btn">点击修改</button>
</template>
兄弟组件传值
繁琐的实现
兄弟组件A.vue和B.vue可以通过共同的父组件Home.vue传值,就是把父组件当做桥梁
A.vue
<script setup>
import {ref} from 'vue'
let str = ref('这是A组件的数据')
const emit = defineEmits(['aToB'])
const btn = ()=>{emit('aToB',str)}
</script>
<template>
<h1>A组件</h1>
<button @click="btn">传送到B</button>
</template>
B.vue
<script setup>
const props = defineProps({
str:{
type:String,
default:"B中str的默认值"
}
})
</script>
<template>
<h1>B组件</h1>
B中的值{{str}}
</template>
Home.vue
<script setup>
import {ref} from "vue"
import A from '../components/A.vue'
import B from '../components/B.vue'
const str = ref('') // 用于接收到A传过来的值后给B赋值
const changeToB = (n)=> {
str.value = n.value
console.log(n.value)
}
</script>
<template>
<A @a-to-b="changeToB"></A>
<B :str="str"></B>
</template>
通过mitt库传值
Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中事件总线模式已经被移除,官方建议使用外部的、实现了事件触发器接口的库,例如 mitt 或 tiny-emitter。npm install --save mitt
在src目录下新建plugins/Bus.js
import mitt from 'mitt'
const emitter = mitt()
export default emitter
// 导出的只有1个,所以导入的时候不用{}
在Home.vue中引入A、B组件
<script setup>
import A from '../components/A.vue'
import B from '../components/B.vue'
</script>
<template>
<A></A>
<B></B>
</template>
A组件中通过 emitter.emit('aToB',str)
<script setup>
import {ref} from 'vue'
import emitter from '../plugins/Bus'
let str = ref('这是A组件的数据')
const btn=()=>{
emitter.emit('aToB',str) //自定义事件名和要发送的数据
}
</script>
<template>
<h1>A组件</h1>
<button @click="btn">传送到B</button>
</template>
B组件中通过emitter.on('aToB',e=>{get_from_a.value = e.value})
<script setup>
import {onBeforeMount, ref} from 'vue'
import emitter from '../plugins/Bus'
let get_from_a = ref('') // 用于接收从A中传过来的值
onBeforeMount(()=>{ //在生命周期中接收
emitter.on('aToB',e=>{
get_from_a.value = e.value
console.log('从A组件传过来的数据',e.value)
})
}
)
</script>
<template>
<h1>B组件</h1>
B中的值{{get_from_a}}
</template>