封装修改完成header头部导航栏组件为动态tree渲染
This commit is contained in:
parent
3a561a504e
commit
e2e5e73d04
97
components/header-nav.vue
Normal file
97
components/header-nav.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div
|
||||
class="h-100"
|
||||
:class="level === 0 ? 'd-flex align-items-center' : ''"
|
||||
>
|
||||
<div
|
||||
v-for="(item,index) in nodes"
|
||||
:key="index"
|
||||
class="nav-link-item d-flex align-items-center justify-content-center"
|
||||
>
|
||||
<nuxt-link
|
||||
:to="item.to"
|
||||
v-if="item.children.length === 0"
|
||||
>
|
||||
{{ item.label }}
|
||||
</nuxt-link>
|
||||
<b-nav-item-dropdown
|
||||
v-else
|
||||
:id="item.id"
|
||||
:text="item.label"
|
||||
right
|
||||
@show="isDropdown=true"
|
||||
v-model="isDropdown"
|
||||
@hide="dropdownHide($event, item)"
|
||||
>
|
||||
<header-nav
|
||||
:nodes="item.children"
|
||||
:level="level + 1"
|
||||
/>
|
||||
</b-nav-item-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'HeaderNav',
|
||||
props: {
|
||||
level: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
nodes: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDropdown: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
dropdownHide(e, item) {
|
||||
if (this.isDropdown) {
|
||||
e.preventDefault()
|
||||
this.isDropdown = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@mixin activeNav {
|
||||
&:hover {
|
||||
position: relative;
|
||||
color: #015fe8;
|
||||
background: linear-gradient( 180deg, rgba(1,95,232,0) 0%, rgba(1,95,232,0.08) 100%);
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: .125rem;
|
||||
background: #015fe8;
|
||||
}
|
||||
>a {
|
||||
color: #015fe8;
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-link-item {
|
||||
height: 100%;
|
||||
padding: 0 1.4375rem;
|
||||
>a {
|
||||
color: #151516;
|
||||
}
|
||||
@include activeNav;
|
||||
}
|
||||
.active-item {
|
||||
@include activeNav;
|
||||
}
|
||||
|
||||
</style>
|
@ -4,14 +4,7 @@
|
||||
<img src="~assets/image/logo.png" width="265px" :alt="$t('index.corporateName')">
|
||||
|
||||
<nav class="d-md-flex align-items-center">
|
||||
<nuxt-link
|
||||
class="nav-link-item d-flex align-items-center"
|
||||
:to="item.href"
|
||||
v-for="(item,index) in menuList"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.name }}
|
||||
</nuxt-link>
|
||||
<HeaderNav :nodes="menuTree" />
|
||||
</nav>
|
||||
|
||||
<div class="search-box">
|
||||
@ -48,11 +41,11 @@
|
||||
<nav class="mob-nav hide_scroll_bar d-flex align-items-center">
|
||||
<nuxt-link
|
||||
class="nav-link-item d-flex align-items-center"
|
||||
:to="item.href"
|
||||
v-for="(item,index) in menuList"
|
||||
:to="item.to"
|
||||
v-for="(item,index) in menuTree"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.name }}
|
||||
{{ item.label }}
|
||||
</nuxt-link>
|
||||
</nav>
|
||||
</header>
|
||||
@ -62,23 +55,32 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import MenuDrawer from './menu-drawer.vue';
|
||||
import HeaderNav from './header-nav.vue';
|
||||
|
||||
export default {
|
||||
components: { MenuDrawer },
|
||||
components: {
|
||||
MenuDrawer,
|
||||
HeaderNav
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchVal: '',
|
||||
menuList: [
|
||||
{ name: this.$t('menu.Home'), href: '/' },
|
||||
{ name: this.$t('menu.AboutUs'), href: '/abou-us' },
|
||||
{ name: this.$t('menu.Products'), href: '/products' },
|
||||
{ name: this.$t('menu.News'), href: '/news' },
|
||||
{ name: this.$t('menu.Exhibition'), href: '/exhibition' },
|
||||
{ name: this.$t('menu.ContactUs'), href: '/contact-us' },
|
||||
{ name: this.$t('menu.Feedback'), href: '/feedback' },
|
||||
]
|
||||
// menuList: [
|
||||
// { name: this.$t('menu.Home'), href: '/' },
|
||||
// { name: this.$t('menu.AboutUs'), href: '/abou-us' },
|
||||
// { name: this.$t('menu.Products'), href: '/products' },
|
||||
// { name: this.$t('menu.News'), href: '/news' },
|
||||
// { name: this.$t('menu.Exhibition'), href: '/exhibition' },
|
||||
// { name: this.$t('menu.ContactUs'), href: '/contact-us' },
|
||||
// { name: this.$t('menu.Feedback'), href: '/feedback' },
|
||||
// ]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['menuTree'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -110,38 +112,8 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
@mixin activeNav {
|
||||
&:hover {
|
||||
position: relative;
|
||||
color: #015fe8;
|
||||
background: linear-gradient( 180deg, rgba(1,95,232,0) 0%, rgba(1,95,232,0.08) 100%);
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: .125rem;
|
||||
background: #015fe8;
|
||||
}
|
||||
>a {
|
||||
color: #015fe8;
|
||||
}
|
||||
}
|
||||
}
|
||||
nav {
|
||||
height: 100%;
|
||||
.nav-link-item {
|
||||
height: 100%;
|
||||
padding: 0 1.4375rem;
|
||||
>a {
|
||||
color: #151516;
|
||||
}
|
||||
@include activeNav;
|
||||
}
|
||||
.active-item {
|
||||
@include activeNav;
|
||||
}
|
||||
}
|
||||
.header-box {
|
||||
width: 100%;
|
||||
|
4
env.js
4
env.js
@ -8,8 +8,8 @@ module.exports = {
|
||||
// 开发环境 接口请求地址 (http)或(https)://www.a.com(换成你的域名)/api
|
||||
dev: {
|
||||
MODE: 'dev',
|
||||
// VUE_APP_API_URL: 'http://122.51.230.86:8099/',
|
||||
VUE_APP_API_URL: 'http://192.168.1.4:8099/',
|
||||
VUE_APP_API_URL: 'http://122.51.230.86:8099/',
|
||||
// VUE_APP_API_URL: 'http://192.168.1.4:8099/',
|
||||
VUE_APP_WEBSOCKET: 'ws://localhost:8099/ws/asset/'
|
||||
},
|
||||
// 生产环境 接口请求地址 (http)或(https)://www.a.com(换成你的域名)/api 非独立部署默认为空
|
||||
|
7
middleware/header.js
Normal file
7
middleware/header.js
Normal file
@ -0,0 +1,7 @@
|
||||
export default async function ({
|
||||
$axios,
|
||||
store
|
||||
}) {
|
||||
const menuTree = await $axios.$get('/web/category')
|
||||
store.commit('SET_MENU_TREE', menuTree)
|
||||
}
|
@ -78,7 +78,7 @@ export default {
|
||||
icons: false
|
||||
},
|
||||
router: {
|
||||
middleware: ['i18n', 'footer']
|
||||
middleware: ['i18n', 'footer', 'header']
|
||||
},
|
||||
/*
|
||||
** Build configuration
|
||||
|
17369
package-lock.json
generated
17369
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,14 @@
|
||||
const routeMap = {
|
||||
'dym': 'separate', // 单页面
|
||||
'xp': 'inquiry', // 询盘栏目
|
||||
'wz': 'article', // 文章栏目
|
||||
'cp': 'product' // 产品栏目
|
||||
}
|
||||
|
||||
export const state = () => ({
|
||||
locales: ['en', 'zh'],
|
||||
locale: 'en',
|
||||
menuTree: [],
|
||||
footerInfo: {}
|
||||
})
|
||||
|
||||
@ -12,6 +20,25 @@ export const mutations = {
|
||||
},
|
||||
SET_FOOTER_INFO (state, info) {
|
||||
state.footerInfo = info
|
||||
},
|
||||
SET_MENU_TREE (state, tree) {
|
||||
state.menuTree = [
|
||||
{label:'Home', to: '/', children: []}
|
||||
]
|
||||
const fn = (list) => {
|
||||
list.forEach(item => {
|
||||
if (item.catgLevel===1) {
|
||||
item.to = `/${routeMap[item.catgType]}?catgId=${item.id}`
|
||||
} else {
|
||||
item.to = `/${routeMap[item.catgType]}/${item.id}?catgId=${item.maxParentId}`
|
||||
}
|
||||
if (item.children.length) {
|
||||
fn(item.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
fn(tree)
|
||||
state.menuTree = [...state.menuTree, ...tree]
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user