前言
vue的导入
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
or:
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
问题
问题描述:通过v-for渲染表格,在第一次渲染成功后,修改了某个单元格内容,第二次渲染时该单元格内容未改变(同行其他单元格内容成功渲染)
问题分析:渲染成功后直接修改表格的内容,会直接替换掉修改位置的表达式,使得不能二次渲染
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div>
<div id="app" style="text-align: center;align-items: center">
<table style="width: 50%;margin: 0 auto"
class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">用户名</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="pwd_list">
<tr v-for="item in items">
<th scope="row">{{ item.ID }}</th>
<td><span>{{ item.name }}</span></td>
<td>
<button class="btn btn-default" v-on:click="Onclick($event)">修改</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-default" v-on:click="review()" style="margin: 2px auto">重新渲染表格</button>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"}
],
},
methods: {
Onclick: function (event) {
var button_ob = event.currentTarget;
var name_obj = $(button_ob).parent().prev();
name_obj.text('测试')
},
review: function () {
app.items = [
{"ID": 2, "name": "qwe1"},
{"ID": 2, "name": "qwe1"}
]
}
}
});
</script>
</body>
</html>
如上述代码所示:点击修改按钮将当前行的用户名修改为测试
,然后再点击重新渲染表格
按钮,但是已修改位置数据没有改变仍为测试
解决方法
本人是vue的初学者所以接下来会将我遇到这个问题时尝试的几种方法展示出来:
第一种“蠢”办法
基于我是要对用户名进行修改的这个需求,想到可以在用户名这个单元格内增加一个隐藏<span id="change" style="display:none">hide</span>
标签来展示修改文本
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div>
<div id="app" style="text-align: center;align-items: center">
<table style="width: 50%;margin: 0 auto"
class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">用户名</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="pwd_list">
<tr v-for="item in items">
<th scope="row">{{ item.ID }}</th>
<td>
<span id="default">{{ item.name }}</span>
<span id="change" style="display:none">hide</span>
</td>
<td>
<button class="btn btn-default" v-on:click="Onclick($event)">修改</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-default" v-on:click="review()" style="margin: 2px auto">重新渲染表格</button>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"}
],
},
methods: {
Onclick: function (event) {
var button_ob = event.currentTarget;
var name_obj = $(button_ob).parent().prev();
name_obj.find('span[id^="default"]').hide();
name_obj.find('span[id^="change"]').show();
name_obj.find('span[id^="change"]').text('测试')
},
review: function () {
app.items = [
{"ID": 2, "name": "qwe1"},
{"ID": 2, "name": "qwe1"}
]
$("[id=default]").each(function () {
$(this).show()
});
$("[id=change]").each(function () {
$(this).hide()
});
}
}
});
</script>
</body>
</html>
第二种方法
每次点击修改时,不直接修改单元格内容,而是对数据集对应内容进行修改
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div>
<div id="app" style="text-align: center;align-items: center">
<table style="width: 50%;margin: 0 auto"
class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">用户名</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="pwd_list">
<tr v-for="(item,index) in items">
<th scope="row">{{ item.ID }}</th>
<td>
<span id="default">{{ item.name }}</span>
<span id="change" style="display:none">hide</span>
</td>
<td>
<!-- <button class="btn btn-default" v-on:click="Onclick($event)">修改</button>-->
<button class="btn btn-default" v-on:click="Onclick(index)">修改</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-default" v-on:click="review()" style="margin: 2px auto">重新渲染表格</button>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"},
{"ID": 1, "name": "qwe"}
],
},
methods: {
Onclick: function (index) {
/*app.items[index].name = '测试';*/
this.$set(this.items[index], 'name', 测试)
},
review: function () {
app.items = [
{"ID": 2, "name": "qwe1"},
{"ID": 2, "name": "qwe1"}
]
$("[id=default]").each(function () {
$(this).show()
});
$("[id=change]").each(function () {
$(this).hide()
});
}
}
});
</script>
</body>
</html>