您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

vue3.0实现下拉菜单的封装

51自学网 2022-02-21 13:41:24
  javascript

vue3.0出来已经有段时间的了,也与必要开始研究它了!

先看下我们要实现的效果

很常见的展开显示菜单项的内容,在vue3.0里面怎么开发,这里样式我们用的是bootstrap的默认样式

思路一:

<DropDown :title="'退出'" :list="menuLists" />

思路二:

<drop-down :title="'退出'">   <drop-dowm-item>新建文章</drop-down-item>   <drop-dowm-item>编辑文章</drop-down-item>   <drop-dowm-item>个人信息</drop-down-item></drop-down>

两种思路都行,相比较而言,第二种思路比较清晰,使用的时候知道具体的层次,也是elementUI组件开发的模式.
现在就第二种组件开发思路进行分析

DropDown.ts

<template>  <div class="dropdown" ref="dropDownRef">    <a      @click.prevent="toggleOpen"      class="btn btn-secondary dropdown-toggle"      href="#" rel="external nofollow"     >      {{ title }}    </a>    <div class="dropdown-menu" :style="{ display: 'block' }" v-show="isOpen">      <slot></slot>    </div>  </div></template>

js部分

<script lang="ts">import { defineComponent, ref, onMounted, onUnmounted, watch } from "vue";import useClickOutside from "../hooks/useClickOutside";export default defineComponent({  name: "DropDown",  props: {    title: {      type: String,      required: true,    },  },  setup(context) {    const isOpen = ref(false);    //vue3.0获取dom对象的引用    const dropDownRef = ref<null | HTMLElement>(null);    const toggleOpen = () => {      isOpen.value = !isOpen.value;    };    const handleClick = (e: MouseEvent) => {      console.log(e.target, "e");      if (dropDownRef.value) {        console.log(dropDownRef.value);        if (        //contains判断节点是否包含节点          !dropDownRef.value.contains(e.target as HTMLElement) &&          isOpen.value        ) {          isOpen.value = false;        }      }    };    onMounted(() => {    //注册全局的点击事件      document.addEventListener("click", handleClick);    });    onUnmounted(() => {    //解绑      document.removeEventListener("click", handleClick);    });     return {      isOpen,      toggleOpen,      dropDownRef,    };  },});</script>

DropDownItem.ts

<template>  <li class="dropdowm-option" :class="{ 'is-disabled': disabled }">    <slot></slot>  </li></template><style scoped>/* 此处是插槽需要穿透 */.dropdowm-option.is-disabled >>> * {  color: #6c757d;  pointer-events: none;  background-color: transparent;}</style>
<script lang="ts">import { defineComponent } from "vue";export default defineComponent({  props: {    disabled: {      type: Boolean,      default: false,    },  },  setup() {    return {};  },});</script>

到这里这个组件就完成了。但是…我们可以看到点击整个document隐藏这个事件与整个组件的关联不大,因此我们可以抽取成一个hooks

useClickOutside.ts

import { ref, onMounted, onUnmounted,Ref } from 'vue'const useClickOutside = (elementRef:Ref<null | HTMLElement>) => {    const isClickOutside = ref(false)    const handler = (e: MouseEvent) => {        console.log(elementRef.value);        if (elementRef.value) {            if (elementRef.value.contains(e.target as HTMLElement)) {                isClickOutside.value = false            } else {                isClickOutside.value = true            }        }    }    onMounted(() => {      document.addEventListener("click", handler);    });    onUnmounted(() => {      document.removeEventListener("click", handler);    });    return isClickOutside}export default useClickOutside

然后再改写我们的DropDown.ts组件

//删掉之前已有的事件逻辑<script lang="ts">...  const isClickOutside = useClickOutside(dropDownRef);    /* console.log(isClickOutside.value, "isClickOutside"); */    //引入监听方法,数据变化时我们改变isOpen的值为false    watch(isClickOutside, (newValue) => {      if (isOpen.value && isClickOutside.value) {        isOpen.value = false;      }    }); ...</script>

实现了同样的效果,整个组件的代码也精简了不少!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持51zixue.net。


下载地址:
vue3.0实现复选框组件的封装
Vue+Element UI实现下拉菜单的封装
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。