【问题标题】:How to select checked checkboxes inside multiple divs with VueJS如何使用 VueJS 在多个 div 中选中选中的复选框
【发布时间】:2019-10-25 06:08:12
【问题描述】:

我对 VueJS 还比较陌生,我遇到了一个用 jQuery 很容易解决的问题,但即使我确定有 VueJS,我也找不到。

我有一个用户选择的路径列表,对于每个路径,我在该 div 中创建一个带有 3 个复选框的 div:添加、编辑和删除。

假设我有 2 个路径:'/foo' and '/bar',对于这 2 个路径,我创建了 3 个复选框:为每个路径添加、编辑和删除。如果用户检查添加、编辑和第一个路径,并且只检查第二个路径上的删除,那么我想以编程方式构建以下对象:

[
{path: '/foo', actions: ["add","edit"]}, 
{path: '/bar' , actions: ["delete"]}
]

当用户按下最终提交按钮时,会在最后调用创建此对象的函数,以下是一些相关代码:

在组件模板中:

<li v-for = "selectedPath in newProfile.paths">
                <Card :card-name="selectedPath">
                    <h5>{{selectedPath}}</h5>
                    <base-checkbox :data-path="selectedPath" type = "default" name = "add">Ajout</base-checkbox>
                    <base-checkbox :data-path="selectedPath" name = "edit">Edition</base-checkbox>
                    <base-checkbox :data-path="selectedPath" name = "delete">Supression</base-checkbox>
                </Card>
            </li>

JS 代码包含用于选择复选框的 vanilla JS,但问题是我正在使用我正在使用的模板附带的组件复选框,因此除非您获得每个复选框组件内的内容,否则无法获取选中的属性这很快就会变得丑陋和非 vuejs 的方式来做到这一点。

那么我怎样才能实现这一点(基于每个 div 中的复选框构建该对象)?

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您需要监听base-checkbox 组件上的事件并相应地更新合适的数据结构。在 Vue 中,DOM 是次要的,您的主要事实来源是 JavaScript 数据。

    有许多不同的方法可以解决这个问题,具体取决于在给定场景中哪些数据结构最有意义。引用神话中的人月

    表示编程的本质。

    考虑到这一点,我不相信我在下面构建的示例一定是使用最好的数据结构来表示数据,或者我什至不相信我正在使用这些数据结构以及它们可以使用.

    一些注意事项:

    • 计算属性out 保存完成格式的数据,即单击提交按钮时使用的格式。我没有包含提交按钮,我只是将数据转储出来以便您查看。
    • 保持pathsselectedPaths 分开不是严格要求,但它似乎更接近您的原始代码,paths 类似于newProfile.paths
    • selectedPaths 中的格式为{path1: {add: true, edit: false, delete: true}, path2: ...}。属性是惰性创建的,默认所有复选框为false
    • 因为selectedPaths 最初是空的,所以它的属性不会是响应式的。这就是使用$set 的原因。如果可以在 data 方法中预填充此对象,则无需使用 $set
    • 我在复选框中使用了 HTML &lt;input&gt; 元素,但方法与复选框组件完全相同。一个 prop 传入当前值,当值发生变化时,一个事件用于更新数据。
    • 当像这样使用v-for 时,为子组件分离一个单独的子组件通常更简单。与其在父级中操作复杂的数据结构,不如将一些工作卸载到每个子级上。我在这里没有这样做,因为我试图将所有内容都放在一个组件中,但如果我真的这样做,我会探索它。
    <template>
        <div>
            <ul>
                <li v-for="path in pathsWithSelections" :key="path.path">
                    {{ path.path }}
                    <input type="checkbox" :checked="path.add" @input="onChecked(path.path, 'add')">
                    <input type="checkbox" :checked="path.edit" @input="onChecked(path.path, 'edit')">
                    <input type="checkbox" :checked="path.delete" @input="onChecked(path.path, 'delete')">
                </li>
            </ul>
            {{ out }}
        </div>
    </template>
    
    <script>
        export default {
            data () {
                return {
                    paths: ['path1', 'path2', 'path3'],
                    selectedPaths: {}
                }
            },
    
            computed: {
                pathsWithSelections () {
                    return this.paths.map(path => {
                        const selected = this.selectedPaths[path] || {}
    
                        return {
                            path,
                            ...selected
                        }
                    })
                },
    
                out () {
                    const out = []
    
                    for (const path of this.pathsWithSelections) {
                        const actions = []
    
                        for (const action of ['add', 'edit', 'delete']) {
                            if (path[action]) {
                                actions.push(action)
                            }
                        }
    
                        if (actions.length) {
                            out.push({
                                path: path.path,
                                actions
                            })
                        }
                    }
    
                    return out
                }
            },
    
            methods: {
                onChecked (path, action) {
                    const selectedPaths = this.selectedPaths
    
                    const selected = selectedPaths[path] || {}
    
                    this.$set(selectedPaths, path, selected)
                    this.$set(selected, action, !selected[action])
                }
            }
        }
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多