阅读 87

组件封装之入门,还扯到了diff操作

为什么要封装

最近最后台管理项目,表单写的有点多,其中下拉框代码最占地方,整个文件显的很大,我就想把它封起来,正好做表格的时候封装了一个根据金额正负显示的颜色的小组件。这次把两个组件都来出来说说。

根据正负显示颜色

封装组件肯定要绑定数据,子组件离不开props。使用value是因为要在父组件的D2组件的columns里调用,默认参数是value。 子组件里的props

 props: {
    value: {
      required: true,
    },
  },复制代码

在子组件中props已经接受数据,并可以用this拿到了,所以我直接在template中使用。在标签中进行style的判断就可以实现颜色改变。这段代码意思是:在value里查找-,如果存在就返回位置,这个返回值一定大余等于-1,这时三元运算符判断通过返回red,显示红色。相反找不到-1返回-1,显示绿色。

 <span :style="{ color: String(value).indexOf('-') > -1 ? 'red' : 'green' }">
      {{ value }}
 </span>复制代码

父组件的D2组件里的columns

columns: [
        { title: "金额", key: "money", component: { name: TradeAmount } },
      ],复制代码

这个组件只是用来显示,不需要其他操作,所以最简单。

下拉框的封装

这个要多操作几步 由于子组件要接受一个数组props如下:

props: {
    selections: {
      type: Array,
    },
  },复制代码

参数接受了要放入下拉框,问题来了。el-option标签作为选择项要遍历数组显示出来;要选择某一项,还要对选中的值进行操作,就需要在el-select里绑定一个值,这里我用的value,其他值也行,只是一个代号,在data里返回。

<el-select v-model="value" placeholder="请选择状态" clearable>
      <el-option
        v-for="item in selections"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
      </el-option>
</el-select>复制代码

接下来要考虑选中时,value会发生变化,这样我们可以根据值的变化触发事件,把值传给父组件。这里我用了watch监听,其实在组件使用change绑定方法也可以。这样的话,每次值的变化会被watch监听到,触发onChange方法,从而派发一个input的事件,同时携带value

methods: {
    onChange() {
      console.log(this.value);
      this.$emit("input", this.value);
    },
  },
watch: {
    value: "onChange",
},复制代码

到这里子组件的工作完成了。 下面进行父组件的操作。

  1. 第一步在父组件中import引入

  2. components注册为perSelect

  3. template进行使用

父组件代码使用如下

<perSelect
        v-model="formInline.productSource"
        :selections="distributionProductSource"
        :key="componentKey"
></perSelect>复制代码

下面分开解析:

  • 第一部分:

v-model="formInline.productSource"复制代码

这个v-model可以分为:value@input,可以理解为

<input :value="formInline.productSource" @input="formInline.productSource= $event.target.value">复制代码

这样一来,就可以在父组件拿到子组件触发的input事件携带的数据,同时复制给formInline.productSource

  • 第二部分

:selections="distributionProductSource"复制代码

这个部分就是给子组件传值了。 重点在第三部分

  • 第三部分

:key="componentKey"复制代码

我们知道循环组件的时候要加key,为什么我这里加key呢?这里简单说一下key的作用,key是虚拟DOM的唯一标识,通过key可以让diff操作准确找到新旧树的不同。然后patch到真实DOM。

我在这里用key,是要利用key变化,会从新渲染组件,不会节点复用。

为什么要避免节点复用呢?

因为我在清空表单,也就是清空formInline.productSource时发现这里变化了,但是子组件里的value没有改遍,仔细想来,我确实只给子组件传了数组,但没从父组件给子组件其他操作。相当于我每次清空表单,虽然子组件的v-model没了,但子组件内部还在,节点就根本没有变化。

现在我要避免这种情况,最简单的就是在父组件引用的子组件上加一个key。每一次清空,改变key的值,这样vue根据这个唯一标识,就会从新开始渲染子组件。

当然也可以用v-if,根据条件判断进行DOM的建立与销毁。但是没有加key好,因为key可以帮助diff操作更快更准确找到这个子组件。


作者:常彬
链接:https://juejin.cn/post/7024453018779123720


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