index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <div class="bg-[#fff]" :class="{'border-b-[2px] border-b-[var(--el-color-primary)] border-solid':navShow}">
  3. <div class="flex items-center w-[1200px] mx-auto h-[46px] leading-[46px] bg-[#fff]" >
  4. <div class="category w-[200px] bg-[var(--el-color-primary)] text-[#fff] text-center cursor-pointer text-[16px] leading-[46px] relative " @mouseleave.stop="handleOut($event)" @mouseover.stop="subMenuClick($event)">
  5. <span>商品分类</span>
  6. <div class="category-popup absolute top-[46px] left-0 z-9 flex" :class="{'hidden':hidden}">
  7. <div class="w-[200px] box-border h-[520px] overflow-y-auto text-[14px] bg-[rgba(51,51,51,.9)]" >
  8. <template v-for="(item,index) in categoryList" :key="index">
  9. <div class="h-[40px] flex items-center justify-between px-[20px] box-border cursor-pointer text-[#fff]" @click.stop="toGoodsList(item.category_id)" :class="`index${index}`">
  10. <span class="w-[140px] text-left truncate">{{item.category_name}}</span>
  11. <span class="iconfont icon-fanhui text-[#fff] !text-[10px]"></span>
  12. </div>
  13. </template>
  14. </div>
  15. <div class="box-border w-[1000px] bg-[#fff] pt-[20px] text-[#333]" :class="{'hidden': !rightShow}" >
  16. <template v-for="(subItem,subIndex) in categoryList[tabActive]?.child_list" :key="subIndex">
  17. <div>
  18. <div class="px-[20px] text-[14px] text-[#333] !leading-[20px] cursor-pointer text-left mb-[30px]" :class="{'mb-[10px]': !subItem.child_list }" @click.stop="toGoodsList(subItem.category_id)">{{subItem.category_name}}</div>
  19. <div class="flex-1 flex flex-wrap">
  20. <template v-for="(grandItem,grandIndex) in subItem.child_list" :key="grandIndex">
  21. <div class="flex items-center cursor-pointer px-[20px] mb-[30px]" @click.stop="toGoodsList(grandItem.category_id)">
  22. <div class="h-[60px] flex-shink-0 mr-[10px]">
  23. <el-image class="w-[60px] h-[60px] " :src="img(grandItem.image)" fit="contain">
  24. <template #error>
  25. <div class="image-slot">
  26. <img class="w-[60px] h-[60px]" src="@/assets/images/nav/default_category.png" />
  27. </div>
  28. </template>
  29. </el-image>
  30. </div>
  31. <div class="text-[14px] text-[#999] text-left w-[140px] h-[60px] leading-[60px] truncate">{{grandItem.category_name}}</div>
  32. </div>
  33. </template>
  34. </div>
  35. </div>
  36. </template>
  37. </div>
  38. </div>
  39. </div>
  40. <div class="px-20px flex item-center flex-1 overflow-x-auto">
  41. <template v-for="(item,index) in navList" :key="index" >
  42. <div class="px-[20px] text-[#333] text-[16px] leading-[46px] cursor-pointer" :class="{'!text-[var(--el-color-primary)]':activeName == item.nav_url}" @click="handleClick(item)">{{ item.nav_title }}</div>
  43. </template>
  44. </div>
  45. </div>
  46. </div>
  47. </template>
  48. <script setup lang="ts">
  49. import { ref,reactive, watch} from "vue";
  50. import { isUrl } from '@/utils/common'
  51. import { getCategoryTree,getNavList } from '@/app/api/index'
  52. import { useRouter, useRoute } from 'vue-router'
  53. const router = useRouter()
  54. const route = useRoute()
  55. const activeName = ref('')
  56. const navList = ref([])
  57. // 获取导航链接
  58. const getNavListFn = () =>{
  59. getNavList().then(res=>{
  60. navList.value = res.data
  61. navList.value.forEach(item =>{
  62. if(item.nav_url && item.nav_url.url){
  63. if(route.path == item.nav_url.url){
  64. activeName.value = item.nav_url
  65. }
  66. }
  67. })
  68. })
  69. }
  70. getNavListFn()
  71. const handleClick = (item) => {
  72. activeName.value = item.nav_url
  73. if (item.nav_url && item.nav_url.url) {
  74. if(isUrl(item.nav_url.url)){
  75. window.open(item.nav_url.url)
  76. }else{
  77. if (item.is_blank == 1) {
  78. const url = router.resolve({
  79. path: item.nav_url.url
  80. })
  81. window.open(url.href)
  82. } else {
  83. router.push({ path: item.nav_url.url })
  84. }
  85. }
  86. }
  87. }
  88. // 一级菜单样式控制
  89. const tabActive = ref(0)
  90. const categoryList = ref([])
  91. const getCategoryTreeFn = () => {
  92. getCategoryTree().then(res => {
  93. categoryList.value = res.data
  94. })
  95. }
  96. getCategoryTreeFn()
  97. // 是否展示商品全部分类
  98. let hidden = ref(true)
  99. // 控制右侧展示
  100. const rightShow = ref(false)
  101. const subMenuClick = (event) =>{
  102. hidden.value = false
  103. if(event.target.className.indexOf('index') !== -1){
  104. let data = event.target.className.split('index')
  105. tabActive.value = Number(data[1])
  106. if(!rightShow.value) rightShow.value = true
  107. }
  108. }
  109. const handleOut = (event)=>{
  110. rightShow.value = false
  111. hidden.value = true
  112. }
  113. // 去详情
  114. const toGoodsList = (id) =>{
  115. hidden.value = true
  116. rightShow.value = false
  117. router.push({path:'/goods/list',query:{goods_mall_category:id}})
  118. }
  119. let navShow = ref(false)
  120. watch(()=> router.currentRoute.value.path ,(newValue)=>{
  121. if(router.currentRoute.value.path == '/' ){
  122. navShow.value = false
  123. activeName.value = ''
  124. }else{
  125. navShow.value = true
  126. }
  127. },{immediate:true,deep: true})
  128. </script>
  129. <style lang="scss" scoped>
  130. .bg-color{
  131. background-color: rgba(0,0,0,.4);
  132. }
  133. :deep(.popover-box){
  134. top:200px !important;
  135. }
  136. </style>