首页 > 其他分享 >vue3 父子组件间的数据传递

vue3 父子组件间的数据传递

时间:2024-01-25 14:22:06浏览次数:27  
标签:vue const value 父子 msg vue3 组件 ref

一、简介

二、实际代码

三、问题

 

一、简介

  vue 父子组件的传递原则是单向的, 子组件是无法修改父组件的参数, 但是可以通过另一种渠道可以实现通信。            

二、实际代码

  1 父传子

  1.1 props 

  父组件内容

<template>
    <div>这里是父组件</div>
    <input type="text" v-model="inputMsg"/>
    
    <div>
        inputMsg:{{inputMsg}}
    </div>
    <div>
        msg:{{msg}}
    </div>
    
    <div>
        <button @click="changeMsg">点击修改</button>
    </div>
    <div style="margin: 10px;">分割线-------------------------</div>

<childView
    :toMsg="msg"
    :toFunc="func"
></childView>

</template>

<script setup>
import { reactive, ref } from 'vue';
import  childView  from './edit.vue'

const inputMsg = ref('这里是父组件的消息')
const msg = ref('')

const func = () =>{
    changeMsg()
}

const changeMsg = () => {
    msg.value = inputMsg.value
}

</script>

    这里父组件传入msg  和一个方法

   子组件内容

<template>
    <div>
        <div>这里是子组件</div>
        <div>收到父组件消息toMsg:{{toMsg}}</div>
    </div>
    <div>
        <button @click="toFunc">点击执行收到的父组件方法</button>
    </div>
    <div>
        <button @click="changeMsg">点击修改toMsg</button>
    </div>
    
</template>

<script setup>
    // 需要定义defineProps
const props = defineProps({
    toMsg: {
        type: String,
        default: 100,
    },
    toFunc: {
        type: Function,
        default: async () => {},
    }
})

const changeMsg = () => {
    props.toMsg = "子组件修改"
}
</script>

<style>
</style>

    这样了就得到了这样一个界面

   点击父组件的修改,就会修改msg 参数的值,并且会实时渲染到子组件

    点击子组件里的 执行收到的父组件方法也可以达到同样的效果, 但是点击 子组件里的修改toMsg 就会报错

    这就是vue的特性,父组件能修改值,但是子组件不能修改父组件的子,只能通过调用父组件的方法修改值。

    顺带提一句,可以直接使用 inputMsg 传入子组件的toMsg,可以立即渲染。

<childView
    :toMsg="inputMsg"
    :toFunc="func"
></childView>

  按照上面的逻辑,是不是可以回调方法传参呢,我将父组件稍微调整了下

<template>
    <div>这里是父组件</div>
    <input type="text" v-model="inputMsg"/>
    
    <div>
        inputMsg:{{inputMsg}}
    </div>
    <div>
        msg:{{msg}}
    </div>
    
    <div>
        <button @click="tapChangeMsg">点击修改</button>
    </div>
    <div style="margin: 10px;">分割线-------------------------</div>

<childView
    :toMsg="msg"
    :toFunc="func"
></childView>

</template>

<script setup>
import { reactive, ref } from 'vue';
import  childView  from './edit.vue'

const inputMsg = ref('这里是父组件的消息')
const msg = ref('')

// 增加参数 const func = (val) =>{ changeMsg(val) } const tapChangeMsg = () =>{ changeMsg() } const changeMsg = (val) => { if (!!val){ msg.value = val }else{ msg.value = inputMsg.value } } </script>

  子组件传参

<template>
    <div>
        <div>这里是子组件</div>
        <div>收到父组件消息toMsg:{{toMsg}}</div>
    </div>
    <div>
        <button @click="toFunc('1')">点击执行收到的父组件方法</button>
    </div>
    <div>
        <button @click="changeMsg">点击修改toMsg</button>
    </div>
    
</template>

  实验结果,是可行的

 

  2 子传父

    除了上面的回调传参,还有一种其他方式,

    emit: 组件封装了一系列 emit 事件,并返回数据、回调函数等,或单纯执行某个操作后,触发父组件的事件响应。 外部要用时,使用 @xxxx 来接收使用、响应。

  2.1 实际内容

  父组件

<template>
    <div>这里是父组件</div>

    <div>
        msg:{{msg}}
    </div>

    <div style="margin: 10px;">分割线-------------------------</div>

<childView
    @backTo="func"
></childView>

</template>

<script setup>
import { ref } from 'vue';
import  childView  from './edit.vue'

const msg = ref('')
const func = (val) =>{
    msg.value = val
}

</script>

   子组件

<template>

    <div>
        <button @click="changeMsg">点击修改父组件</button>
    </div>
    
</template>

<script setup>
    // 需要定义defineProps
const emit = defineEmits(["backTo"])

const changeMsg = () => {
    emit("backTo", "子组件修改") 
}
</script>

  执行效果

    这里就是使用 defineEmits 自定义了一个事件列表,使用@的方式。

 

  3 父子组件双向绑定

    这个的实现,需要使用到computed, 对于这个网上没有看到一个通俗详细的说法,只知道性能比调用方法好,会缓存。

    可以参考这里去看看

  3.1  实际代码

  父组件

<template>
    <div>这里是父组件</div>
    <div>
        msg:{{msg}}
    </div>
    <button @click="change">父组件改</button>
    <div style="margin: 10px;">分割线-------------------------</div>

<childView
   v-model:msg="msg"
></childView>

</template>

<script setup>
import { reactive, ref } from 'vue';
import  childView  from './edit.vue'


