<template>
  <div :style="{'padding-left': level*14+'px'}">
    <ul v-if="newData.length">
      <li v-for="(item, i) in newData" :key="i" @click.stop="selectItem(item)" v-show="expandFlag">
        <div class="item">
          <!-- 展开的图标 -->
          <i class='expandIcon'
             @click.stop="expandItem(item, i)"
             :class="[
                expandArr.includes(i) ? 'reduce' : 'add',
                item.children && item.children.length ? '' : 'disabled'
            ]">
          </i>
          <!-- 选项名 -->
          <p style="margin:10px">{{item[labelKey]}}</p>
          <!-- 选择的图标 -->
          <!--<i class='selectIcon'-->
          <!--   :class="[-->
          <!--        value[valueKey] == item[valueKey] ? 'checked' : 'noChecked',-->
          <!--         item[disabledKey] ? 'disabled' : ''-->
          <!--        ]">-->
          <!--</i>-->
        </div>
        <tree-index
            v-if='item.children'
            @input='input'
            :level="level+1"
            :newData='item.children'
            :valueKey='valueKey'
            :labelKey='labelKey'
            :disabledKey='disabledKey'
            :isBuy='isBuy'
            :value="value"
            :toastText='toastText'
            :expandFlag='expandArr.includes(i)'
        />
      </li>
    </ul>
  </div>
</template>
<script>
import { reactive, toRefs, onMounted } from 'vue'
import { Toast } from 'vant'
import { useRouter } from 'vue-router'

export default {
  // 组件名必写
  name: 'TreeIndex',
  props: {
    level: {
      type: String,
      default: 0,
    },
    // 选中的值的属性名,必传
    valueKey: {
      type: String,
    },
    // 在页面要展示的选项属性名,必传
    labelKey: {
      type: String,
    },
    // 不可选的唯一标识,如item[disabledKey]未true则不可选择,非必传
    disabledKey: {
      type: String,
    },
    isBuy: {
      type: String,
    },
    // 选中的值,必传
    value: {
      type: Object,
      default() {
        return {}
      },
    },
    // 控制展开,不需要传
    expandFlag: {
      type: Boolean,
      default: true,
    },
    // 总数据,必传
    newData: {
      type: Array,
      default() {
        return []
      },
    },
    // 不可选提示文字,非必传
    toastText: {
      type: String,
    },
  },
  setup(props) {
    onMounted(() => {
      console.log('---', data.newData)
    })
    const router = useRouter()
    const data = reactive({
      newData: props.newData,
      isBuy: props.isBuy,
      // 当前级组件已展开的项
      expandArr: [],
    })
    const method = {
      // 子组件逐级传递选中项
      input(item) {
        console.log(item)
        console.log(item.listen_switch)
        console.log(data.isBuy)
        if (item.listen_switch === 1) {
          /*console.log(item.mp4)*/
          /*router.push({ path: '/play',query: {src:item.mp4}})*/
          window.location.href = 'https://www.1zzx.com/yulan?files=' + item.mp4
        } else if (data.isBuy === 1) {
          /*console.log(item.mp4)*/
          /*router.push({ path: '/play',query: {src:item.mp4}})*/
          window.location.href = 'https://www.1zzx.com/yulan?files=' + item.mp4
        }
        // 首页需要树状
        else if (data.isBuy === 7) {
          console.log('首页')
        } else {
          Toast.fail('你还未购买该课程')
        }
        // this.$emit('input', item)
      },
      // 选择
      selectItem(item) {
        // industryDeptType为1表示时不可选择该工会
        if (this.disabledKey && item[this.disabledKey]) {
          if (this.toastText) {
            alert(this.toastText)
          }
          return
        }
        this.$emit('input', item)
      },
      // 展开
      expandItem(item, i) {
        if (item.children && item.children.length) {
          let index = this.expandArr.indexOf(i)
          if (index > -1) {
            this.expandArr.splice(index, 1)
          } else {
            this.expandArr.push(i)
          }
        }
      },
    }
    return { ...toRefs(data), ...method }
  },
}
<style scoped>
ul {
  width: 100%;
  color: #2a2a2a;
  font-size: 0.346667rem;
  overflow: hidden;
  background: #fff;
  border-bottom: 0.013333rem solid #e1e1e1;
}
ul li .item {
  padding: 0.186667rem 0.32rem;
  display: flex;
  align-items: center;
  width: 100%;
}
ul li .item .expandIcon {
  height: 0.453333rem;
  width: 0.453333rem;
  border: 0.02rem solid;
  border-radius: 50%;
  position: relative;
}
ul li .item .expandIcon:after {
  position: absolute;
  top: 51%;
  left: 50%;
  font-size: 0.47rem;
  transform: translate(-50%, -50%);
}
ul li .item .expandIcon.add {
  margin-left: 30px;
  border-color: #2a2a2a;
}
ul li .item .expandIcon.add:after {
  color: #2a2a2a;
  content: '+';
}
ul li .item .expandIcon.reduce {
  border-color: #ff6633;
  margin-left: 30px;
}
ul li .item .expandIcon.reduce:after {
  color: #ff6633;
  content: '-';
}
ul li .item .expandIcon.disabled {
  border-color: #ddd;
}
ul li .item .expandIcon.disabled:after {
  color: #ddd;
}
ul li .item .selectIcon {
  height: 0.453333rem;
  width: 0.453333rem;
  border: 0.02rem solid;
  border-radius: 50%;
  position: relative;
}
ul li .item .selectIcon:after {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
ul li .item .selectIcon.checked {
  border-color: #ff6633;
  background: #ff6633;
}
ul li .item .selectIcon.checked:after {
  font-size: 0.32rem;
  color: #fff;
  content: '✓';
}
ul li .item .selectIcon.noChecked {
  border-color: #ff6633;
}
ul li .item .selectIcon.disabled {
  border-color: #ddd;
}
ul li .item h1 {
  margin-right: 0.08rem;
  padding: 0 0.213333rem;
  position: relative;
  top: 0.026667rem;
  height: 0.8rem;
  line-height: 0.8rem;
  font-size: 0.4rem;
  flex: 1;
  white-space: nowrap;
  color: #2a2a2a;
  overflow-x: auto;
}
ul li:not(:first-child) {
  border-top: 0.013333rem solid #e1e1e1;
}
ul li > ul {
  border-bottom: 0;
  padding-left: 0.8rem;
}
ul li > ul li .item {
  padding-left: 0.16rem;
}
ul li > ul li {
  border-top: 0.013333rem;
}
</style
你好 我有如下代码 请帮我用vue3 移动端转化为vue2 uniapptemplatediv style=padding-left level14+px ul v-if=newDatalength li v-for=item i in newData key=i clickstop=selectItemitem v-show=expandFlag div class

原文地址: https://www.cveoy.top/t/topic/gAC0 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录