怎么利用Vue实现3个级别的联动?

codepen地址:http://codepen.io/JoeZheng2015/pen/qdKKer
问题描述:1、这段3个层次的联动,为什么全选级别的无法改变seller级别的;2、有其他更简洁的办法可以实现这种联动吗?

问题场景:
最近在学Vue,想利用computed简单的3中层级的联动,即当商品级别的全选,更改seller变量,seller级别的全选更改all变量这个联动。但是遇到问题:
在seller的for循环后,computed的get无法穿参,所以无法识别当前是哪个seller。
所以改用组件,每个seller有自己的作用域。但是现在又遇到问题:
全选级别的更改,无法触发商品级别的联动。

阅读 5.6k
2 个回答

通过绑定onchange事件,刚写出一个烫手的Beta版本 - 二层级结构的checkbox,基本满足题主的要求。

初期想法:对有子层级数据节点的checkbox进行事件绑定,否则通过v-model进行数据双向绑定

TODO:

  • 进行组件化

  • 实现多层级结构

Others:

  • 应该还有其他方法,希望分享你的想法和实现

  • 对此有什么问题或优化,欢迎指正和建议

build tree by array
http://stackoverflow.com/questions/18017869/build-tree-array-from-flat-array-in-javascript

make tree with template
http://stackoverflow.com/questions/11854514/is-it-possible-to-make-a-tree-view-with-angular

watch array selected property and change your toggleAll


改自官网的例子http://cn.vuejs.org/examples/tree-view.html

<!doctype html>
<html>
<head>
    <title>Vue Demo</title>
</head>
<body id="example">

    <!-- item template -->
    <script type="text/x-template" id="item-template">
        <li>
            <input type="checkbox" v-model="model.selected" />
            <div :class="{bold: isFolder}"
                 @click="toggle"
                 @dblclick="changeType">
                {{model.name}}
            </div>
            <ul v-if="isFolder">
                <item class="item"
                      v-for="model in model.children"
                      :model="model">
                </item>
            </ul>
        </li>
    </script>

    <p>(You can double click on an item to turn it into a folder.)</p>

    <!-- the demo root element -->
    <ul id="demo">
        <input type="checkbox" v-model="toggleAll" v-on:change="selectchange" />select all

        <item class="item"
              :model="getTree">
        </item>
    </ul>

    <script src="http://cdn.bootcss.com/vue/1.0.14/vue.js"></script>

    <script>

        // define the item component
        Vue.component('item', {
            template: '#item-template',
            props: {
                model: Object,
            },
            data: function () {
                return {
                    open: false
                }
            },
            computed: {
                isFolder: function () {
                    return this.model.children &&
                      this.model.children.length
                },
            },
            methods: {
                toggle: function () {
                    if (this.isFolder) {
                        this.open = !this.open
                    }
                },
                changeType: function () {
                    if (!this.isFolder) {
                        Vue.set(this.model, 'children', [])
                        this.addChild()
                        this.open = true
                    }
                },
                addChild: function () {
                    this.model.children.push({
                        name: 'new stuff'
                    })
                }
            }
        })

        // boot up the demo
        var demo = new Vue({
            el: '#demo',
            data: {
                nodes: [
                    { id: 1, name: 1, parentId: 0, selected: false, },
                    { id: 2, name: 2, parentId: 1, selected: false, },
                    { id: 3, name: 3, parentId: 2, selected: false, },
                ],
            },
            methods: {
                selectchange: function () {
                    var selectall = this.toggleAll;
                    this.nodes.forEach(function (seller) {
                        seller.selected = !selectall;
                    })
                },
            },
            computed: {
                getTree: function () {
                    var map = {}, node, roots = [];
                    for (var i = 0; i < this.nodes.length; i += 1) {
                        node = this.nodes[i];
                        node.children = [];
                        map[node.id] = i; // use map to look-up the parents
                        if (node.parentId !== 0) {
                            this.nodes[map[node.parentId]].children.push(node);
                        } else {
                            roots.push(node);
                        }
                    }
                    return roots[0];
                },
                toggleAll: function () {
                    var all = true;
                    this.nodes.forEach(function (seller) {
                        if (!seller.selected) all = false;
                    })
                    return all;
                },
            },
        })
    </script>


    <style>
        body {
            font-family: Menlo, Consolas, monospace;
            color: #444;
        }

        .item {
            cursor: pointer;
        }

        .bold {
            font-weight: bold;
        }

        ul {
            padding-left: 1em;
            line-height: 1.5em;
            list-style-type: dot;
        }
    </style>
</body>
</html>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题