文章目录
前言
提示:vue组件传值学习用vue3语法
提示:以下是本篇文章正文内容,下面案例可供参考
一、父组件传值子组件接收
1.在父组件中引入子组件并通过
components
注册
父组件内容示例:
html 内容
<template><divclass="home">
父组件
<child:msg="msg"></child></div></template>
js 内容
import child from "../components/Child/Child";
<script>import{ defineComponent, ref, computed }from"vue";import child from"../components/Child/Child";import{ useRouter }from"vue-router";exportdefaultdefineComponent({name:"About",components:{
child,},setup(props, ctx){let msg =ref("这是父组件的值");letsend=(value)=>{
console.log(value);};return{
msg,
send,};},});</script>
子组件内容示例
html 内容
<template><divclass="">
这是子组件 父组件传地的值 {{ msg }}
</div></template>
js 内容
props: { msg: { type: String, default: "", }, },;
<script>import{ defineComponent, ref, computed, onMounted }from"vue";import{ useRouter }from"vue-router";exportdefaultdefineComponent({name:"child",props:{msg:{type: String,default:"",},},});</script>
二、子组件传值父组件接收
子组件内容示例
html 内容
<template><divclass=""><button@click="send">子组件传给父组件</button></div></template>
js 内容
setup(props, ctx)
ctx.emit("send", [childMsg.value, childNum.value]);
<script>import{ defineComponent, ref, computed, onMounted }from"vue";import{ useRouter }from"vue-router";exportdefaultdefineComponent({name:"child",props:{msg:{type: String,default:"",},},setup(props, ctx){
console.log(props.msg);let childMsg =ref("这是子组件传递给父组件");let childNum =ref(10);// 子组件 传父组件letsend=()=>{// 通过 ctx.emit 分发事件// emit 第一个参数是事件名称 第二个参数是传递数据// 传参方式// 数组形式 对象像是
ctx.emit("send",[childMsg.value, childNum.value]);// ctx.emit("send",{// msg:childMsg.value,// num:childNum.value// })};onMounted(()=>{// ctx.emit("send",[childMsg.value,childNum.value])
ctx.emit("send",{msg: childMsg.value,num: childNum.value,});});return{
childMsg,
childNum,
send,};},});</script>
父组件内容示例:
html 内容
@send="send"
<template><divclass="home">
父组件
<child@send="send"></child></div></template>
js 内容
import child from "../components/Child/Child";
<script>import{ defineComponent, ref, computed }from"vue";import child from"../components/Child/Child";import{ useRouter }from"vue-router";exportdefaultdefineComponent({name:"About",components:{
child,},setup(props, ctx){letsend=(value)=>{
console.log(value);//子组件传的值};return{
send,};},});</script>
三、expose / ref
子组件可以通过 expose 暴露自身的方法和数据。
父组件通过 ref 获取到子组件并调用其方法或访问数据。
<!-- Parent.vue --><template><div>父组件:拿到子组件的message数据:{{ msg }}</div><button@click="childFun">调用子组件的方法</button><hr/><Childref="childRef"/></template>
<!-- Parent.vue --><script setup>import{ ref, onMounted }from"vue";import Child from"@/components/Child.vue";const childRef =ref(null);// 通过 模板ref 绑定子组件const msg =ref("");onMounted(()=>{// 在加载完成后,将子组件的 message 赋值给 msg
msg.value = childRef.value.message;});functionchildFun(){// 调用子组件的 changeMessage 方法
childRef.value.changeMessage("前端诡刺");// 重新将 子组件的message 赋值给 msg
msg.value = childRef.value.message;}</script>
<!-- Child.vue --><template><div>子组件:{{ message }}</div></template>
<!-- Parent.vue --><script setup>import{ ref }from"vue";const message =ref("前端菜鸟");functionchangeMessage(data){
message.value = data;}//使用 defineExpose 向外暴露指定的数据和方法defineExpose({
message,
changeMessage,});</script>
四、v-model
可以支持多个数据双向绑定
父组件
<!-- Parent.vue --><template><Childv-model:msg1="message1"v-model:msg2="message2"/></template>
<!-- Parent.vue --><script setup>import{ ref }from"vue";import Child from"@/components/Child.vue";const message1 =ref("前端菜鸟1");const message2 =ref("前端菜鸟2");</script>
子组件
<!-- Child.vue --><template><div><button@click="changeMsg1">修改msg1</button> {{ msg1 }}</div><div><button@click="changeMsg2">修改msg2</button> {{ msg2 }}</div></template>
<!-- Child.vue --><script setup>import{ ref }from"vue";// 接收const props =defineProps({msg1: String,msg2: String,});const emit =defineEmits(["update:msg1","update:msg2"]);functionchangeMsg1(){emit("update:msg1","前端诡刺1");}functionchangeMsg2(){emit("update:msg2","前端诡刺2");}</script>
五、provide / inject
遇到多层传值时,使用 props 和 emit 的方式会显得比较笨拙。
这时就可以用 provide 和 inject 了。
provide 是在父组件里使用的,可以往下传值。
inject 是在子(后代)组件里使用的,可以往上取值。
无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。
父组件
<!-- Parent.vue --><template><Child></Child></template>
<!-- Parent.vue --><script setup>import{ ref, provide, readonly }from"vue";import Child from"@/components/Child.vue";const msg1 =ref("");const msg2 =ref("前端菜鸟2");// 使用readonly后子组件直接修改会发出警告,需要调用provide往下传的方法来修改provide("msg1",readonly(msg1));provide("msg2", msg2);provide("changeName",(value)=>{
msg1.value = value;});</script>
子组件
<!-- Child.vue --><template><div><div>msg1: {{ msg1 }}</div><div>msg2: {{ msg2 }}</div><button@click="handleClick">修改</button></div></template>
<!-- Child.vue --><script setup>import{ inject }from"vue";const msg1 =inject("msg1","默认值");// 看看有没有值,没值的话就适用默认值。const msg2 =inject("msg2");const changeName =inject("changeName");functionhandleClick(){// 这样写不合适,因为vue里推荐使用单向数据流,当父级使用readonly后,子元素直接修改会发出警告。// msg1.value = '前端诡刺1'// 正确的方式changeName("前端诡刺1");// 因为 msg2 没被 readonly 过,所以可以直接修改值
msg2.value ="前端诡刺2";}</script>
六、mitt
Vue3 中没有了 EventBus 跨组件通信,但是现在有了一个替代的方案 mitt.js,原理还是 EventBus。
先安装 npm i mitt -S
然后像以前封装 bus 一样,封装一下。
//mitt.jsimport mitt from'mitt'const mitt =mitt()exportdefault mitt
// 组件 A<script setup>import mitt from'./mitt'consthandleClick=()=>{
mitt.emit('handleChange')}</script>// 组件 B<script setup>import mitt from'./mitt'import{ onUnmounted }from'vue'constsomeMethed=()=>{...}
mitt.on('handleChange',someMethed)onUnmounted(()=>{
mitt.off('handleChange',someMethed)})</script>
七、Vuex / pinia
pinia使用方法简易版
版权归原作者 零-Mr_J 所有, 如有侵权,请联系我们删除。