7

在 vue3 中轻松实现 switch 功能组件 「简单易懂」

 3 years ago
source link: https://my.oschina.net/u/4811659/blog/4881065
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

编程语言里面,除了使用 if 语句来做条件判断,还有另外一个常用的就是 switch 了。

而在 vue 中,官方已经帮助我们实现了 v-if 这个指令,但是还没有 switch ,那我们能不能自己实现一个呢?

这篇文章就是来探索这个问题,并且最终实现一个 Switch 组件

先来看看我们希望用户是如何使用 Switch 的

用 js 的方式来对比一下:

用户可以通过一个 VSwitch 组件来应用 switch 功能

通过 case 来确定匹配的条件

然后每一个 case 匹配的条件用 template 来表示

这样我们已经规定好用户该如何使用了,剩下的其实就是实现了

这一步背后的思想就是确定组件的规格,也可以说是确定组件的使用接口

那么我们应该如何实现呢?

我们先来思考一下 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 都显示出来呢?

作者:春去春又来

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK