【Vue3】组件元素定义的ref属性和expose,setup返回值的关系

news/2024/9/28 10:13:12 标签: vue.js, javascript, 前端

1、实例代码

   首先一个测试结果:

    1、在组件模版中元素定义的ref属性,会在编译阶段生成对应的props数据,作为参数传入到创建这个ref所在元素的vnode的方法中。

2、如果ref定义在一般的元素中,那么ref就指向这个元素的dom实例,如果ref定义在子组件上,那么ref就指向这个子组件实例的一个代理属性proxy上(前提是子组件没有通过expose方法指定暴露的信息,如果指定了,就只能有些暴露的属性,其他数据没有)

3、如果在setup函数返回值中有key和这个ref的名称一样的话,那么ref引用的数据就会覆盖setup返回值原来的key对应的值。

4、ref引用的值不管怎么样都会暴露到父组件(如果子组件定义了 ref)的instance.refs属性中。可以在组件定义的methods方法中通过this.$refs获取到。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
      <style>
         .red{color:red}
      </style>
      <!--
         <script src="https://unpkg.com/vue@3.4.30/dist/vue.global.js"></script>
      -->
   <script src="./vue/vuetest.global.js"></script>
  </head>
  <body>
      <div id="app">
          
      </div>
  </body>   
   
  <script  type="module"> 
   
    const app = Vue.createApp({
         name:"root-component",
         props: {///这个定义 会赋值给组件实例instance中的propsOptions(属性的定义,数据类型,是否必填等)
            rootprops1: String,
         },
         renderTracked:function(e){
            console.log("------------renderTracked,参数e: "+e);
         },
         data:function(){
            return {
                  msg:'hello vue3'
                   }
         },
         methods: {
            dealChange:function(str){
               alert("子组件发射了chanage事件: "+str);
            },
            dealPutinfo:function(str){
               alert("子组件发射了putinfo事件: "+str);
            },
            divtestdata1:function(str){
               console.log(this.$refs.mydiv);
               console.log(this.$refs.tcinstance);
               console.log("--------------------");
               console.log(this.mydiv);
               console.log(this.tcinstance);
            }
         },
         mounted:function(){
            console.log("mount--------------",this.$refs.mydiv,this.$refs.tcinstance);
         },
         beforeCreate:function(){console.log("root-beforeCreate");},
         setup:function(props,ctx){
            ///执行setup函数时, 组件已经实例化了
             // context中有 props, attrs, slots, emit 和 expose
            通过这种方式注册的钩子函数获取不到this,为什么? vue内部创建注册这个钩子函数的时候没后指定bind()
            //通过在组件定义对象定义mounted钩子函数可以获取到this,
            Vue.onMounted((args) => {
               console.log("onMounted--------------");
            });
            //这个mydiv名称要和下面元素中定义的ref的名称一致,然后在setRef函数中就会根据这个名称 把ref值绑定到mydiv中
            //名称不一致的话,那么在setupState中就获取不到mydiv关联的dom或者实例代理对象了
            //tcinstance 也是和mydiv一样
            return {"mydiv":"","tcinstance":"",setupData:{data1:"data1",data2:"data2"}};
         },
         ///用到了template 需要引入的vue中有 编译模块, 或者在构建阶段完成编译
         //这些信息具体是在哪里解析的呢: 在执行父组件的render函数
         template:`<div >
                     <div ref="mydiv" id="root-chidren-div-id" style="color: blue;">----</div>
                     <button @click="divtestdata1" >按钮</button>
                     <test-component ref="tcinstance" v-on:chanage='dealChange' @putinfo="dealPutinfo" >
                        <template v-slot:other="slotProps"><div>我是父组件的other插槽内容测试锻炼{{msg}}--{{slotProps.url}}</div></template>
                     </test-component>
                   </div>`,
      },{rootprops1:"rootmsg1",rootprops2:"rootmsg2"});
      //
      var testComponet={
         name:"test-component",
         props: {
            testpmsg1: String,
            onPutinfo:Function
         },
         data:function(){
            return {
               cmsg:"shengbinqian",
               cdata:"zhongguoren",
               url:"http://www.baidu.com"
            }
         },
         methods: {
            testdata1:function(str){
               console.log("testdata-"+str);
               this.$emit("chanage","你好我是子组件信息chanage");
            },
            testdata2:function(str){
               this.$emit("putinfo","你好我是子组件信息putinfo");
            }
         },
         template:`<div class='border:solid 1px red'>
                     <div>我是子组件testComponent---{{cmsg}}</div> 
                     <div><slot name="other" :url="url"></slot></div>
                     <div><button @click="testdata1" >chanageEmit</button></div> 
                     <div><button @click="testdata2" >putinfoEmit</button></div> 
                  </div>`,
         setup:function(props,ctx){
            let data={tname:"qianqian"};
            //如果父组件的模版定义中,设置了子组件的ref属性,那么在父组件中就可以获取到这个子组件的实例代理对象
            //但是如果子组件要想暴露它想暴露的数据,那么就可以适用expose()方法,如果设置了这个方法,那么父组件就只能访问这些expose的数据
            //起到一个屏蔽的作用
            ctx.expose(data);
            console.log("testComponet-setup");
         }
      };
      ///会在app的上下文对象APPContext中的components中保存testComponet
      app.component("test-component",testComponet);
      app.mount('#app');
  </script>      
