【问题标题】:Treeview with nested inputs with VueJS带有 VueJS 的嵌套输入的 Treeview
【发布时间】:2017-05-28 05:28:42
【问题描述】:

我正在尝试构建一个树视图组件来比较输入以更改我的源 json。

绑定部分似乎工作正常,但分支上的隐藏/显示操作被破坏:

HTML:

<div id="app">
  <tree :data="json" :link="json"></tree>

  <p>Outside component :</p>
  <pre>{{json}}</pre>
</div>

JS:

let json = {
  nodeA: {
    nodeA1 : "valueA1",
    nodeA2 : "valueA2"
  },
  nodeB: "valueB",
  nodeC: {
    nodeC1 : "valueC1",
    nodeC2 : "valueC2"
  }
};

Vue.component('tree', {
  name: 'treeview',
  props: [
    'data', 
    'link'
  ],
  template: `<ul>
        <li v-for="(val, key) in data">
            <input type="text" v-if="isLeaf(val)" v-model=link[key]>
            <span @click="toggle">{{key}}</span>
            <tree v-if="!isLeaf(val)" v-show="show" :data="val" :link="link[key]">
            </tree>
        </li>
    </ul>`,
  data: function() {
    return {
      show: false
    };
  },
  methods: {
    isLeaf: function(node) {
      return typeof node != 'object';
    },
    toggle: function() {
      this.show = !this.show;
    }
  }
});

new Vue({
  el: '#app',
  data: {
    json: json
  }
});

https://codepen.io/anon/pen/EZKBwL

如您所见,单击第一个分支(“nodeA”)会同时激活第一个和第三个分支...

我认为问题出在父组件上发生的点击,但我找不到修复代码的方法。

【问题讨论】:

    标签: javascript vue-component vuejs2 vue.js


    【解决方案1】:

    这是因为您将所有元素绑定到同一个参数。

    要单独切换每个元素的可见性,您需要将元素状态存储在它自己的位置,例如对象的字段或数组。

    但我想更好的解决方案是通过单击在目标元素上切换类并通过 css 通过类控制可见性。

    【讨论】:

      【解决方案2】:

      当您使用单个变量 show 隐藏和显示这两个时,您的所有分支都隐藏/显示在一起,您必须为每个节点使用不同的变量。

      拥有与节点数量一样多的变量是不切实际的,但您可以使用如下哈希:

        data: function() {
          return {
            show: {}
          };
        },
      

      并更改切换方法以通过在此show 散列中为该节点创建一个键来为每个节点设置变量。您可以使用vm.$set 来设置对象的属性。如果对象是响应式的,请确保将属性创建为响应式属性并触发视图更新。

      toggle: function(node) {
        if(this.show[node]){
          this.$set(this.show, node, false)
        } else {
          this.$set(this.show, node, true)
        }
      } 
      

      您还需要在HTML中做相应的更改,可以在工作codepen中查看here

      【讨论】:

      • 简单但高效 :) 此外,是否有比将链接作为道具传递更好的解决方案将嵌套输入与源 JSON 绑定?
      • @Pourpre 如果你问的是 props 的替代方案,你可以使用 vuex,如果它适合你的要求,你可以查看docs 或我的答案herehere
      【解决方案3】:

      您可能需要每个节点的show 字段来分别切换它们的可见性,在我的improved example 中,我使用的是这样的数据结构:

      {
          "nodeA": {
              "value": {
                  "nodeA1": {
                      "value": "valueA1",
                      "show": false
                  },
                  "nodeA2": {
                      "value": "valueA2",
                      "show": false
                  }
              },
              "show": true
          },
          "nodeB": {
              "value": "valueB",
              "show": true
          }
      }
      

      我的模板:

      <ul>
          <li v-for="(val, key) in data" v-show='val.show'>
              <input type="text" v-if="isLeaf(val)" v-model='link[key].value'>
              <span @click="toggle(val.value)">{{key}}</span>
              <tree v-if="!isLeaf(val)" :data="val.value" :link="val.value">
              </tree>
          </li>
      </ul>
      

      方法:

      {
          isLeaf: function(node) {
              return typeof node.value != 'object';
          },
          toggle: function(value) {
              for (const nodeName in value) {
                  value[nodeName].show = !value[nodeName].show;
              }
          }
      }
      

      【讨论】:

      • 这个解决方案是功能性的,但需要对源 JSON 进行重大更改,这是不需要的。谢谢你的提议。
      猜你喜欢
      • 2018-02-10
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2011-07-15
      • 2017-07-10
      • 1970-01-01
      • 2021-09-07
      相关资源
      最近更新 更多