Bootstrap

vue3传值的实现

父传子:

通过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>
;