wd-tab.vue 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <template>
  2. <view :class="`wd-tab ${customClass}`" :style="customStyle">
  3. <view :class="['wd-tab__body', { 'wd-tab__body--inactive': !active }]" v-if="shouldBeRender" :style="tabBodyStyle">
  4. <slot />
  5. </view>
  6. </view>
  7. </template>
  8. <script lang="ts">
  9. export default {
  10. name: 'wd-tab',
  11. options: {
  12. addGlobalClass: true,
  13. virtualHost: true,
  14. styleIsolation: 'shared'
  15. }
  16. }
  17. </script>
  18. <script lang="ts" setup>
  19. import { getCurrentInstance, ref, watch, type CSSProperties } from 'vue'
  20. import { isDef, isNumber, isString, objToStyle } from '../common/util'
  21. import { useParent } from '../composables/useParent'
  22. import { TABS_KEY } from '../wd-tabs/types'
  23. import { computed } from 'vue'
  24. import { tabProps } from './types'
  25. const props = defineProps(tabProps)
  26. const { proxy } = getCurrentInstance() as any
  27. const { parent: tabs, index } = useParent(TABS_KEY)
  28. // 激活项下标
  29. const active = computed(() => {
  30. return isDef(tabs) ? tabs.state.activeIndex === index.value : false
  31. })
  32. const painted = ref<boolean>(active.value) // 初始状态tab不会渲染,必须通过tabs来设置painted使tab渲染
  33. const tabBodyStyle = computed(() => {
  34. const style: CSSProperties = {}
  35. if (!active.value && (!isDef(tabs) || !tabs.props.animated)) {
  36. style.display = 'none'
  37. }
  38. return objToStyle(style)
  39. })
  40. const shouldBeRender = computed(() => !props.lazy || painted.value || active.value)
  41. watch(active, (val) => {
  42. if (val) painted.value = true
  43. })
  44. watch(
  45. () => props.name,
  46. (newValue) => {
  47. if (isDef(newValue) && !isNumber(newValue) && !isString(newValue)) {
  48. console.error('[wot ui] error(wd-tab): the type of name should be number or string')
  49. return
  50. }
  51. if (tabs) {
  52. checkName(proxy)
  53. }
  54. },
  55. {
  56. deep: true,
  57. immediate: true
  58. }
  59. )
  60. /**
  61. * @description 检测tab绑定的name是否和其它tab的name冲突
  62. * @param {Object} self 自身
  63. */
  64. function checkName(self: any) {
  65. const { name: myName } = props
  66. if (myName === undefined || myName === null || myName === '') {
  67. return
  68. }
  69. tabs &&
  70. tabs.children.forEach((child: any) => {
  71. if (child.$.uid !== self.$.uid && child.name === myName) {
  72. console.error(`The tab's bound value: ${myName} has been used`)
  73. }
  74. })
  75. }
  76. </script>
  77. <style lang="scss" scoped>
  78. @import './index.scss';
  79. </style>