渲染期间嵌套 ul 列表中的简单 Vue.Draggable 中断

Posted

技术标签:

【中文标题】渲染期间嵌套 ul 列表中的简单 Vue.Draggable 中断【英文标题】:Simple Vue.Draggable inside nested ul list breaks during render 【发布时间】:2021-04-20 04:35:24 【问题描述】:

编辑

我尝试根据@Amaarrockz 的反馈创建一个简单的沙箱,但我遇到的问题似乎仍然出现:

<div id="app">
    <ul>
        <li v-for="stepTitle in collections.stepTitles">
             stepTitle.name 
                <draggable tag="ol" v-model="collections.children">
                    <li v-for="child in collections.children"> child.step </li>
                </draggable>
        </li>
    </ul>
</div>
Vue.use('draggable');
var collection = 
    "stepTitles": [
        "name": "Step 1",
        "id": 1
    , 
        "name": "Step 2",
        "id": 2
    , 
        "name": "Step 3",
        "id": 3
    ],
    "children": [
            "parentID": 1,
            "step": "Child 1"
        ,
        
            "parentID": 2,
            "step": "Child 1"
        ,
        
            "parentID": 2,
            "step": "Child 2"
        ,
        
            "parentID": 2,
            "step": "Child 3"
        ,
        
            "parentID": 3,
            "step": "Child 1"
        ,
        
            "parentID": 3,
            "step": "Child 2"
        
    ]
;
new Vue(
    el: '#app',
    data: 
        collections: collection
    
);

我想要的最终结果应该是:

第 1 步 (不可拖动)
    孩子 1 (可拖动)
第 2 步 (不可拖动)
    孩子 1 (可拖动) 孩子 2 (可拖动) 孩子 3 (可拖动)
第 3 步 (不可拖动)
    孩子 1 (可拖动) 孩子 2 (可拖动)

其中子级应该扩展到 1 级并且可以在各自的父级内移动。

我已将其缩减为这样一个事实,即在父 &lt;ul&gt; 中呈现 &lt;draggable&gt; 似乎存在问题。如果我创建一个使用父级的v-for 变量的二维 JSON 数组,例如stepTitle,则会出现关于stepTitle is not defined 的错误。如果我创建一个一维 JSON 数组并使用不同的 v-for 变量,它不会正确呈现 html

我到处搜索带有嵌套可拖动对象的示例,但我发现的所有示例都显示父对象是可拖动的,这不是我想要的结果。此外,孩子能够成为父母,这也不是我想要的。

不正确的渲染告诉我我做错了什么,但是 vue-draggable 在常规 &lt;ul&gt; 内渲染子 &lt;draggable&gt; 是否存在问题?

原帖

我在使用 vue.draggable 时遇到了一个有趣的问题,我花了好几个小时试图弄清楚。

一般概念是我有一个包含嵌套数组的数组。这是数据:

"steps": [
    "name": "Title 1",
    "steps": ["Sub step 1"]
, 
    "name": "Title 2",
    "steps": ["Sub step 1", "Sub step 2", "Sub step 3"]
, 
    "name": "Title 3",
    "steps": ["Sub step 1", "Sub step 2"]
]

应该呈现如下内容:

目标是让这些子步骤可拖动并相应地调整 Vue 数组。但是,当我引入 &lt;draggable&gt; 标记时,代码中断为:

属性或方法“item”未在实例上定义,但在渲染期间被引用。

这是上下文的完整代码:

HTML

<ul class="steps-section-added">
    <li class="list-group" v-for="(item, index) in stepSections" :key="item.stepSectionTitle" v-on:remove="removeAddedStepSection(index)">
        <div class="row">
            <div class="col-12">
                <div class="ist-group-item list-group-item-steps-header" style="display: table;width: 100%;"> item.stepSectionName 
                    <span>
                        <button class="btn btn-outline-success-white float-right d-flex justify-content-center align-content-between ml-2" v-on:click="removeAddedStepSection(index)"><span class="material-icons">delete</span></button>
                        <button class="btn btn-outline-success-white float-right d-flex justify-content-center align-content-between" v-on:click="editAddedStepSection(index)"><span class="material-icons">edit</span></button>
                    </span>
                </div>
                <div>
                    <!-- Code breaks somewhere here-->
                    <draggable v-model="item.steps" tag="ol" @start="drag=true" @end="drag=false" style="padding-left: 0px;">
                        <li class="recipe-list-group-item list-group-item list-group-item-steps-body" v-for="t in item.steps"> t.stepText </li>
                    </draggable>
                </div>
            </div>
        </div>
    </li>
</ul>

Vue 应用

Vue.use('draggable');
var stepsVM = new Vue(
    el: '#step-section-ingredients',
    data: 
        steps: [],
        stepSections: [],
        stepSectionTitle: '',
        drag: false
    ,
    methods: 
        addNewStep: function () 
            //
        ,
        removeTextRow: function (index) 
            //
        ,
        addNewStepSection: function () 
            //
        ,
        removeAddedStepSection: function (index) 
            //
        ,
        editAddedStepSection: function (index) 
            //
        
    
);

如果我将&lt;draggable&gt; 标记替换为&lt;ol&gt;,它会正确呈现,但嵌套组件不可拖动。一旦我介绍了可拖动标签,它就会中断。经过数小时的试验,我认为错误指的是v-for="t in item.steps"&gt;。如果是这种情况,我该如何让item.steps 工作?

任何指导将不胜感激:)

【问题讨论】:

如果你想让 subs 可拖动,那么你需要改变数据结构 即使我将数据更改为"substeps": [id: 0, stepText: "Sub step 1"],代码似乎仍然失败。你有什么数据结构更好的建议吗?我还是有点卡住了 不,这个改变还不够 @Amaarrockz 我觉得我还是有点困惑,我需要创建一个全新的结构吗? 【参考方案1】:

是的,你的结构应该是这样的

"steps": [
    "name": "Step 1",
     id: 1,
     parentId: null
, 
    "name": "Sub Step 1",
     id: 11,
     parentId: 1
, 
    "name": "Sub Step 2",
     id: 12,
     parentId: 1
, 
    "name": "Step 2",
     id: 2,
     parentId: null
]

这是一个一维数组,但可以扩展到 n 级。如果你可以维护这样的结构,那么使用 vue-draggable 你从 Step1 到 Step2 的“子步骤”,基于你只需要更新你的 parentId 的转变

【讨论】:

以上是关于渲染期间嵌套 ul 列表中的简单 Vue.Draggable 中断的主要内容,如果未能解决你的问题,请参考以下文章

检票口嵌套 ListView(3 次)

选择列表中的第一个嵌套子项,但不选择子项

如何只悬停嵌套ul中的当前li?

浅谈列表<ul>跟<dl>使用注意点及使用的场景

使用 Javascript 从 json 数据中动态嵌套 ul\li 列表

beautifulSoup 不正确嵌套 <ul>s 的屏幕截图列表