在 vue3 中輕鬆實現 switch 功能組件

what

編程語言裏面,除了使用 if 語句來作條件判斷,還有另一個經常使用的就是 switch 了。vue

而在 vue 中,官方已經幫助咱們實現了 v-if 這個指令,可是尚未 switch ,那咱們能不能本身實現一個呢?node

這篇文章就是來探索這個問題,而且最終實現一個 Switch 組件編程

以終爲始

先來看看咱們但願用戶是如何使用 Switch 的markdown

用 js 的方式來對比一下:編程語言

用戶能夠經過一個 VSwitch 組件來應用 switch 功能函數

經過 case 來肯定匹配的條件ui

而後每個 case 匹配的條件用 template 來表示spa

這樣咱們已經規定好用戶該如何使用了,剩下的其實就是實現了設計

這一步背後的思想就是肯定組件的規格,也能夠說是肯定組件的使用接口3d

how

那麼咱們應該如何實現呢?

咱們先來思考一下 switch 的功能

拆分 Switch 功能

某個等於 case 值的那個模板顯示,別的都不該該顯示

舉個栗子:

case = "xiaohong" 時

那麼就只能顯示名字爲 "xiaohong" 的插槽

若是沒有匹配到任何一個 case ,而且還有 defalut 插槽時,顯示 defalut 插槽

固然,switch 還有更復雜的功能,咱們這裏先從最核心的功能入手,慢慢在複雜化(迭代思想)

實現原理

首先咱們必須先知道該組件的 slots,都有哪些

在 vue3 中,咱們只須要經過如下方式就能夠輕鬆獲取 slots

setup(props,{slots}){
  console.log(slots)
}
複製代碼

若是打印 slots 的話,你會發現能夠獲得一個對象,而 key 的值就是 slot 的名稱,而 value 是一個函數,調用這個函數就能夠獲取到對應的 vnode。

那好比我想顯示 xiaohei 這個插槽要怎麼作呢?

只須要這樣

setup(props, { slots }) {
    
    return () => {
      return slots.xiaohei()
    };
  },
複製代碼

setup 除了能夠返回一個對象,做爲導出給 template 用的數據,還能夠直接返回一個函數做爲 render。

而 render 函數只要返回對應的 vnode ,那麼最終就會被渲染到 view 上。

因此按照上面代碼的寫法的話最終會顯示 xiaohei slot 內部的內容

那當明白上述知識點後,咱們在回來看看第一個功能

是否是隻要咱們把和 case 匹配的 slots 渲染出來便可

看代碼:

export default {
  props: ["case"],
  setup(props, { slots }) {
    console.log(slots);
    return () => {
      if (slots[props.case]) {
        return slots[props.case]();
      }
    };
  },
};

複製代碼

注意哦,必定要加條件判斷,由於頗有多是沒有對應的 slot 的

看,懂了原理以後是否是很輕鬆的實現第一個功能了。

咱們在來看第二個功能的時候是否是也很簡單了

只須要在加一段代碼便可:

export default {
  props: ["case"],
  setup(props, { slots }) {
    console.log(slots);
    return () => {
      if (slots[props.case]) {
        return slots[props.case]();
      }

      if (slots["default"]) {
        return slots["default"]();
      }
    };
  },
};

複製代碼

若是在第一個條件那沒有匹配到的話,確定會到達第二個條件判斷,也就是 if (slots["default"])

接着就是若是有 default slot 的話,那麼就返回便可

至此,你已經實現了一個簡單的 Switch 功能組件了

總結

讓咱們來總結總結你已經學到了哪些知識點

  • 設計組件時,先設計該組件的規則(接口)
  • tasking 的思想,把大功能拆小,而後逐一擊破
  • 在 vue3 中獲取 slots 的方式
  • setup 不止能夠返回對象,還能夠返回一個函數,效果同 render 函數同樣
  • render 函數返回的 vnode 最終會被渲染到 view 上

若是你學到的話,那麼請用你的小手點個贊唄~~~

完整代碼

// VSwitch.vue
<script>
export default {
  props: ["case"],
  setup(props, { slots }) {
    return () => {
      if (slots[props.case]) {
        return slots[props.case]();
      }

      if (slots["default"]) {
        return slots["default"]();
      }
    };
  },
};
</script>
複製代碼

擴展思考

那其實這裏實現的 switch 功能並不完整,若是說用戶匹配知足多個條件呢?而且沒有 break,那麼咱們是否是應該把匹配到的 template 都顯示出來呢?

本身嘗試一下實現看看?

相關文章
相關標籤/搜索