为啥v-for循环tab-panel就不行?

来源:1-1 课程 导读

春去_秋来

2022-06-11

//// Tabs.jsx
import { defineComponent, ref } from 'vue'

export default defineComponent({
  name: 'Tabs',
  props: {
    defaultActiveKey: {
      type: String,
      default: ''
    }
  },
  emits: ['change'],
  setup(props, context) {
    const children = context.slots.default()
    const titles = children.map((panel) => {
      const { key, title } = panel.props || {}
      return {
        key,
        title
      }
    })

    const actKey = ref(props.defaultActiveKey)
    const changeActKey = (key) => {
      actKey.value = key
      context.emit('change', key)
    }

    const render = () => (
      <>
        <ul class="nav nav-tabs">
          {titles.map((item) => {
            const { key, title } = item
            return (
              <li class="nav-item">
                <button
                  key={key}
                  onClick={() => changeActKey(key)}
                  class="nav-link"
                  class={{ active: actKey.value === key }}
                >
                  {title}
                </button>
              </li>
            )
          })}
        </ul>

        <div class="tab-content">
          <div class="tab-pane fade show active">
            {children.find((panel) => {
              const { key } = panel.props || {}
              return actKey.value === key
            })}
          </div>
        </div>
      </>
    )

    return render
  }
})
//// TabPanel.vue
<template>
  <slot></slot>
</template>

<script setup>
defineProps({
  title: {
    type: String,
    default: ''
  }
})
</script>
//// 使用组件(写死 tab-panel 可以)
<script setup>
import Tabs from '@/components/Tab/Tabs.jsx'
import TabPanel from '@/components/Tab/TabPanel.vue'

const onTabsChange = (key) => {
  console.log('tab changed', key)
}
</script>

<template>
  <tabs default-active-key="1" @change="onTabsChange">
    <tab-panel key="1" title="tab1">
      <div>This is tab1 content...</div>
    </tab-panel>
    <tab-panel key="2" title="tab2">
      <div>This is tab2 content...</div>
    </tab-panel>
  </tabs>
</template>
//// 使用组件(v-for tab-panel 不行)
<script setup>
import Tabs from '@/components/Tab/Tabs.jsx'
import TabPanel from '@/components/Tab/TabPanel.vue'
import { ref } from 'vue'

const data = ref([
  {
    title: 'tab1',
    description: 'This is tab1 content...'
  },
  {
    title: 'tab2',
    description: 'This is tab2 content...'
  }
])

const onTabsChange = (key) => {
  console.log('tab changed', key)
}
</script>

<template>
  <tabs default-active-key="1" @change="onTabsChange">
    <tab-panel v-for="(item, k) in data" :key="k" :title="item.title">
      <div>{{ item.description }}</div>
    </tab-panel>
  </tabs>
</template>
写回答

1回答

Sunday

2022-06-12

你好

v-for 循环 子节点组件元素,会导致 通过 slots 获取时,内容被存放到 数组的 children 中,所以你需要从 数组的 children 中额外获取。

0
2
Sunday
回复
春去_秋来
这需要增加很多的逻辑判断,比如可以判断 children 是否为一个数组
2022-06-12
共2条回复

基于 Vue3 ,打造前台+中台通用开发提效解决方案

42 种前台常见业务模型, 15 种中台通用组件,成为前端提效高手

788 学习 · 517 问题

查看课程