繁体   English   中英

如何抽象以下模式? (使用Vue.js)

[英]How can I abstract the following pattern? (using Vue.js)

我正在学习Vue.js。 我喜欢它很轻巧。 我正在创建一个有“设备”对象的用户界面。 每个设备都有输入和输出,可以通过mDevice.inputs或mDevice.outputs访问。 输入和输出是对象本身的列表,其中包含输入/输出名称,id和类型。

设备在屏幕上以div形式显示,并且在div上有文本“输入”和“输出”。 可以将鼠标悬停在这些标签上,并显示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>

控件仍然很不稳定,但是我认为这是目前的答案。 一旦一切正常,我将在这里发布答案。 如果你们中有人击败我,那就更好了。

终于想通了。 我使用了Vue.js文档中的文件夹树示例来指导我。 这是模板和html:

<template id="menu-template">
  <div>
  <div>{{menu.name}}
    <span v-if="menu.options.length > 0" v-on:mouseenter="showOptions = !showOptions">&gt;&gt;</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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM