• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Vue中的插槽内容渗透和配置参数过滤


Recommended Posts

需求描述

设计一个嵌套结构(基于元素ui组件),从上到下是:

卡片组(动态卡片组)

卡片(动态卡片)

组(动态布局组,包括el行和el列)

下面的实现是通过配置参数动态渲染组件,避免重复编写视图模板。参数严格按照组件结构来声明。

布局组组件作为槽内容传递到卡组组件中,并渗透到卡组件中。布局组将获取并绑定卡片组件过滤后的布局数组,以确保实际生成的页面严格遵循配置参数的结构。

由于“套牌”和“卡片”组件是独立的,当只有一张卡片时,可以直接生成“卡片”而无需渲染“套牌”,更加灵活。

思路分析

Vue的slot语法允许任何符合要求的文本、表达式或组件被传递到子组件中。因此,可以通过嵌套槽将传入子组件槽的内容渗透到更深的子组件中,并且可以获得由更深的子组件的槽所绑定的数据。

定义要穿透的槽:

!-父组件-

!-将父组件的插槽内容传递到子组件的插槽中-

模板v-slot : childslotname=“{ child data }”

!-定义父组件的插槽,并接收外部传入内容-

slot name=' parentSlotName ' : parentdata=' child data '/slot

/模板

!-子组件-

slot name=' childSlotName ' : child data=' datain child '/slot

代码示例

配置参数cardList表示包含两张卡的卡组,每张卡包含两个el行和几个EL列。

卡组(dyn-card-group.vue):

模板

div class='动态卡组'

动态卡片

:卡='卡'

卡片列表中的v-for='(卡片,索引'

:key='index '

!-槽内容渗透到子组件中,得到过滤后子组件绑定的参数-

模板v-slot : children=“{ children }”

狭槽

name='儿童'

:儿童='儿童'

/插槽

/模板

/动态卡

/电子名片

/div

/模板

脚本

从'导入动态卡。/dyn-card . vue ';

导出默认值{

名称: '动力卡组':

props: {

cardList:数组,

},

组件: {

动态卡片,

},

};

/脚本

卡(dyn-card.vue):

模板

div class='动态卡'

电子贺卡

div slot='header '

span{{ card.cardTitle }}/span

/div

!-父组件插槽的内容将穿透此处,并在此处绑定参数-

狭槽

name='儿童'

:children='card.children '

></slot> </el-form-item> </el-card> </div> </template>
<script>
export default {
  name: "dyn-card",
  props: {
    card: {
      cardTitle: String,
      children: Array,
    },
  },
};
</script>

布局组(dyn-layout-group.vue):

<template>
  <div class="dyn-layout-row-group">
    <el-row
      :type="row.type"
      :gutter="row.gutter"
      :class="row.class"
      :justify="row.justify"
      :align="row.align"
      v-for="(row, index) in rowList"
      :key="index"
    >
      <el-col
        :span="col.span"
        :offset="col.offset"
        :push="col.push"
        :pull="col.pull"
        v-for="(col, index) in row.colList"
        :key="index"
      >
      </el-col>
    </el-row>
  </div>
</template>
<script>
export default {
  name: "dyn-layout-row-group",
  data() {
    return {};
  },
  props: {
    rowList: {
      requred: true,
    },
  },
};
</script>

统一导出各组件 index.js:

import dynCardGroup from './dyn-card-group.vue';
import dynCard from './dyn-card.vue';
import dynLayoutGroup from './dyn-layout-group.vue';
export { dynCardGroup, dynCard, dynLayoutGroup};

在主模块中组合三个组件并传入参数:

<template>
  <div class="container">
    <dyn-card-group :cardList="cardList">
      <!-- 布局 -->
      <template v-slot:children="{children}">
        <dyn-layout-group :rowList="children">
          <!-- 字段 -->
          <template v-slot:children>
            <div class="grid-content bg-purple">栅格</div>
          </template>
        </dyn-layout-group>
      </template>
    </dyn-card-group>
  </div>
</template>
<style lang="scss">
.el-row {
  margin-bottom: 20px;
  &:last-child {
    margin-bottom: 0;
  }
}
.grid-content {
  border-radius: 4px;
  min-height: 36px;
}
.bg-purple {
  background: rgb(218, 149, 218);
}
</style>
<script>
import {
  dynCardGroup,
  dynLayoutGroup,
} from "@/components/index";
export default {
  name: "container",
  data() {
    return {
      cardList: [
        {
          cardTitle: "卡片标题",
          // 这里的 children 属性是根据“卡片”组件的 children 属性命名的,
          // 嵌套层级增加时会导致层级辨识困难,
          // 设计时考虑到实际嵌套的组件是动态的,开发时无法确定子组件的名称,因此使用了适用范围更大的抽象命名 children,
          // 优化方法可以考虑将对象拆分,将此处的布局数组在外部定义,然后引用到此处
          children: [
            {
              gutter: 10,
              colList: [{ span: 12 }, { span: 12 }],
            },
            {
              gutter: 10,
              colList: [{ span: 6 }, { span: 6 }, { span: 6 }, { span: 6 }],
            },
          ],
        },
        {
          cardTitle: "卡片标题",
          children: [
            {
              gutter: 20,
              colList: [{ span: 12 }, { span: 12 }],
            },
            {
              type: "flex",
              justify: "space-around",
              gutter: 30,
              colList: [{ span: 6 }, { span: 6 }, { span: 6 }],
            },
          ],
        },
      ],
    };
  },
  components: {
    dynCardGroup,
    dynLayoutGroup,
  },
};
</script>

输出效果:
1p4m2iwubkj3789.png

总结

插槽穿透:

  • 通过以上方式可以实现插槽内容的穿透,不过这种方式只适合被穿透的组件与穿透到的目标组件具有强耦合关系的场景。这种情况下通过可以将两个组件作为统一的整体同时开发与维护,比如示例中的“卡片组”与“卡片”。嵌套层级最好不超过3层,否则会比较难维护。

过滤配置参数:

  • 通过以上方式过滤配置参数,实际上只绑定了组件的相对层级,也就是组件的祖孙关系(甚至可以实现反向祖孙关系),各组件之间仍然是独立的。修改某个组件的结构和内部数据不会影响其他组件,比如修改布局组件不会影响卡片组件,反之亦然。
  • 在使用时,可以将任意的其他组件嵌入到布局和卡片之间,只要保证配置参数是严格符合组件的视图结构即可。配置参数被传入到各级组件时会根据结构分层以及分组,不同层级和不同分组之间不会相关影响,保证了组件之间的低耦合度。
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now