资讯专栏INFORMATION COLUMN

高级 Vue 组件模式 (5)

woshicixide / 1340人阅读

摘要:你可以下面的链接来看看这个组件的实现代码以及演示在线演示总结当期望获得子元素或者子组件的引用时,切记使用和来解决问题。

05 使用 $refs 访问子组件引用 目标

在之前的文章中,详细阐述了子组件获取父组件所提供属性及方法的一些解决方案,如果我们想在父组件之中访问子组件的一些方法和属性怎么办呢?设想以下一个场景:

当前的 custom-button 组件中,有一个 input 元素

我们期望当 toggle 的开关状态为时,显示 input 元素并自动获得焦点

这里要想完成目标,需要获取某个组件或者每个元素的引用,在不同的 mvvm 框架中,都提供了相关特性来完成这一点:

angularjs: 可以使用依赖注入的 $element 服务

Angular: 可以使用 ViewChild、ContentChild 或者 template ref 来获取引用

react: 使用 ref 属性声明获取引用的逻辑

在 vue 中,获取引用的方法与 react 类似,通过声明 ref 属性来完成。

实现

首先,在 custom-button 组件中增加一个 input 元素,如下:

注意这里的 ref="input",这样在组件内部,可以通过 this.$refs.input 获得该元素的引用,为了实现目标中提及的需求,再添加一个新的方法 focus 来使 input 元素获取焦点,如下:

focus() {
  this.$nextTick(function() {
    this.$refs.input.focus();
  });
},

注意这里的 this.$nextTick,正常情况下,直接调用 input 的 focus 方法是没有问题的,然而却不行。因为 input 的渲染逻辑取决于 prop 属性 on 的状态,如果直接调用 focus 方法,这时 input 元素的渲染工作很可能还未结束,这时 this.$refs.input 所指向的引用值为 undefined,继续调用方法则会抛出异常,因此我们利用 this.$nextTick 方法,将调用的逻辑延迟至下次 DOM 更新循环之后执行。

同理,在 app 组件中,为 custom-button 添加一个 ref 属性,如下:

之后修改 onToggle 方法中的逻辑以满足目标中的需求,当 toggle 组件状态为开时,调用 custom-button 组件的 focus 方法,如下:

onToggle(on) {
  if (on) this.$refs.customButton.focus();
  console.log("toggle", on);
}
成果

点击按钮会发现,每当开关为开时,input 元素都会显示,并会自动获得焦点。

你可以下面的链接来看看这个组件的实现代码以及演示:

sandbox: 在线演示

github: part-5

总结

当期望获得子元素或者子组件的引用时,切记使用 ref 和 $refs 来解决问题。文章中所举例子的交互,在实际场景中很常见,比如:

当通过一个 icon 触发搜索框时,期望自动获得焦点

当表单校验失败时,期望自动获得发生错误的表单项的焦点

当复杂列表的筛选器展开时,期望第一个筛选单元获得焦点

这几种情况下,都可以使用该模式来高效地解决问题,而不是通过使用 DOM 中的 api 或者引入 jquery 获取相关元素再进行操作。

目录

github gist

欢迎关注公众号 全栈101,只谈技术,不谈人生

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98536.html

相关文章

  • 高级 Vue 组件模式 (1)

    摘要:写在前头去年,曾经阅读过一系列关于高级组件模式的文章,今年上半年,又抽空陆陆续续地翻译了一系列关于高级组件模式的文章,碰巧最近接手了一个公司项目,前端这块的技术栈是。同时这个组件还拥有一个属性,用来初始化的状态值。 写在前头 去年,曾经阅读过一系列关于高级 react 组件模式的文章,今年上半年,又抽空陆陆续续地翻译了一系列关于高级 angular 组件模式的文章,碰巧最近接手了一个公...

    lanffy 评论0 收藏0
  • 高级 Vue 组件模式 (6)

    摘要:之后再引入该指令,如下之后就可以在组件的模板中使用该指令了,比如一切都将按预期中运行,当组件的状态为开时,组件的根元素会增加一个的内容增强属性。到后来兴起了组件化开发的开发思想,指令似乎是随着的没落而消失了踪影。 06 通过 directive 增强组件内容 目标 之前的五篇文章中,switch 组件一直是被视为内部组件存在的,细心的读者应该会发现,这个组件除了帮我们提供开关的交互以外...

    makeFoxPlay 评论0 收藏0
  • 高级 Vue 组件模式 (3)

    摘要:在中,我们是否也有一些手段或特性来提高组件的复用程度和灵活性呢答案当然是有的,那就是。成果通过实现,我们成功将注入的逻辑抽离了出来,这样每次需要共享组件的状态和方法时,混入该即可。 03 使用 mixin 来增强 Vue 组件 目标 之前一篇文章中,我们虽然将 toggle 组件划分为了 toggle-button、toggle-on 和 toggle-off 三个子组件,且一切运行良...

    iKcamp 评论0 收藏0
  • 高级 Vue 组件模式 (2)

    摘要:编写复合组件目标我们需要实现的需求是能够使使用者通过组件动态地改变包含在它内部的内容。成果通过复合组件的方式,我们将组件划分为了三个更小的职责更加单一的子组件。 02 编写复合组件 目标 我们需要实现的需求是能够使使用者通过 组件动态地改变包含在它内部的内容。 熟悉 vue 的童鞋可能马上会想到不同的解决方案,比如使用 slot 并配合 v-if,我们这里采用另外一种方法,利用 vu...

    Galence 评论0 收藏0
  • 高级 Vue 组件模式 (9)

    摘要:在中,这种类型的组件也可以叫做函数式组件。这种组件和普通组件相比的优势主要在于,它是无状态的,这意味着它的可测试性和可读性更好,同时一些情况下,渲染开销也更小。 09 使用 Functional 组件 目标 到此为止,我们的 toggle 组件已经足够强大以及好用了,因此这篇文章不会再为它增加新的特性。如果你是从第一篇文章一直读到这里的读者,你一定会发现,整篇文章中,我几乎没有对 to...

    李义 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<