Edit
I tried creating a simple sandbox based on @Amaarrockz's feedback and the issue I'm having still seems to crop up:
<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
}
});
The ultimate result I'd like should be:
- Step 1 (Not draggable)
- Child 1 (Draggable)
- Step 2 (Not draggable)
- Child 1 (Draggable)
- Child 2 (Draggable)
- Child 3 (Draggable)
- Step 3 (Not draggable)
- Child 1 (Draggable)
- Child 2 (Draggable)
where children should only extend to 1 level and be movable within their respective parents.
I've whittled it down to the fact that there seems to be an issue rendering a <draggable> inside a parent <ul>. If I make a 2 dimensional JSON array that uses the parent's v-for variable, like stepTitle, it comes with an error about stepTitle is not defined. If I make a 1 dimensional JSON array and use different v-for variables, it doesn't render the HTML correctly.
I've searched everywhere for examples with nested draggables but all the examples I find show the parent being draggable which isn't the result I'd like. In addition, the child was able to become a parent which is also not what I want.
The incorrect rendering tells me I've done something wrong, but does vue-draggable have issues with rendering children <draggable> inside a regular <ul>?
Original Post
I have an interesting problem when using vue.draggable that I've spent hours trying to figure out.
The general concept is that I have an array that contains a nested array. Here's the data:
"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"]
}]
which should render something like this:

The goal is to get those sub steps draggable and have the Vue array adjust accordingly. However when I introduced the <draggable> tag the code breaks with a:
Property or method "item" is not defined on the instance but referenced during render.
Here's the full code for context:
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 app
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) {
//
}
}
});
If I replace the <draggable> tag to an <ol> it renders correctly but the nested components aren't draggable. As soon as I introduce the draggable tag it breaks. From hours of experimenting I think the error is referring to the v-for="t in item.steps">. If this is the case, how do I get the item.steps to work?
Any guidance would be appreciated :)
Yes your structure should be something like this
This is a one-dimension array but can extend upto n-levels. If you could maintain a structure like this then using vue-draggable you 'sub-step' from Step1 to Step2, based on the shift you just need to update your parentId's