I am learning vue and one of the things I would like to do is to clone elements. I was playing with this code:
var multiple = new Vue({
el: '#vue',
data: {
},
methods: {
cloneWidget(e) {
let widgets = document.getElementById('widgets');
let widget = document.getElementById('widget');
clone = widget.cloneNode(true);
clone.id = Math.round(Math.random()*100);
widgets.appendChild(clone);
},
deleteClone(e) {
e.target.parentNode.remove();
}
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="styles.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<h1>Cloning</h1>
<div id="vue">
<form @submit.prevent>
<div id="widgets">
<div id="widget">
<div>
<label for="field1">Field 1:</label>
<input type="text" name="field1">
</div>
<div>
<label for="field2">Field 2:</label>
<input type="text" name="field2">
</div>
<i class="material-icons delete" @click="deleteClone">delete</i>
</div>
</div>
<button @click="cloneWidget">Add Widget</button>
</form>
</div>
<script src="app.js"></script>
</body>
</html>
However, the deleteClone method never gets called outside the original div="widget"
.
I can't seem to figure out why the event listener is not getting attached to the clones. Will cloneNode() mess up Vue?
答案 0 :(得分:1)
With Vue, generally you want to think in terms of data. Here is your example revised, such that a widget is rendered for each object in the widgets array.
In this case, the contents of the array don't make much sense; you would probably want to the properties of each object in the array to match your input fields, but this is just an example to get you going.
var multiple = new Vue({
el: '#vue',
data: {
widgets:[{}]
},
methods: {
addWidget() {
this.widgets.push({})
},
removeWidget(widget) {
this.widgets.splice(this.widgets.findIndex(w => w === widget), 1)
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css" rel="stylesheet"/>
<h1>Cloning</h1>
<div id="vue">
<form @submit.prevent>
<div id="widgets">
<div v-for="widget in widgets">
<div>
<label for="field1">Field 1:</label>
<input type="text" name="field1">
</div>
<div>
<label for="field2">Field 2:</label>
<input type="text" name="field2">
</div>
<i class="material-icons delete" @click="removeWidget(widget)">delete</i>
</div>
</div>
<button @click="addWidget">Add Widget</button>
</form>
</div>
For the most part, you want to stay away from manipulating the DOM directly and let Vue do the work for you.