更新Vue.js中的嵌套父类

时间:2017-06-19 21:55:44

标签: javascript vue.js vuejs2

我每次尝试将一个类添加到父容器中时,#34; advanced"单击链接。

所以使用jQuery我会写一些像..

$(this).closest('.row').addClass('overlay');

$(this).closest('section').addClass('overlay');

但是,似乎与Vue有点复杂,只是将一个类添加到被单击的项的父容器中。我确信有更简单的方法可以解决这个问题。

以下是我的代码示例。

<div id="app">
    <section v-bind:class="{ overlay: i == sectionActive && rowActive == null }" v-for="(section, i) in sections">
        <a href="#0" @click.prevent="toggleAdvanced(i)">Advanced</a>

        <div class="advanced-fields" v-bind:class="{ overlay: i == sectionActive && rowActive == null }">
            <fieldset>
                <label>
                    ID
                    <input type="text" name="section[id]" v-model="section.id">
                </label>
            </fieldset>
            <fieldset>
                <label>
                    Class
                    <input type="text" name="section[css_class]" v-model="section.css_class">
                </label>
            </fieldset>
        </div>

        <div class="row" v-bind:class="{ overlay: i == sectionActive && row_i == rowActive }" v-for="(row, row_i) in section.rows">
            <a href="#0" @click.prevent="toggleRowAdvanced(section, row)">Advanced</a>

            <div class="advanced-fields" v-bind:class="{ overlay: i == sectionActive && row_i == rowActive }">
                <fieldset>
                    <label>ID</label>
                    <input type="text" name="" v-model="row.id">
                </fieldset>
                <fieldset>
                    <label>CSS Class</label>
                    <input type="text" name="" v-model="row.css_class">
                </fieldset>
            </div>
        </div>
    </section>

    <pre>{{ $data }}</pre>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        "sections": [{
            "id": "section-1",
            "css_class": "",
            "rows": [{
                "id": "",
                "css_class": ""
            }, {
                "id": "",
                "css_class": ""
            }]
        }, {
            "id": "section-2",
            "css_class": '',
            "rows": [{
                "id": "",
                "css_class": ""
            }]
        }],
        sectionActive: null,
        rowActive: null,
        columnActive: null
    },
    methods: {
        toggleAdvanced: function(index) {
            this.sectionActive = this.sectionActive === index ? null : index;
            this.rowActive = null;
            this.columnActive = null;
        },
        toggleRowAdvanced: function(section, row) {
            var sectionIndex = this.sections.indexOf(section);
            var rowIndex = section.rows.indexOf(row);

            this.sectionActive = this.sectionActive === sectionIndex ? null : sectionIndex;
            this.rowActive = this.rowActive === rowIndex ? null : rowIndex;
        }
    }
});
</script>

我需要为列做同样的事情,但正如你所看到的,它变得过于复杂。关于如何简化这个的任何想法?

我知道将数据属性添加到每一行会更容易,但我将哈希值保存到数据库中,并且不想仅为UI切换添加不必要的数据。

https://jsfiddle.net/ferne97/4jbutbkz/

1 个答案:

答案 0 :(得分:1)

我采用了不同的方法并构建了几个可重用的组件。这将删除您放入Vue的所有复杂逻辑。

Vue.component("expand-link",{
    template:`<a href="#0" @click="toggle">Advanced</a>`,
  data(){
        return {
        expanded: false
    }
  },
  methods:{
    toggle(){
        this.expanded = !this.expanded
        this.$emit('toggled', this.expanded)
    }
  }
})

Vue.component("expanded-fields",{
    props:["details", "expanded"],
  template:`
        <div class="advanced-fields" :class="{overlay: expanded}">
            <fieldset>
                <label>
                    ID
                    <input type="text" name="section[id]" v-model="details.id">
                </label>
            </fieldset>
            <fieldset>
                <label>
                    Class
                    <input type="text" name="section[css_class]" v-model="details.css_class">
                </label>
            </fieldset>
        </div>
  `
})

Vue.component("expandable-section", {
    props:["section"],
    template:`
    <section>
        <expand-link @toggled="onToggle"></expand-link>
      <expanded-fields :details="section" :expanded="expanded"></expanded-fields>
      <expandable-row v-for="row in section.rows" :key="row" :row="row"></expandable-row>
    </section>
  `,
  data(){
    return {
        expanded: false
    }
  },
  methods:{
    onToggle(val){
        this.expanded = val
    }
  }
})

Vue.component("expandable-row",{
    props:["row"],
    template:`
    <div class="row">
      <h3>Row</h3>
      <expand-link @toggled="onToggle"></expand-link>
      <expanded-fields :details="row" :expanded="expanded"></expanded-fields>
    </div>
  `,
  data(){
    return {
        expanded: false
    }
  },
  methods:{
    onToggle(val){
        this.expanded = val
    }
  }
})

模板就变成了

<div id="app">
  <expandable-section v-for="section in sections" :key="section" :section="section"></expandable-section>
  <pre>{{ $data }}</pre>
</div>

这是你的小提琴updated