美文网首页
Breadcrumb Vue 3 TypeScript版本

Breadcrumb Vue 3 TypeScript版本

作者: EasyNetCN | 来源:发表于2021-04-04 22:24 被阅读0次

本示例主要演示了父组件通过provide传递数据,以及子组件通过inject接收并处理父组件传递过来的数据

Breadcrumb

<template>
    <div :class="classes">
        <slot></slot>
    </div>
</template>
<script lang="ts">
import { defineComponent, computed, provide, toRefs } from 'vue'
const prefixCls = 'ivu-breadcrumb'

export default defineComponent({
  name: 'Breadcrumb',
  props: {
    separator: {
      type: String,
      default: ''
    }
  },
  setup (props) {
    const { separator } = toRefs(props)

    provide('separator', separator)

    const classes = computed(() => {
      return `${prefixCls}`
    })

    return {
      classes
    }
  }
})
</script>

BreadcrumbItem

<template>
    <span>
        <a
            v-if="to"
            :href="linkUrl"
            :target="target"
            :class="linkClasses"
            @click.exact="handleCheckClick($event, false)"
            @click.ctrl="handleCheckClick($event, true)"
            @click.meta="handleCheckClick($event, true)">
            <slot></slot>
        </a>
        <span v-else :class="linkClasses">
            <slot></slot>
        </span>
        <span :class="separatorClasses" v-html="separator" v-if="!showSeparator"></span>
        <span :class="separatorClasses" v-else>
            <slot name="separator"></slot>
        </span>
    </span>
</template>
<script lang="ts">
import { computed, defineComponent, getCurrentInstance, inject, onMounted, PropType, ref, toRefs } from 'vue'
const prefixCls = 'ivu-breadcrumb-item'

export default defineComponent({
  name: 'BreadcrumbItem',
  props: {
    to: {
      type: [Object, String]
    },
    replace: {
      type: Boolean,
      default: false
    },
    target: {
      type: String as PropType<'_blank' | '_self' | '_parent' | '_top'>,
      default: '_self'
    },
    append: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  setup (props, ctx) {
    const { to, replace, target, append } = toRefs(props)

    const separator = inject('separator')
    const showSeparator = ref(false)

    const instance = getCurrentInstance()
    const router = instance?.appContext.config.globalProperties.$router

    const linkClasses = computed(() => {
      return `${prefixCls}-link`
    })

    const separatorClasses = computed(() => {
      return `${prefixCls}-separator`
    })

    const linkUrl = computed(() => {
      const type = typeof to?.value
      if (type !== 'string') {
        return null
      }
      if ((to?.value as string).includes('//')) {
        /* Absolute URL, we do not need to route this */
        return to?.value
      }

      if (router) {
        const current = router.currentRoute
        const route = router.resolve(to?.value, current, append.value)
        return route ? route.href : to?.value
      }
      return to?.value
    })

    onMounted(() => {
      showSeparator.value = ctx.slots.separator !== undefined
    })

    const handleClick = (newWindow = false) => {
      if (newWindow) {
        let toOpen = to?.value

        if (router) {
          const current = router.currentRoute
          const route = router.resolve(to?.value, current, append.value)
          toOpen = route ? route.href : to?.value
        }
        window.open(toOpen as string)
      } else {
        if (router) {
          if ((typeof to?.value === 'string') && to.value.includes('//')) {
            window.location.href = to.value
          } else {
            replace.value ? router.replace(to?.value) : router.push(to?.value)
          }
        } else {
          window.location.href = to?.value as string
        }
      }
    }

    const handleCheckClick = (event: any, newWindow = false) => {
      if (to?.value) {
        if (target.value === '_blank') {
          return false
        } else {
          event.preventDefault()
          handleClick(newWindow)
        }
      }
    }

    return {
      separator,
      showSeparator,
      linkClasses,
      separatorClasses,
      linkUrl,
      handleClick,
      handleCheckClick
    }
  }
})
</script>

相关文章

网友评论

      本文标题:Breadcrumb Vue 3 TypeScript版本

      本文链接:https://www.haomeiwen.com/subject/oyhrkltx.html