【vue3】项目中使用jsx语法

目标:用jsx语法 渲染出这个结构

 选项卡和下面内容 分别是 b2c-tabs组件和b2c-panel组件

b2c-tabs组件放置所有选项卡,每个b2c-panel放置一个选项卡

在index页面

<template>
    <!-- <体验jsx语法 -->
     <!-- 引入选项卡组件,里面放默认插槽内容panel组件 -->
    <b2c-tabs>
      <b2c-tabs-panel label="选项卡1" name="first">内容1</b2c-tabs-panel>
      <b2c-tabs-panel label="选项卡2" name="first">内容2</b2c-tabs-panel>
    </b2c-tabs>
  </div>
</template>

b2c-tabs页

<!-- jsx语法写,组件tabs-panel组件 -->
<script>
export default {
  name: 'B2cTabs',
  render () {
    // 需要在这里进行组织
    // 1.tabs组件大容器
    // 2.选项卡的导航菜单结构
    // 3.内容容器

    // 2.选项卡的导航菜单结构
    // 获取index页面 里b2c-tabs组件里的插槽内容  (几个panel组件)
    // label选项卡的文字,name选项卡的唯一标识,panels的长度就是选项卡的个数
    const panels = this.$slots.default()// panels就是 装着所有panel的面板,this是tabs组件
    // 选项卡依赖于 index页面 里 panel组件的label
    const nav = <nav>
        {
            panels.map((panel, i) => <a href="javascript:;">{panel.props.label}</a>)
        }
    </nav>
    // 3.内容容器
    // 选项卡依赖于 index页面 里 b2c-tabs-panel组件的 插槽内容
    // 可以去这个组件里 写一个容器,比较省事
    // const content = <div>
    //   <div>内容1</div>
    //   <div>内容2</div>
    //   <div>内容3</div>
    // </div>
    return <div class="b2c-tabs-container">{[nav, panels]}</div>
  }
}
</script>

<style lang="less" scoped>
.b2c-tabs-container {
  background: #fff;
  > nav {
    height: 60px;
    line-height: 60px;
    display: flex;
    border-bottom: 1px solid #f5f5f5;
    > a {
      width: 110px;
      border-right: 1px solid #f5f5f5;
      text-align: center;
      font-size: 16px;
      &.active {
        border-top: 2px solid @b2cColor;
        height: 60px;
        background: #fff;
        line-height: 56px;
      }
    }
  }
}
</style>

b2c-tabs-panel页

<template>
  <!-- 每个选项卡对应的内容 放在这里 -->
  <div class="b2c-tabs=panel">
    <slot/>
  </div>
</template>
<script>
export default {
  name: 'B2cTabsPanel',
  props: {
    label: { // 选项卡文字
      type: String,
      default: ''
    },
    name: { // 选项卡 唯一标识
      type: [String, Number],
      default: ''
    }
  }
}
</script>

<style>

</style>

如果 index页 有静态和动态遍历 创建的

<template>
  <div class="">我的订单
    <!-- <体验jsx语法 -->
    <!-- 引入选项卡组件,里面放默认插槽内容panel组件 -->
    <b2c-tabs>
      <!-- 静态 -->
      <b2c-tabs-panel label="选项卡" name="first">内容</b2c-tabs-panel>
      <!-- 动态遍历 -->
      <b2c-tabs-panel v-for="i in 4" :key="i" :label="`选项卡${i}`" :name="`name${i}`">内容{
   
   { i}}</b2c-tabs-panel>
    </b2c-tabs>
  </div>
</template>
<!-- jsx语法写,组件tabs-panel组件 -->
<script>
export default {
  name: 'B2cTabs',
  render () {
    // 需要在这里进行组织
    // 1.tabs组件大容器
    // 2.选项卡的导航菜单结构
    // 3.内容容器

    // 2.选项卡的导航菜单结构
    // 获取order/index页面 里b2c-tabs组件里的插槽内容  (几个panel组件)
    // label选项卡的文字,name选项卡的唯一标识,panels的长度就是选项卡的个数
    const panels = this.$slots.default()// panels就是 装着所有panel的面板,this是tabs组件
    // console.log(panels, 'panels')
    // 得到动态(v-for)生成的panels集合和静态生成的panels集合
    const dynamicPanels = []
    panels.forEach(item => {
      // 静态
      if (item.type.name === 'B2cTabsPanel') {
        dynamicPanels.push(item)
      } else { // 动态遍历的
        item.children.forEach(item => {
          dynamicPanels.push(item)
        })
      }
    })

    // 选项卡依赖于 order/index页面 里 panel组件的label
    const nav = <nav>
        {/* <a href="javascript:;">选项1</a>
        <a href="javascript:;">选项2</a>
        <a href="javascript:;">选项3</a> */}
        {
            dynamicPanels.map((panel, i) => <a href="javascript:;">{panel.props.label}</a>)
        }
    </nav>
    // 3.内容容器
    // 选项卡依赖于 order/index页面 里 b2c-tabs-panel组件的 插槽内容
    // 可以去这个组件里 写一个容器,比较省事
    // const content = <div>
    //   <div>内容1</div>
    //   <div>内容2</div>
    //   <div>内容3</div>
    // </div>
    return <div class="b2c-tabs-container">{[nav, dynamicPanels]}</div>
  }
}
</script>

<style lang="less" scoped>
.b2c-tabs-container {
  background: #fff;
  > nav {
    height: 60px;
    line-height: 60px;
    display: flex;
    border-bottom: 1px solid #f5f5f5;
    > a {
      width: 110px;
      border-right: 1px solid #f5f5f5;
      text-align: center;
      font-size: 16px;
      &.active {
        border-top: 2px solid @b2cColor;
        height: 60px;
        background: #fff;
        line-height: 56px;
      }
    }
  }
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_51290060/article/details/129882350