递归实现菜单导航
**1. 递归组件**
```
{{ title }}
v-for="(item, idx) in children"
:key="idx"
:index="index + '-' + idx"
:title="item.title"
:children="item.children"
:options="item.options"
:prefix="prefix"
@naf-menu-item="$emit('naf-menu-item', $event)"
>
>
{{ title }}
{{ title.length > 9 ? title.substr(0, 9) + '...' : title }}
export default {
name: 'naf-menu-item',
props: {
title: String,
index: String,
options: Object,
children: Array,
prefix: { type: String, default: '' },
},
methods: {
menuClick() {
console.debug('click menu item....');
if (this.options.url) {
window.open(this.options.url, this.options.target);
} else if (this.options.path) {
const to = `${this.prefix}${this.options.path}`;
if (to != (this.$route && this.$route.path)) {
this.$router.push(to);
} else {
this.$emit('naf-menu-item', this.options);
}
}
},
},
computed: {
hasChildren() {
return this.children && this.children.length > 0;
},
hasIcon() {
return this.options.icon && this.options.icon.length > 0;
},
hasTooltip() {
return this.options.tooltip && this.options.tooltip.length > 0;
},
iconCls() {
if (this.options.icon && !(this.options.icon.indexOf('el-') === 0)) {
return `naf-icons naf-icon-${this.options.icon}`;
}
return this.options.icon;
},
},
};
```
2. 使用递归组件
```
v-for="(item, idx) in menuItems"
:key="idx"
:index="idx.toString()"
:title="item.title"
:options="item.options"
:children="item.children"
:target="item.target"
:prefix="routerPrefix"
@naf-menu-item="$emit('naf-menu-item', $event)"
>
import NafMenuItem from './menu-item';
export default {
components: {
NafMenuItem,
},
props: {
theme: String,
isCollapse: Boolean,
menuItems: Array,
routerPrefix: { type: String, default: '' },
},
data() {
return {
msg: 'Use Vue 2.0 Today!',
// menus,
};
},
// mounted: function() {
// this.$nextTick(_ => {
// // Code that will run only after the
// // entire view has been rendered
// this.$refs.menu.open('0');
// });
// },
computed: {
// 计算属性的 getter
themeStyles() {
// `this` 指向 vm 实例
if (this.theme === 'dark') {
// dark styles
return {
backgroundColor: '#545c64',
textColor: '#fff',
activeTextColor: '#ffd04b',
};
}
// default styles
return {
backgroundColor: undefined,
textColor: undefined,
activeTextColor: undefined,
};
},
backgroundColor() {
return this.isCollapse ? '' : 'transparent';
},
},
};
```