【问题标题】:Output nested array properly正确输出嵌套数组
【发布时间】:2017-07-18 01:00:16
【问题描述】:

我尝试使用组件在 Vue 中构建数据树。

考虑以下数据:

"data": [
{
  "id": 1,
  "name": "foo",
  "children": [
    {
      "id": 2,
      "name": "bar",
      "children": []
    },
    {
      "id": 3,
      "name": "hulu",
      "children": []
    }
  ]
},
{
  "id": 4,
  "name": "foobar",
  "children": [
    {
      "id": 5,
      "name": "foobar hulu",
      "children": []
    }
  ]
}]

现在我想用如下表格输出它:

ID ║ 名称 ║ 路径
1 ║ 富 ║ /富
2 ║ 酒吧 ║ /foo/bar
3 ║ 葫芦 ║ /foo/hulu
4 ║ foobar ║ /foobar
5 ║ foobar 葫芦 ║ /foobar/foobar 葫芦

如果有可用的子级,我尝试使用“调用”自身的组件。问题是 Vue.js 只允许一个根元素。

我的组件:

var Element = {
    props: ['context', 'path'],
    name: 'self',
    template: `
        <tr>
            <td>{{context.id}}</td>
            <td>{{context.name}}</td>
            <td>{{path}}</td>
        </tr>
        <self v-if="context.children.length != 0" v-for="child in context.children" :context="child" :path="path + '/' + child.name"></self>
    `
};

var Tree = {
    components: {
        'element': Element
    },
    template: `
        <table v-if="elements.length != 0">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Path</th>
                </tr>
            </thead>

            <element v-for="element in elements" :context="element" :path="'/' + element.name"></element>
        </table>
    `,

你会如何绕过这个问题?我尝试将元素模板包装在 tbody 中。这将正确计算路径并输出所有元素,但是这会产生嵌套在列中的行并且看起来非常难看。

有什么想法吗?

【问题讨论】:

    标签: javascript html vue.js vuejs2


    【解决方案1】:

    平整路径。

    Vue.component("flat-tree",{
      props:["paths"],
      template: "#flat-tree-template",
      methods:{
        flatten(data, root, accumulator){
          return data.reduce((acc, val) => {
            accumulator.push({
              id: val.id,
              name: val.name,
              path: root + val.name
            });
            if (val.children)
              return this.flatten(val.children, root + val.name + "/", accumulator);
            else
              return accumulator;
          }, accumulator);
        }
      },
      computed:{
        flattened(){
          return this.flatten(this.paths, "/", []);
        }
      }
    })
    

    模板

    <template id="flat-tree-template">
      <table>
        <tr v-for="path in flattened">
          <td>{{path.id}}</td>
          <td>{{path.name}}</td>
          <td>{{path.path}}</td>
        </tr>
      </table>
    </template>
    

    Working example.

    【讨论】:

    • 太棒了!不幸的是,您的 codepen 不起作用,但我自己想通了。为什么要使用计算属性来输出数据? v-for="flatten(paths, '/', [])" 不一样吗?
    • @Qobus 我玩了一段时间的codepen,所以你可能在它处于错误状态时点击了链接;道歉。它现在应该可以工作了。我正在使用计算属性,因为展平的路径是从原始路径派生的。通过使用计算,如果原始路径发生变化,将重新计算扁平路径并反映新状态。
    • @Qobus 通常看起来更干净,至少对我来说是这样。你是对的,v-for="path in flatten(paths, '/', [])" 会完成几乎相同的事情。
    猜你喜欢
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多