【Vue】Vue v-for中json中Push,会导致v-bind中methods从头渲染一遍的问题

问题描述

代码如下

    <div v-for="(d,i) in data">

<span :class="isFavorite(i) ? 'red' : ''">{{d.name}}</span>

</div>

当首次加载页面时,会遍历data中所有的数据,每个数据都会判断一次isFavorite方法
但是如果data中push了新的对象,会从头渲染再重复判断一次isFavorite方法
我的项目中绑定的data量巨大,每次只要新增一小批内容,由于从头开始渲染,会导致cpu使用暴增。

问题出现的环境背景及自己尝试过哪些方法

尝试过
加:key 无效
加v-once 无效

相关代码

写了个demo完整代码如下

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Vue2 test</title>

<style>

.red{

color: red;

}

</style>

</head>

<body>

<div id="app">

<button @click="loadMore">loadMore</button>

<div v-for="(d,i) in data">

<span :class="isFavorite(i) ? 'red' : ''">{{d.name}}</span>

</div>

</div>

<script src="https://cdn.bootcss.com/vue/2.5.22/vue.min.js"></script>

<script>

let vm = new Vue({

el: '#app',

data: {

data: [

{

id: 1,

name: "one"

},

{

id: 2,

name: "two"

},

{

id: 3,

name: "three"

}

],

favorite: [

{

id: 1,

name: "one"

}

]

},

methods: {

isFavorite: function (index) {

console.log(index)

for (let f of this.favorite) {

if(this.data[index].id == f.id)

return true

}

return false;

},

loadMore: function () {

this.data.push(

{

id:100,

name:"100"

}

)

}

}

});

</script>

</body>

</html>

你期待的结果是什么?实际看到的错误信息又是什么?

运行效果如下图,期望是不要重复渲染,只渲染新增部分。
实际测试发现只要v-for下有v-bind,就会出现从头开始重新渲染的问题

【Vue】Vue v-for中json中Push,会导致v-bind中methods从头渲染一遍的问题

回答

我来回答吧,你可以把会发生重复渲染的模板提取成子组件,就能够避免函数重复触发这样的问题了,下面是我优化后的代码,希望对你有所帮助

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Vue2 test</title>

<style>

.red{

color: red;

}

</style>

</head>

<body>

<div id="app">

<button @click="loadMore">loadMore</button>

<div v-for="(d, i) in data">

<item :name="d.name" :id="d.id" :favorite="favorite" :key="i"></item>

</div>

</div>

<script src="https://cdn.bootcss.com/vue/2.5.22/vue.min.js"></script>

<script>

Vue.component('item', {

props: ['name', 'id', 'favorite'],

computed: {

isFavorite: function () {

console.log(this.id)

for (let f of this.favorite) {

if(this.id == f.id)

return true

}

return false;

}

},

template: `<span :class="isFavorite ? 'red' : ''">{{name}}</span>`

})

let vm = new Vue({

el: '#app',

data: {

data: [

{

id: 1,

name: "one"

},

{

id: 2,

name: "two"

},

{

id: 3,

name: "three"

}

],

favorite: [

{

id: 1,

name: "one"

},

{

id: 2,

name: "two"

}

]

},

methods: {

// isFavorite: function (index) {

// console.log(index)

// for (let f of this.favorite) {

// if(this.data[index].id == f.id)

// return true

// }

// return false;

// },

loadMore: function () {

this.data.push(

{

id:100,

name:"100"

}

)

}

}

});

</script>

</body>

</html>

这样就能保证只在新增的时候触发函数
【Vue】Vue v-for中json中Push,会导致v-bind中methods从头渲染一遍的问题

首先,感谢邀请。
1.个人感觉可能是vue的机制有关系,vue会监听绑定的数据,在数据变化时渲染dom,这个时候调用了isFavorite方法。
2.你可以尝试给数据添加个isFavorite属性默认false,如果添加对象的id等于this.favorite[0].id,就将isFavorite赋值为true。

<div v-for="(d,i) in data">

<span :class="d.isFavorite ? 'red' : ''">{{d.name}}</span>

</div>

loadMore: function () {

var obj = {

id:100,

name:"100",

isFavorite:false

}

if(obj.id == this.favorite[0].id){

obj.isFavorite:false = true

}

this.data.push(obj)

}

这样就只对新增的数据进行运算,方法的时间复杂度也降低了。
有个弊端就是只对新增数据运算的话,你的this.favorite就不能变化了。

加个key值,key值变化可以确定是否重新渲染

主要还是key的问题,如果重复渲染了说明key加的不对。

以上是 【Vue】Vue v-for中json中Push,会导致v-bind中methods从头渲染一遍的问题 的全部内容, 来源链接: utcz.com/a/72771.html

回到顶部