javascript - 更新 Vue.js 中的嵌套父类

标签 javascript vue.js vuejs2

每次单击“高级”链接时,我都会尝试向父容器添加一个类。

所以使用 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/

最佳答案

我采用了不同的方法并构建了几个可重用的组件。这消除了您放入 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>

这是你的 fiddle updated .

关于javascript - 更新 Vue.js 中的嵌套父类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44640593/

相关文章:

javascript - 当用户输入错误的 Angular 时,代码不会显示错误消息

javascript - 如何在Vue Js中通过axios调出查询

javascript - 使用 JEST 对 Vue.js 路由器进行单元测试 - 如何模拟页面?

javascript - 405 不允许从 javascript 获取 couchdb 文档的方法

vue.js - VueJS 2.0 - 无法在 Prop 更新上 Hook 组件

php - IE 和 Safari 中的 javascript 和 ajax 问题

javascript - 如何正确堆叠砌体布局和延迟加载图像?

php - 如何触发 AJAX 请求并在发出请求后重定向?

pdf - 使用 VueJS 在另一个窗口中打开 PDF 文件

javascript - 使用 httponly cookie 将 JWT 从 Node REST API 发送到 Vue.js SPA