我正在学习Vue.js.我喜欢它轻巧。我正在创建一个用户界面,其中有“设备”对象。每个设备都有输入和输出,可以通过mDevice.inputs或mDevice.outputs访问。输入和输出是具有输入/输出名称,id和类型的对象列表。
设备在屏幕上显示为div,在div上有文本“Inputs”和“Outputs”。可以将鼠标悬停在这些标签上,并显示mDevice.inputs和mDevice.outputs。这是那部分:
<div v-on:mouseover="device.showInputs = !device.showInputs">inputs</div>
<ul class="io-list" v-if="device.showInputs">
<li v-for="(e, idx) in device.inputs">
{{e.id}} - {{ e.the_type }}
<div
v-on:mouseover="e.showAvailableOutputs = !e.showAvailableOutputs"
class="xpull-right" style="display:inline;font-size:1.5em;">»</div>
<ul class="sub-io-list" v-if="e.showAvailableOutputs"
v-on:mouseleave="e.showAvailableOutputs = !e.showAvailableOutputs">
<li style="white-space:nowrap" v-for="io in setupOutputs">
({{io.device.model}}) - {{io.the_type}}
</li>
</ul>
</li>
</ul>
<div v-on:mouseover="device.showOutputs = !device.showOutputs">outputs</div>
<ul class="io-list" v-if="device.showOutputs">
<li v-for="(e, idx) in device.outputs">
{{e.id}} - {{ e.the_type }}
<div
v-on:mouseover="e.showAvailableInputs = !e.showAvailableInputs"
class="xpull-right" style="display:inline;font-size:1.5em;">»</div>
<ul class="sub-io-list" v-if="e.showAvailableInputs"
v-on:mouseleave="e.showAvailableInputs = !e.showAvailableInputs">
<li style="white-space:nowrap" v-for="io in setupInputs">
({{io.device.model}}) - {{io.the_type}}
</li>
</ul>
</li>
</ul>
列表是多级的(2)。这里有重复,我想抽象。
我试过了:
<template v-for="x in ['inputs','outputs']">
<div v-on:mouseover="toggleShowIOs(device,x, false)">{{x}}</div>
<ul class="io-list" v-if="showIOs(device, x, false)">
<li v-for="(e, idx) in device[x]">
{{e.id}} - {{ e.the_type }}
<div
v-on:mouseover="toggleShowIOs(e,x, true)"
class="xpull-right" style="display:inline;font-size:1.5em;">»</div>
<ul class="sub-io-list" v-if="showIOs(e,x,true)"
v-on:mouseleave="toggleShowIOs(e,x, true)">
<li style="white-space:nowrap" v-for="io in setupOutputs">
({{io.device.model}}) - {{io.the_type}}
</li>
</ul>
</li>
</ul>
</template>
但是当传递给函数toggleShowIOs时,似乎x(天气是'输入'或'输出')不会持续存在。我在想,因为我没有在我的vue实例的data属性中声明它。
抽象这种创建多级菜单的最简单方法是什么?我是在正确的轨道上吗?我正在考虑创建一个组件。
还有一个问题,在数据或道具属性中放置函数有多糟糕?
编辑: 好吧,我想我越来越接近这个了。这就是我现在所拥有的:
Vue.component('hover-menu', {
template: '#hover-menu-template',
props: ['label','menuItems'],
data : function() {
return {
show: false,
}
},
methods: {
flipAndEmit: function() {
this.show = !this.show;
this.$emit('flipAndEmit');
}
}
});
模板:
<template id="hover-menu-template">
<div v-on:mouseover="flipAndEmit" v-on:mouseleave="flipAndEmit">
<div>{{ label }} » </div>
<ul v-if="show" style="display:inline;background-color:#5BE;">
<li is="hover-menu"
v-for="(item, index) in menuItems"
v-bind:label="item.id"
v-bind:menu-items="menuItems"></li>
</ul>
</div>
</template>
<hover-menu label="Inputs" :menu-items="device.inputs"></hover-menu>
<hover-menu label="Outputs" :menu-items="device.outputs"></hover-menu>
控制仍然不稳定,但我认为这是现在的答案。一旦它全部工作,我将在这里发布答案。如果你们中的任何人打败我,那就更好了。
答案 0 :(得分:0)
终于明白了。我使用了Vue.js文档中的文件夹树示例来指导我。这是模板和html:
<template id="menu-template">
<div>
<div>{{menu.name}}
<span v-if="menu.options.length > 0" v-on:mouseenter="showOptions = !showOptions">>></span>
<span v-else v-on:click="selectOption">OK</span>
</div>
<menu-children :options="menu.options" v-if="showOptions" v-on:went-out="showOptions = !showOptions"></menu-children>
</div>
</template>
<template id="menu-options-template">
<ul class="list" v-on:mouseleave="sendUp">
<li v-for="choice in options">
<amenu-parent v-if="choice.options" :menu="choice"></amenu-parent>
<span v-else>{{ choice.name }}</span>
</li>
</ul>
</template>
<div id="app">
<div v-for="r in root">
<amenu-parent :menu="r"></amenu-parent>
</div>
</div>
这是js:
Vue.component('amenu-parent', {
template: "#menu-template",
props: ['menu'],
data: function() {
return {
showOptions: false,
}
},
methods: {
selectOption: function(v) {
alert('clicked');
}
}
});
Vue.component('menu-children', {
template: "#menu-options-template",
props: ['options'],
methods: {
sendUp: function() {
this.$emit("went-out");
}
}
});
var app = new Vue({
el: "#app",
data: {
root: [{
name: 'a',
options: [{
name: '1',
options: []
}, {
name: 'asdf',
options: [{
name: 'deep',
options: []
}]
}]
}, {
name: 'number2',
options: [{
name: 'deep',
options: []
}]
}]
},
});
还有一些css:
body {
font-size:1.8em;
}
.list > li {
background-color:#EEE;
width:300px;
}