文章目录

  • 背景
  • v-for 循环创建子组件
  • 组件封装
  • 启示录

背景

前端开发过程中,需要动态添加操作面板,而操作面板可以封装成独立的组件,被父组件引用。比如这个添加收货信息的场景,父组件中可以添加多个收货地址:

vue 循环出来的模板字符串标签如何使用索引 vue组件循环引用_双向通信


要实现在父组件中动态添加组件的功能有哪些技术点呢?本文来讨论一下这个简单场景里面的技术要点。

v-for 循环创建子组件

显然,父组件应该使用 v-for 来创建多个子组件,这里父子组件需要进行双向通信,表现为:

  1. 编辑操作,父组件回显信息时,需要传递给子组件收货信息;
  2. 父组件的保存操作,需要收集子组件的数据。

所以呢,要用两种组件通信方式 props$refs。父组件传递给子组件的 props 数据,虽然只能由父组件修改,但是它也是子组件的数据,子组件可以读取、但不能修改;同时,子组件又需要维护自己的数据,便于子组件编辑。

为了达到双向通信的目的,可以采取的操作如下:

  1. 子组件维护自己的数据,但数据的初始化是利用 props 完成的;
  2. 父组件使用 v-for 创建子组件时,为每个组件设置 ref 属性,通过 $refs 获取每个子组件的数据。

这里有个知识点,值得关注,父组件的 v-for 语句中怎么动态设置子组件的 ref 属性呢?

找到的解决方案是使用字符串的占位符号拼接上 index 来设置,例如,创建 N 个 el-button 子组件,且为每个组件设置各自的 ref 名称,代码如下:

<el-button 
        :key="index" 
        :ref="`btn${index}`"
         v-for="(btn,index) in btns">
          {{ btn.name}}
    </el-button>

v-for 循环创建子组件常见的一个警告是Component lists rendered with v-for should have explicit keys.,所以需要绑定这个属性 :key="index"

组件封装

封装原型图中的 Child 标记的组件,命名为 AddressPanel,组件参数有:

参数

说明

address

属性:地址

postCode

属性:邮编

telephone

属性:电话

panelIndex

属性:当前面板的编号,remove 事件时需要

@addPanel

事件:添加一个面板,父组件的 panels 添加一个新记录

@removePanel

事件:删除一个面板,移除父组件的 panels[panelIndex] 处的记录

AddressPanel 组件定义的伪代码:

props: ['address', 'postCode', 'telephone', 'panelIndex'],
data(){
   return {
        data:{ //保证能修改数据,使用 props 属性来初始化数据
            address:address,
            postCode:postCode,
            telephone:telephone
        }
   }
}

父组件引用的伪代码:

<div v-for="(panel, index) in panels">
     <address-panel
         :address="panel.address"
         :postCode="panel.postCode"
         :telephone="panel.telephone"
         :panelIndex="index"
         :ref="`panel${index}`"
     </address-panel>
</div>

启示录

本文探讨的是父子组件双向通信的方式,以及 v-for 循环创建子组件时怎么动态设置 ref 属性,都是 Vue 基本的知识点,因为封装一个可以重复动态添加的组件而遇到的问题。

测试动态 ref 时,用了 ElementUI 的在线运行编辑器,可能是国外的服务器,也可能是家里网络太慢,响应时间很是磨人的。这是今天 Vue 学习的内容,又离入门近了一点!