脚本专家 发表于 2026-6-11 19:00:00

Vue ref与$attrs实战:父子组件通信、v-model和.sync语法糖详解

在Vue开发中,ref和$attrs是处理组件引用与跨级属性传递的常用工具,而v-model和.sync则是简化父子通信的语法糖。本文结合具体代码,梳理它们的核心用法与常见场景。

## ref的三种用法
ref可以在三种场景下使用,分别获取不同对象:

1. 加在普通HTML元素上,通过this.$refs.name获取DOM节点。
2. 加在子组件上,获取的是组件实例,可以调用子组件的所有方法和属性。
3. 在v-for中配合ref使用,会返回一个数组,包含对应循环项的所有实例或DOM节点,不会因为重名而被覆盖。

注意:this.$refs对象中存储了所有设置了ref属性的元素,如果出现同名,后者会覆盖前者(v-for场景除外)。普通元素返回DOM对象,Vue组件返回组件实例。

示例(省略具体代码,读者可自行测试):

<div ref="myDiv">普通元素</div>
<child-component ref="myChild"></child-component>
<div v-for="item in list" :key="item.id" :ref="'item_' + item.id">...</div>

通过this.$refs.myDiv获取DOM,this.$refs.myChild获取组件实例,而v-for中建议使用函数式ref或利用数组索引。

## $attrs:跨级属性传递的桥梁
当父组件向子组件传递属性时,如果子组件的props中没有声明该属性,那么该属性会进入子组件的$attrs对象中。这使得我们可以方便地将未在props中定义的值继续向下传递,避免“逐层声明”的冗余。

例如,父组件传递了propA(已定义)、propB(未定义)和grand-id(未定义),子组件通过this.$attrs可以获取到{ propB, grandId }(grand-id自动转为驼峰grandId)。

若需要在子组件中继续向孙组件传递这些未声明的属性,可以使用v-bind="$attrs"。这等价于逐一绑定每个属性:

<grand-child v-bind="$attrs"></grand-child>

这样孙组件既可以通过props接收,也可以通过this.$attrs继续传递。

## 语法糖:v-model 和 .sync
在父子组件通信中,Vue提供了两个语法糖简化双向绑定。

### v-model
v-model本质上是:value和@input的组合。父组件写:

<child v-model="parentValue"></child>

子组件内部接收value为props,并在值变化时触发input事件:

export default {
props: ['value'],
data() {
    return {
      inputValue: this.value
    }
},
watch: {
    inputValue(newVal) {
      this.$emit('input', newVal)
    }
}
}

这样父组件的parentValue就会随子组件的inputValue变化而更新。

### .sync 修饰符
对于普通属性(非value),可以用.sync实现类似v-model的效果。父组件写法:

<child :changep.sync="object.p"></child>

子组件中通过$emit('update:changep', newValue)来触发更新:

methods: {
clickHandle() {
    this.$emit('update:changep', '改变了对应的p')
}
}

这等价于父组件监听@update:changep事件并更新对应的属性值。

## 总结
ref提供了对DOM或组件实例的直接访问,适合操作焦点、集成第三方库等场景;$attrs简化了跨级属性传递,尤其适用于高阶组件或封装库;v-model和.sync则让双向绑定更简洁。掌握这些技巧,可以编写更清晰、可维护的Vue组件。

热心网友7 发表于 2026-6-11 19:05:00

Re: Vue ref与$attrs实战:父子组件通信、v-model和.sync语法糖详解

感谢楼主的详细总结,把ref、$attrs、v-model和.sync的用法讲得很清楚。之前我对v-for里ref返回数组的特性有点模糊,看了你的说明就理解了,尤其是在循环中避免同名的坑确实需要注意。另外$attrs配合inheritAttrs: false在封装高阶组件时特别有用,能控制哪些属性透传到根元素,这点如果楼主能顺便提一下就完美了,不过目前的内容已经很实用了。

热心网友5 发表于 2026-6-20 15:05:00

Re: Vue ref与$attrs实战:父子组件通信、v-model和.sync语法糖详解

感谢分享!写得非常清晰,对 `ref` 在 `v-for` 里的用法解释得很到位——用函数式 `ref` 确实能避免覆盖问题。平时用 `$attrs` 做组件库封装时确实省了很多透传的麻烦,就是得注意 `inheritAttrs: false` 配合样式类名的处理。想请教一下,在多个 `.sync` 修饰符同时使用时,子组件内部 `$emit` 多个 `update:` 事件,有没有什么推荐的命名规范或避免冲突的技巧?

热心网友7 发表于 2026-6-20 17:20:01

Re: Vue ref与$attrs实战:父子组件通信、v-model和.sync语法糖详解

写得非常清晰实用,ref的三种用法和$attrs的跨级传递一直是我开发中的痛点,看完以后豁然开朗。v-model和.sync的对比也很有用,特别是.sync对普通属性的双向绑定处理,之前总是容易和v-model搞混。有没有遇到过$attrs在透传时class或style被覆盖的坑?想听听你的经验。
页: [1]
查看完整版本: Vue ref与$attrs实战:父子组件通信、v-model和.sync语法糖详解