什么是组件化

组件化是一种思维,就是拆分的意思,艰深而言,就是大而化小(没有小而化了)、方便管理。比方咱们中国地大物博,人口众多不好治理,所以就拆分成许多省、直辖市、自治区,方便管理。写代码也是一样,如果一个文件写了几万行代码,就会耦合太重大,拆分开来,方便管理。

然而组件化不能过渡应用,不能为了组件化而组件化。正当应用,才为上策

组件化和模块化的区别

  • 组件化-ui视图层面的拆分
    以vue为例,一个页面有头部、内容区、底部。能够拆分开来,这里的拆分个别都会带着款式css,所以称之为UI视图层面的拆分(当然也会蕴含js的相干逻辑)
  • 模块化-js层面的拆分
    模块化的拆分次要是js逻辑层面的拆分,二者相似,但不同

组件的分类

  • 独立拆分的组件
    比方咱们把一个页面的头部、内容区、底部别离拆分成三个独立的组件
  • 公共复用的组件
    比方在很多的路由页面里,都须要应用到一个弹框、或者应用到一个表格。咱们能够封装一个弹框或者封装一个表格,哪里须要引哪里,不同页面的弹框或表格数据不一样,咱们能够通过给封装的公共组件传递不同的数据,使其展示不同。

    其实一个.vue文件就是一个组件,只不过是页面级别的组件罢了

独立拆分的组件之拆分步骤

第一步 组件拆分

原本都写在一个文件中的内容,比方一个.vue文件的构造中包含头部、底部、内容区。咱们把头部的html、css、js的内容,独自拎进去成为一个新的.vue文件。当然底部、和内容区的也同样独自拎进去。独自拎进去的就放在components文件夹下吧

第二步 组件引入

import dialogMask from "./components/dialog";

第三步 组件注册

// 是components不是component,要加个s,因为组件可能要注册多个export default {    // ...    components: {        dialogMask,    },}

第四步 组件应用

<div class="dialog">      <dialog-mask></dialog-mask></div>

公共复用的组件之拆分步骤

复用组件的拆分步骤,最初el-table组件的二次封装会解说,诸位看官且持续往下看。这里先按下不表。
说道组件的封装,就要与数据传递打交道,所以这里简略说一下vue组件间的数据传递,又因为封装组件大多数的数据传递是以父子组件的传递为主,所以这里提一下vue父子组件间的数据传递。

父子组件间的数据传递之两种形式

形式一(v-bind加v-on)

父传子

  • 父组件v-bind绑定本人data中数据传递给子组件
  • 子组件通过props接管到在页面中应用
    步骤图如下:

    子传父

  • 子组件通过this.$emit('eventName','参数')触发父组件中的办法
  • 父组件要提前在组件上通过v-on裸露给子组件以便调用
    步骤图如下:

    形式二(应用ref取值赋值)

    父传子或子传父

  • 第一步,给子组件打一个ref,就能够看到子组件所有的货色,感兴趣的敌人能够打印一下this.$refs.dialogRef后果高深莫测。

    <dialogMask ref="dialogRef"></dialogMask>
  • 第二步,在父组件中把父组件的数据赋给子组件(父传子)

    this.$refs.dialogRef.子组件的数据 = this.父组件的数据
  • 第三步,在子组件中间接取到拿到子组件的数据赋给父组件

    this.父组件的数据 = this.$refs.dialogRef.子组件的数据

父子组件的办法的互相调用

就记住罕用的形式吧

  • 父组件调用子组件的办法,应用ref
    this.$refs.xxx.childMethods()
  • 子组件调用父组件的办法,应用this.$emit('eventName','参数')
    this.$emit('eventName','参数')

饿了么UI中的el-table组件的二次封装

饿了么UI的组件是饿了么团队基于vue封装的,外面有很多罕用的组件,不便咱们疾速开发我的项目。不过假如咱们的我的项目中的很多页面都有表格出现,表格的构造差不多,就是数据不一样,如果我么每个页面都去写el-table一大堆的话,就会比拟麻烦,倒不如本人封装一个公共的table组件,那个页面用table的话,那个页面就引进来,传参即可。

第一步,新建组件,注册并在main.js引入

流程图如下:

至此,咱们自定义的封装的myTable组件曾经注册好了,那个页面须要用,就在那个页面去引入,传对应的参数即可

第二步,依据需要思考传参

咱们先看一下效果图:

需要如下:

  • 复选框列和序号列可管制是否展现
  • 表头数据动静展现
  • 表内容数据也动静展现
