Vue3起手式(一)

24 min read

查看Vue版本

> vue --version
@vue/cli 4.5.8

定义类型接口

export interface ColumnProps {
  _id: string;
  title: string;
  avatar?: ImageProps;
  description: string;
}

props使用类型PropType进行类型传参

1.引入 ProType

import { defineComponent, PropType, computed } from 'vue'

2.传入类型,这里的Array是一个构建函数而非类型,使用as类型断言成类型,方便后续的类型使用

props: {
    list: {
      type: Array as PropType<ColumnProps[]>,
      required: true
    }
  },

Contains

**Node.contains()**返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点。

下面的函数用来检查一个元素是否是body元素的后代元素且非body元素本身.

function isInPage(node) {
  return (node === document.body) ? false : document.body.contains(node);
}

Ref

  • 创建响应式对象

  • 获取节点对象

  • 泛型支持 elementRef: Ref<null | HTMLElement>

  • 取值 RefObject.value

useClickOutside

在hooks中使用Vue生命周期

import { ref, onMounted, onUnmounted, Ref } from 'vue'

const useClickOutside = (elementRef: Ref<null | HTMLElement>) => {
  const isClickOutside = ref(false)
  const handler = (e: MouseEvent) => {
    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

setup生命周期只走一次,对于返回的响应式对象需要使用watch监测其变化

setup() {
    const isOpen = ref(false)
    const dropdownRef = ref<null | HTMLElement>(null)
    const toggleOpen = () => {
      isOpen.value = !isOpen.value
    }
    const isClickOutside = useClickOutside(dropdownRef)

    watch(isClickOutside, () => {
      if (isOpen.value && isClickOutside.value) {
        isOpen.value = false
      }
    })
    return {
      isOpen,
      toggleOpen,
      dropdownRef
    }
  }