const msg = ref('')

const change = () => {
    msg.value = "从父组件改"
}

</script>

  子组件

<template>

    <div>
        {{value}}
    </div>
    <button @click="change">改变值</button>
</template>

<script setup>
    // 需要定义defineProps

// 接受父组件传递过来的参数msg
const props = defineProps(['msg'])
// 定义子传父事件, update可默认执行父组件数据更新,父组件不需要调用此方法
const emit = defineEmits(['update:msg'])
// 计算属性接受父组件传递过来的msg, 设置get、set方法实现数据双向绑定
const value = computed({
    get: () => props.msg,
    set: (val) => emit('update:msg', val)
})

const change = () => {
    value.value = "从子组件改"
}
</script>

<style>
</style>

  这样相当于,父组件msg 变化会影响到 子组件value, 而子组件value变换会通过 emit 修改父组件的值。

  注意:不管使用props 或者emits 在vue3 里面都需要使用 defineProps 和 defineEmits 声明。

  4 注入传值。

  vue3 还有一种传值方式 provide 和 inject

  按照上面父子组件传值只能传一层,也就是当父子组件大于2以上层数时, 最上面一层往底层传参,按传统得一层一层传,使用这个,就可以直接传下去。

  详细可参考这

  4.1 实际代码

  父组件

<template>
    <div>这里是父组件</div>
    <div>
        msg:{{msg}}
    </div>
    <button @click="change">父组件改</button>
    <div style="margin: 10px;">分割线-------------------------</div>

<childView
></childView>

</template>

<script setup>
import { reactive, ref } from 'vue';
import  childView  from './edit.vue'

const msg = ref('')

const change = () => {
    msg.value = "从父组件改"
}

provide('proMsg',msg)

</script>

  子组件

<template>

    <div>
        {{ofMsg}}
    </div>
    <button @click="change">改变值</button>
</template>

<script setup>

const change = () => {
    ofMsg.value = "从子组件改"
}

const ofMsg = inject('proMsg',ref('none'))

</script>

<style>
</style>

  实测,数据可以双向绑定,子组件修改,父组件可以改变,子组件修改,父组件会更改。

  上面代码操作跟3.1的操作结果一致。

三、问题

标签:vue,const,value,父子,msg,vue3,组件,ref
From: https://www.cnblogs.com/nobody-/p/17987062

相关文章

  • prometheus组件
    prometheusserverPrometheusServer是Prometheus组件中的核心部分,负责实现对监控数据的获取,存储以及查询。PrometheusServer可以通过静态配置管理监控目标,也可以配合使用ServiceDiscovery的方式动态管理监控目标,并从这些监控目标中获取数据。其次PrometheusServer需要对采......
  • [Vue]Vue3学习笔记1
    官网文档: https://cn.vuejs.org/guide/essentials/template-syntax.html 每个组件都是由createApp创建import{createApp}from'vue'constapp=createApp({/*根组件选项*/}) Vue3.4+支持v-bind同名简写如果属性名称与要绑定的JavaScript值相同,语法可以......
  • 界面组件DevExpress .NET MAUI中文教程 - 如何优化手机屏幕空间?
    DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。获取DevExpressv23.2正式版下载DevExpress技术交流群9:909157416      欢迎一起进群讨论BottomSheet......
  • vue3中使用animate.css+wow.js
    官网链接:animatewow.js版本声明:"dependencies":{"vue":"^3.3.11","animate.css":"^4.1.1","wow.js":"^1.2.2"},1.安装:npminstallanimate.css--savenpminstallwow.js......
  • js/ts中Date类的ref响应式 -- VUE3
    现象:Date对象无法响应式原因:Date是个深层对象,外面那层可以响应,但是更改里面的层,则不会被侦测到改动解决:强制触发副作用即可参考文档:https://cn.vuejs.org/api/reactivity-advanced.html#triggerref<template><divclass="cnblogs_yucloud">{{DateTime}}</div>......
  • 拆分面板组件备忘留存
    最近项目中需要用到左右布局,但可以动态拖动两边布局的宽度,遂研究了下面板拆分组件vue项目可用vue-splitpanehttps://www.npmjs.com/package/vue-splitpanenpminstallvue-splitpaneimportsplitPanefrom'vue-splitpane'Vue.component('split-pane',splitPane);<split-......
  • k8s~istio的安装与核心组件
    安装istio在线安装:https://istio.io/latest/docs/setup/getting-started/#download或者直接在这里下载:https://github.com/istio/istio/releases/tag/1.20.2$curl-Lhttps://istio.io/downloadIstio|ISTIO_VERSION=1.20.2TARGET_ARCH=x86_64sh-$cdistio-1.20.2$e......
  • vue3 axios 封装
    一、介绍二、代码三、问题 一、介绍Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。这里介绍的是在vue3中怎么封装二、代码1.基本使用1.1安装npminstallaxios1.2简单使用1.2.1局部使用importaxiosfrom'axio......
  • UniApp Vue3 动态表单
    左侧手机部分为动态表单内容,右侧为提交后获取到表单的值。页面代码:<viewstyle="margin:15px;padding:10rpx;"><tn-formlabel-position="top"ref="formRef":model="formData":rules="formRules"><tn-for......
  • 通过CanvasRenderer.SetColor和Image.color修改UI组件颜色的区别
    1)通过CanvasRenderer.SetColor和Image.color修改UI组件颜色的区别2)OPPO相关机型没法在Unity启用90或120FPS3)手机输入法中的emoji4)UnityApplicationPatching怎么用这是第369篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面......