vue组件传值之$attrs

1.概述:$attrs用于实现当前组件的父组件,向当前组件的子组件通信(祖-》孙)

2.具体说明:$attrs是一个对象,包含所有父组件传入的标签属性。

注意:$attrs会自动排除props中声明的属性(可以认为声明过的props被子组件自己消费了)

首先,创建父-子-孙之间的组件关系

我们首先来看父子之间的传值:

我们都知道,父传子传值的口诀是:父在子的属性上书写属性名=属性值,子组件使用defineProps接收。

那么我们的父组件的代码如下:【组件关系:爷爷:index.vue,子:brother.vue,孙:grandSon.vue】

index.vue

html 复制代码
<template>  
    <div>  
      <el-card ref="myButton"  @click="handlerClick">Click Me
        <el-card @click="clickSpan">点我</el-card>
        <Children ref="childRef" :fatherToSon="handlerClick"></Children>
        <!-- @myHandler="handlerClick" -->
         <Brother v-model:aaa="name" age="20" :happy="happy" :happyPlus="happyPLus" test="测试数据" v-bind="{x:100,y:200}" />
         <!-- <el-tag type="danger" size="normal"  effect="dark" closable @close="">{{ name }}</el-tag -->
         <el-badge :value="name" :max="99" :is-dot="false" :hidden="false" type="primary">
          
          <el-button size="small">cet</el-button>
         </el-badge>
         <br />
         
         
         爷爷的:{{ happy }}
      </el-card>  
    </div>  
  </template>  
    
  <script lang="ts" setup>  
  import { ref, onMounted, nextTick } from 'vue';  
  import { ElButton } from 'element-plus'; // 确保你已经正确引入了 Element Plus  
  import Children from './child.vue'  
  import Brother from './brother.vue'
  const childRef = ref(null);  
  const name = ref('tomCat')
let happy=ref('哈哈')
const happyPLus=()=>{
    happy.value+='!'
}
      const myButton = ref(null);  
      
      const handlerClick=(value:any)=>{
        console.log("父组件被点击了,子组件传递过来的值为",value);
        console.log(childRef.value);
        console.log(childRef.value?.SonFun());
        console.log(childRef.value?.sonValue);
        
        
        
        
      }
      const clickSpan=()=>{
        console.log("span被点击了");
      }
      // onMounted(() => {  
      //   // 访问 el-button 组件实例  
      //   console.log(myButton.value);  
      //   console.log(24,myButton.value.handleClick);
      //   console.log(25,ref);
        
      //   // 打印所有属性和方法(注意:直接操作实例的属性和方法可能不是最佳实践)  
      //   console.log('Properties:', Object.keys(myButton.value.$props));  
      //   console.log('Methods:', Object.keys(myButton.value.$options.methods));  
      // });  
    
      // 返回 ref 以便在模板中使用  
      
    
   
  </script>

可以看到父给子传递的数据,有静态的,也有动态的,也有使用v-bind=对象的这种方式来传递的,其实这种方式就是等价于:

javascript 复制代码
v-bind="{x:100,y:200}"   ==》 :x=100 :y=200

这样我们就可以看到对应的x和y也被传递过来了,然后我们的关注重点是祖孙传值,而不是父子传值,所以这个brother组件就是一个桥梁,其作用就是不使用父组件的值,直接将父组件传递的值使用$attrs直接传递给孙组件。

brother.vue

html 复制代码
<template>
 <div>
  自定义组件实现v-model
    <!-- <input type="text" :value="aaa" @input="inputChange"/>
    <h3>age:{{ age }}</h3>
    <h3>其他:{{ $attrs }}</h3> -->
    <GrandSon v-bind="$attrs"></GrandSon>
 </div>
</template>

<script setup lang="ts">
import {ref,reactive} from 'vue'
import GrandSon from './grandSon.vue';
// const emit =defineEmits(['update:aaa'])

// defineProps(['aaa','age'])

// const inputChange=({target:{value}})=>{
//     emit('update:aaa',value)

// }
</script>

<style scoped>

</style>

这里我们需要注意的时,当父组件传递给孙组件的值被子组件接收后,如果子组件没有传递出去,那么孙组件就无法使用被子组件占用的值。

孙组件grandSon.vue

html 复制代码
<template>
 <div>
  this is grandson page
<h2>test:{{ test }}</h2>
<h2>age:{{ age }}</h2>
<h2>x:{{ x }}</h2>
<h2>y:{{ y }}</h2>
<h2>孙子的happy:{{ happy }}</h2>

<el-button type="primary" size="default" @click="happyPlus">修改爷爷的happy</el-button>

 </div>
</template>

<script setup lang="ts">
import {ref,reactive} from 'vue'
defineProps(['test','age','x','y','happy','happyPlus'])


</script>

<style scoped>

</style>

来到调试工具,我们就可以看到孙组件接受到了来自爷爷传递过来的值。

然后我们可能会有疑问,既然爷爷可以向孙组件传递数据,那么孙可不可以修改爷爷的数据呢,其实,原理和当时的props是一样的,这种方式虽然不能直接修改爷爷的值,但是可以让爷爷再传递一个方法给孙组件,然后孙组件调用这个方法,完成对爷爷的修改。比如传递过来的函数happyPLus

来到界面,我们点击按钮,就可以修改爷爷的数据

有几个比较细致的点,需要注意一下,就是当父组件给子组件传递数据的时候,子组件可以不全部接受父组件传递过来的数据,

可以看到,接受到的数据被放在props中,没接受的数据放到了attrs之中,同样,刚才已经提到过,如果子组件接收了父组件的数据,那么在孙组件就会看不到数据,正是这个原因

相关推荐
桂月二二4 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
CodeClimb5 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
沈梦研5 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb5 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角5 小时前
CSS 颜色
前端·css
轻口味6 小时前
Vue.js 组件之间的通信模式
vue.js
九酒6 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔7 小时前
HTML5 新表单属性详解
前端·html·html5
lee5767 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm