1. <dd id="erndk"></dd>
                1. Vue 中的插槽內容穿透和配置參數過濾

                  互聯網 2022/5/1 23:14:21

                  需求描述 (以element ui組件為基礎)設計一種嵌套結構,從上到下依次是:卡片組(dyn-card-group) 卡片(dyn-card) 布局組(dyn-layout-group,包含 el-row 和 el-col)以下實現是通過配置參數的方式動態渲染組件,避免重復書寫視圖模板。配置參數嚴格按照組件結構聲明。 將“…

                  需求描述

                  (以element ui組件為基礎)設計一種嵌套結構,從上到下依次是:

                  • 卡片組(dyn-card-group)
                  • 卡片(dyn-card)
                  • 布局組(dyn-layout-group,包含 el-rowel-col)

                  以下實現是通過配置參數的方式動態渲染組件,避免重復書寫視圖模板。配置參數嚴格按照組件結構聲明。

                  將“布局組”組件作為插槽內容傳入“卡片組”組件,并穿透到“卡片”組件內,“布局組”會獲取并綁定“卡片”組件過濾后的布局數組,以確保實際生成的頁面嚴格遵照配置參數的結構。

                  由于“卡片組”和“卡片”組件是獨立的,當只有一個卡片時可以不渲染“卡片組”直接生成“卡片”,更加靈活。

                  思路分析

                  Vue 的插槽語法允許將任意符合要求的文本、表達式或組件傳入到子組件中。因此,可以通過嵌套插槽的方式,將傳入子組件插槽的內容穿透到更深層次的子組件中,并且可以獲取到深層次子組件的插槽所綁定的數據。

                  定義需要穿透的插槽:

                  <!-- 父組件 -->
                  ···
                    <!-- 將父組件的插槽內容傳入子組件的插槽 -->
                    <template v-slot:childSlotName="{childData}">
                      <!-- 定義父組件的插槽,接收外部傳入的內容 -->
                      <slot name="parentSlotName" :parentData="childData"></slot>
                    </template>
                  ···
                  <!-- 子組件 -->
                  ···
                    <slot name="childSlotName" :childData="dataInChild"></slot>
                  ···
                  

                  代碼示例

                  配置參數 cardList 表示一個卡片組,組內包含兩個卡片,每個卡片各自包含兩個 el-row 以及若干 el-col。

                  卡片組(dyn-card-group.vue):

                  <template>
                    <div class="dyn-card-group">
                      <dyn-card
                        :card="card"
                        v-for="(card, index) in cardList"
                        :key="index"
                      >
                        <!-- 插槽內容穿透到子組件,并獲取子組件過濾后綁定的參數 -->
                        <template v-slot:children="{children}">
                          <slot
                            name="children"
                            :children="children"
                          >
                          </slot>
                        </template>
                      </dyn-card>
                      </el-card>
                    </div>
                  </template>
                  
                  <script>
                  import dynCard from "./dyn-card.vue";
                  export default {
                    name: "dyn-card-group",
                    props: {
                      cardList: Array,
                    },
                    components: {
                      dynCard,
                    },
                  };
                  </script>
                  

                  卡片(dyn-card.vue):

                  <template>
                    <div class="dyn-card">
                      <el-card>
                        <div slot="header">
                          <span>{{ card.cardTitle }}</span>
                        </div>
                  
                        <!-- 父組件插槽的內容會穿透到這里,并獲取此處綁定的參數 -->
                        <slot
                          name="children"
                          :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>
                  

                  輸出效果:

                  總結

                  插槽穿透:

                  • 通過以上方式可以實現插槽內容的穿透,不過這種方式只適合被穿透的組件與穿透到的目標組件具有強耦合關系的場景。這種情況下通過可以將兩個組件作為統一的整體同時開發與維護,比如示例中的“卡片組”與“卡片”。嵌套層級最好不超過3層,否則會比較難維護。

                  過濾配置參數:

                  • 通過以上方式過濾配置參數,實際上只綁定了組件的相對層級,也就是組件的祖孫關系(甚至可以實現反向祖孫關系),各組件之間仍然是獨立的。修改某個組件的結構和內部數據不會影響其他組件,比如修改布局組件不會影響卡片組件,反之亦然。
                  • 在使用時,可以將任意的其他組件嵌入到布局和卡片之間,只要保證配置參數是嚴格符合組件的視圖結構即可。配置參數被傳入到各級組件時會根據結構分層以及分組,不同層級和不同分組之間不會相關影響,保證了組件之間的低耦合度。
                  隨時隨地學軟件編程-關注百度小程序和微信小程序
                  關于找一找教程網

                  本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
                  本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
                  [Vue 中的插槽內容穿透和配置參數過濾]http://www.yachtsalesaustralia.com/tech/detail-318563.html

                  贊(0)
                  關注微信小程序
                  程序員編程王-隨時隨地學編程

                  掃描二維碼或查找【程序員編程王】

                  可以隨時隨地學編程啦!

                  技術文章導航 更多>
                  国产在线拍揄自揄视频菠萝

                        1. <dd id="erndk"></dd>