</html>

2、大概看下ref的实现原理

 

 

 


http://www.niftyadmin.cn/n/5680873.html

相关文章

DataLight(V1.4.5) 版本更新,新增 Ranger、Solr

DataLight&#xff08;V1.4.5&#xff09; 版本更新&#xff0c;新增 Ranger、Solr DataLight 迎来了重大的版本更新&#xff0c;现已发布 V1.4.5 版本。本次更新对平台进行了较多的功能拓展和优化&#xff0c;新增了对 Ranger 和 Solr 服务组件的支持&#xff0c;同时对多项已…

ResNet50V2:口腔癌分类

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 ResNet和ResNetV2对比 改进点&#xff1a;(a)original表示原始的ResNet的残差结构&#xff0c;(b)proposed表示新的ResNet的残差结构&#xff0c;主要差别就是(a)结构先卷积后进行BN和激活函数…

C语言自定义类型:结构体

目录 前言一、 结构体类型的声明1.1结构体的回顾1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的⾃引⽤ 二、 结构体内存对齐2.1 对齐规则2.2 为什么存在内存对⻬?2.3 修改默认对齐数 三、结构体传参四、结构体实现位段4.1 什么是位段4.2 位段的…

【frp】frp重启、frp启动、frp后台启动、frps dashboard等等

我写的关于frp配置的文章&#xff1a;frp配置 服务端frps 1. 创建服务文件 sudo nano /etc/systemd/system/frps.service2. 添加服务配置 在打开的文件中添加以下内容&#xff1a; [Unit] DescriptionFRPS Server Afternetwork.target[Service] Typesimple ExecStart/root…

开卷可扩展自动驾驶(OpenDriveLab)

一种通用的视觉点云预测预训练方法 开卷可扩展自动驾驶&#xff08;OpenDriveLab&#xff09; 自动驾驶新方向&#xff1f;ViDAR&#xff1a;开卷可扩展自动驾驶&#xff08;OpenDriveLab&#xff09;-CSDN博客 创新点 在这项工作中&#xff0c;本文探索了专为端到端视觉自动…

卷轴模式商城APP开发指南

卷轴模式商城APP的开发是一项融合了技术创新、用户体验优化与商业策略实施的综合性工程。本文将从程序员的角度出发&#xff0c;详细介绍该类型应用的开发流程&#xff0c;涵盖从需求分析到后期维护的各个环节。 一、需求分析 首先&#xff0c;明确APP的核心功能需求&#xff…

深圳·2025胶粘剂展会 BOND第六届胶展

BOND第六届胶展、2025大湾区国际胶粘剂及密封剂展览会 时间&#xff1a;2025年6月25-27日 地址&#xff1a;深圳国际会展中心&#xff08;新馆&#xff09; UV胶、快干胶、结构粘结胶、导热胶、低温黑胶、硅胶、SMT贴片红胶、底部填充胶、低温热固胶、COB黑胶、围堰填充胶、U…

认知杂谈91《菜鸟的自我修炼:减少过度干预》

内容摘要&#xff1a;          在投资和生活中&#xff0c;动作过多往往因情绪波动和缺乏计划而引发亏损。历史上的安史之乱和现代投资中的频繁交易都是例证。要管理情绪&#xff0c;首先要认识自己的情绪模式&#xff0c;然后改变消极的思考方式&#xff0c;并通过合…