理论我的项目中咱们要发申请获取表的数据和表内容数据,这里的话,咱们就模仿一下数据即可

封装的myTable组件代码

<template>  <div class="box">    <el-table      :data="tableData"      border      style="width: 100%"      @selection-change="handleSelectionChange"    >      <!-- 复选框列              复选框列和索引列因为有的显示有的不显示,所以咱们应用一个v-if去管制它,              v-if的标识取决于父组件(援用这个组件的组件)传递过去的标识。子组件也就是              咱们封装的这个myTable组件用props接管一下又因为复选框要有勾选工夫所以              @select-change事件不能落下       -->      <el-table-column        v-if="isShowCheckbox == true"        type="selection"        width="48"        fixed      ></el-table-column>      <!-- 索引列 -->      <el-table-column        v-if="isShowIndex == true"        label="序号"        type="index"        width="50"        fixed      >      </el-table-column>      <!-- 主内容列               主内容列的表头就是label,表头列对应的数据就是prop,所以父组件能够传递过去              一个数组,外面的每一项就是label的名字和prop对应的值。通过v-for就动静了      -->      <el-table-column        :prop="item.propName"        :label="item.labelName"        v-for="(item, index) in tableHeaderTitle"        :key="index"      >      </el-table-column>    </el-table>  </div></template><script>export default {  name: "myTable",  props: {    // 父组件传递过去的表头的数组数据    tableHeaderTitle: {      type: Array,      default: [],    },    // 父组件传递过去的表内容的数组数据    //  留神:表头内容数据和表内容数据有关联的    tableData: {      type: Array,      default: [],    },    // 父组件传递过去的是否展现复选框列的标识    isShowCheckbox: {      type: Boolean,      default: false,    },    // 父组件传递过去的是否展现序号索引列的标识    isShowIndex: {      type: Boolean,      default: false,    },  },  methods: {    // 勾选当前,要把勾选的这一行的数据传递给父组件,以供应用    handleSelectionChange(checked) {      this.$emit("receiveCheckedData", checked);    },  },};</script>

援用myTable组件的父组件代码

<template>  <div id="app">    <!-- 因为之前曾经vue全局注册了本人封装的组件,所以这里不须要在引入这个组件了         能够间接用即可 -->    <my-table      :tableHeaderTitle="tableHeaderTitle"      :tableData="tableData"      :isShowCheckbox="isShowCheckbox"      :isShowIndex="isShowIndex"      @receiveCheckedData="receiveCheckedData"    ></my-table>  </div></template><script>export default {  data() {    return {      // 模仿表头数据,理论要发申请获取的      tableHeaderTitle: [        {          propName: "name",          labelName: "姓名",        },        {          propName: "age",          labelName: "年龄",        },        {          propName: "gender",          labelName: "性别",        },        {          propName: "height",          labelName: "身高",        },        {          propName: "weight",          labelName: "体重",        },        {          propName: "like",          labelName: "喜好",        },        {          propName: "address",          labelName: "住址",        },      ],      // 模仿表内容数据      tableData: [        {          id:"11111",          name: "孙悟空",          age: 500,          gender: "男",          height: "七尺男儿",          weight: "三百吨",          like: "桃子",          address: "花果山水帘洞",        },        {          id:"22222",          name: "猪八戒",          age: 88,          gender: "男",          height: "七尺男儿",          weight: "八百吨",          like: "肉包子",          address: "高老庄",        },        {          id:"33333",          name: "沙和尚",          age: 1000,          gender: "男",          height: "七尺男儿",          weight: "三百吨",          like: "鱼",          address: "通天河",        },      ],      // 是否展现复选框列      isShowCheckbox:true,      // 是否展现序号索引列      isShowIndex:true,    };  },  methods: {    // 接管子组件勾选的行的数据    receiveCheckedData(checked){      console.log('checked',checked);    }  },};</script><style lang="less" scoped>#app {  width: 100%;  min-height: 100vh;  box-sizing: border-box;  padding: 50px;}</style>

在理论状况中,须要依据产品的需要,去做出对应的封装。组件封装肯定要灵便

补充(看饿了么组件的播种)

咱们关上node_modules文件夹下,外面有很多的依赖包(库),咱们找到element-ui的这个文件夹,外面的packages文件夹寄存的就是饿了么团队封装好的组件。如下图:

没事看看也挺好,也能学到不少的货色

**小伙伴们如果感觉文章写的还勉强对付能看,给激励一下点个赞呗。感激哦**