Ⅰ. vue.extend 使用场景

  • 需要 频繁 向 多个类型 vue组件中 导入组件,而且存在 频繁切换;
  • (如果 v-if  和 v-else ,需要到每个向里面去添加 ,不太好 )
  • 调用 方法就去页面中 ,添加一条   Message 提示  的vue组件 ,而且点击多次会多次弹出。

这时 :vue.extend 就有了合理的出场机会。

  • 效果如下:

f4acfdb3bc2b41528c46cf6cd53c451e.gif

  •  需要创建 四个文件,举例如下 :

84f7e3ae8f54421cb0a96763a0b07291.png

   inputBox  =>  双击后出现的输入框组件;

    textBox   =>   双击已是输入框的,或点保存,还原的文本组件;

    changeBox => 是将 上面两个组件导入 ,继承并暴露出去;

    tableBox =>  通过new  changeBox 暴露的继承组件 ,实现功能。


Ⅱ. 通过 vue.extend 实现表格的任意编辑多条数据

  •  首先创建一个输入框,和一个文本框组件,便于后面的继承。 

输入框如下  inputBox.vue

<template>
    <input  class="inputBox"  v-model="value" />
</template>
<script>
export default {
  props: {
     value: String || Number,
  }
}
</script>

文本框如下 textBox.vue

<template>
  <div class="cell">{{ value }} </div>
</template>
<script>
export default {
  props: {
    value: String || Number,
  },
};
</script>

  •  创建一个 中间 Js 文件, 用于继承,上面 2 个输入框组件

   中间层  changeBox.js  

import Vue from "vue";
import  inputBox from "./inputBox.vue";
import textBox from "./textBox.vue";

const inputItem = Vue.extend(inputBox);
const textItem = Vue.extend(textBox);
export default {
    inputItem,
    textItem,
}

去使用extend  继承组件

采用 element - ui 的表格 ,方便双击 ,找到对应的 dom 【不用自己手写】

  1. 通过 new  继承组件  , 然后通过 $mount  , 去挂载指定的位置 ;
  2. 写成 2 个方法  changeInput 【切换输入框】,changeText 【切换文本】;
  3. 通过双击 判断 对应节点的   className  来 实现    输入框 ↔ 文本    来回切换 ;
  4. keepAll 方法 ,用于将所有没有切换的 输入框  转换成文本 , 主要通过遍历dom【注意 :这里的dom数组是伪数组,转换成真数组才能用数组的方法】,来修改虚拟dom 
  5. 通过遍历,重复调用 changeText  ,来实现全部保存成文本 ;

  table.vue最后表格组件代码整合:

<template>
  <div class="pageBox">
    <el-table
      :data="tableData"
      size="mini"
      class="tableBox"
      @cell-dblclick="dblclick"
    >
      <el-table-column
        v-for="item in columns"
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
      />
    </el-table>
    <el-button @click="keepAll">保存</el-button>
  </div>
</template>
<script>
import changeBox from "./changeBox";
export default {
  data() {
    return {
      columns: [
        { prop: "name", label: "姓名" },
        { prop: "height", label: "身高" },
      ],
      tableData: [
        { name: "张三", height: "180cm" },
        { name: "李四", height: "185cm" },
      ],
    };
  },
  methods: {
    dblclick(row, column, cell) {
      let to = cell.children[0];

      if (to.className.includes("inputBox")) {
        this.changeText(to.value, to);
      } else {
        this.changeInput(cell.innerText, to);
      }
    },

    changeInput(value, to) {
      new changeBox.inputItem({ propsData: { value: value } }).$mount(to);
    },
    changeText(value, to) {
      new changeBox.textItem({ propsData: { value: value } }).$mount(to);
    },

    keepAll() {
      //遍历dom ,修改虚拟dom
      let inputList = document.getElementsByClassName("inputBox");
      [...inputList].forEach((item) => {
        let text = item.value;
        this.changeText(text, item);
      });
    },
  },
};
</script>

Logo

前往低代码交流专区

更多推荐