Vue 改变数组中对象的属性不重新渲染View的解决方案

在解决问题之前,我们先来了解下 vue响应性原理: Vue最显著的一个功能是响应系统-- 模型只是一个普通对象,修改对象则会更新视图。
受到javascript的限制,Vue不能检测到对象属性的添加或删除,因为vue在初始化实列时将属性转为getter/setter,所以属性必须在data对象上才能让vue转换它。
但是vue可以使用 Vue.set(object, key, value)方法将响应属性添加到嵌套的对象上:如下代码:

Vue.set(obj, '_isHover', true);

或者可以使用vm.$set的实列方法,也是Vue.set方法的别名:

this.$set(obj, '_isHover', false);

问题: 页面上多个item项, 当我鼠标移动上去的时候,我想在该数组中的对象添加一个属性 isHover=true, 当鼠标移出的时候,我想让该属性变为 isHover=false,然后希望改变对象的属性的时候让其重新渲染view层,重新执行rowClasses方法,然后该方法会判断 isHover是否等于true,如果为true的话,让其增加一个类名。
代码如下:

<!DOCTYPE html>
<html>
<head>
<title>演示Vue</title>
<style>
* {margin: 0; padding: 0;}
ul, li {list-style: none;}
#app {width: 800px; margin: 20px auto; border:1px solid #ccc; border-bottom: none;}
#app li {height: 32px; line-height: 32px; border-bottom: 1px solid #ccc;}
#app li.bgColor {background-color: red;}
</style>
</head>
<body>
<div id='app'>
<ul>
<li
v-for="(item, index) in items"
@mouseenter.stop="handleMouseIn(index)"
@mouseleave.stop="handleMouseOut(index)"
:class="rowClasses(index)"
>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</body>
<script src="https://tugenhua0707.github.io/vue/vue1/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
items: [
{name: 'kongzhi'},
{name: 'longen'},
{name: 'tugenhua'}
]
},
computed: { },
methods: {
rowClasses (index) {
return [
{
[`bgColor`]: this.$data.items[index] && this.$data.items[index]._isHover
}
]
},
handleMouseIn(index) {
if (this.$data.items[index]._isHover) {
return;
}
console.log(111); // 可以执行到
this.$data.items[index]._isHover = true;
},
handleMouseOut(index) {
this.$data.items[index]._isHover = false;
}
}
});
</script>
</html>

查看效果

可以看到鼠标移动上去的时候 没有效果。

解决的方案如下:

1. 使用 Object.assign

鼠标移动上去的时候 代码可以改成如下:

this.$data.items[index]._isHover = true;
this.$data.items = Object.assign({}, this.$data.items);

鼠标移出的时候,代码改成如下:

this.$data.items[index]._isHover = false;
this.$data.items = Object.assign({}, this.$data.items);

代码如下:

<!DOCTYPE html>
<html>
<head>
<title>演示Vue</title>
<style>
* {margin: 0; padding: 0;}
ul, li {list-style: none;}
#app {width: 800px; margin: 20px auto; border:1px solid #ccc; border-bottom: none;}
#app li {height: 32px; line-height: 32px; border-bottom: 1px solid #ccc;}
#app li.bgColor {background-color: red;}
</style>
</head>
<body>
<div id='app'>
<ul>
<li
v-for="(item, index) in items"
@mouseenter.stop="handleMouseIn(index)"
@mouseleave.stop="handleMouseOut(index)"
:class="rowClasses(index)"
>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</body>
<script src="https://tugenhua0707.github.io/vue/vue1/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
items: [
{name: 'kongzhi'},
{name: 'longen'},
{name: 'tugenhua'}
]
},
computed: { },
methods: {
rowClasses (index) {
return [
{
[`bgColor`]: this.$data.items[index] && this.$data.items[index]._isHover
}
]
},
handleMouseIn(index) {
if (this.$data.items[index]._isHover) {
return;
}
console.log(111); // 可以执行到
this.$data.items[index]._isHover = true;
this.$data.items = Object.assign({}, this.$data.items);
},
handleMouseOut(index) {
this.$data.items[index]._isHover = false;
this.$data.items = Object.assign({}, this.$data.items);
}
}
});
</script>
</html>

查看效果

2. 使用Vue.set(object, key, value)方法将响应属性添加到嵌套的对象上。

鼠标移动上去的时候 代码可以改成如下:

this.$set(this.$data.items[index], '_isHover', true);

鼠标移出的时候,代码改成如下:

this.$set(this.$data.items[index], '_isHover', false);

所有的代码如下:

<!DOCTYPE html>
<html>
<head>
<title>演示Vue</title>
<style>
* {margin: 0; padding: 0;}
ul, li {list-style: none;}
#app {width: 800px; margin: 20px auto; border:1px solid #ccc; border-bottom: none;}
#app li {height: 32px; line-height: 32px; border-bottom: 1px solid #ccc;}
#app li.bgColor {background-color: red;}
</style>
</head>
<body>
<div id='app'>
<ul>
<li
v-for="(item, index) in items"
@mouseenter.stop="handleMouseIn(index)"
@mouseleave.stop="handleMouseOut(index)"
:class="rowClasses(index)"
>
<span>{{item.name}}</span>
</li>
</ul>
</div>
</body>
<script src="https://tugenhua0707.github.io/vue/vue1/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
items: [
{name: 'kongzhi'},
{name: 'longen'},
{name: 'tugenhua'}
]
},
computed: { },
methods: {
rowClasses (index) {
return [
{
[`bgColor`]: this.$data.items[index] && this.$data.items[index]._isHover
}
]
},
handleMouseIn(index) {
if (this.$data.items[index]._isHover) {
return;
}
console.log(111); // 可以执行到
this.$set(this.$data.items[index], '_isHover', true);
},
handleMouseOut(index) {
this.$set(this.$data.items[index], '_isHover', false);
}
}
});
</script>
</html>

查看效果

Vue 改变数组中对象的属性不重新渲染View的解决方案的更多相关文章

  1. array排序(按数组中对象的属性进行排序)

    使用array.sort()对数组中对象的属性进行排序 <template> <div> <a @click="sortArray()">降序& ...

  2. 利用KVC的方式更方便地获取数组中对象的属性的最值平均值等

    直接上代码 输出结果也在相应的代码里标注出来了 //main.m文件 #import <Foundation/Foundation.h> #import "Student.h&q ...

  3. JS 取Json数据中对象特定属性值

    解析JSON JSON 数据 var str = '[{"a": "1","b": "2"}, {"a&quo ...

  4. 仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大

    仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大 1.介绍 先看图 ​ 今天在项目中遇到了一个问题,例如我现在需要传一些数据到后端,数组例如是 let arr = [ {" ...

  5. js sort方法根据数组中对象的某一个属性值进行排序(实用方法)

    js sort方法根据数组中对象的某一个属性值进行排序 sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr = [ {nam ...

  6. js对象数组中的某属性值 拼接成字符串

    js对象数组中的某属性值 拼接成字符串 var objs=[ {id:1,name:'张三'}, {id:2,name:'李四'}, {id:3,name:'王五'}, {id:4,name:'赵六' ...

  7. JavaScript中对象的属性

    在JavaScript中,属性决定了一个对象的状态,本文详细的研究了它们是如何工作的. 属性类型 JavaScript中有三种不同类型的属性:命名数据属性(named data properties) ...

  8. Day_12【集合】扩展案例1_利用集合的知识对长度为10的int数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序

    分析以下需求,并用代码实现 1.定义一个长度为10的int数组,并存入10个int类型的数据,其中有一些数据是重复的 2.利用集合的知识对数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序 3 ...

  9. java 对list中对象按属性排序

    实体对象类 --略 排序类----实现Comparator接口,重写compare方法 package com.tang.list; import java.util.Comparator; publ ...

随机推荐

  1. js事件冒泡和事件捕获详解

    Javascript与HTML之间的交互是通过事件实现. 一.事件流 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间.事件流,描述的是页面中接受事件的顺序.IE9,chrome,Firefox,O ...

  2. git 出现gnome-ssh-askpass:32737

    今天在git push origin master时,竟然出现了错误 (gnome-ssh-askpass:32737): Gtk-WARNING **: cannot open display: e ...

  3. linux下安装mysql环境

    1.在安装apache的时候已经检查了本地没有安装centos自带的mysql,有的话一定要卸载掉,否则可能占用端口 2.准备mysql安装包(注意编译的时候,mysql5.5版本以上的编译和5.5一 ...

  4. css3火焰文字样式代码

    css样式: <style type="text/css"> body{background:#000;} *{margin:0;padding:0;transitio ...

  5. 对GIL的一些理解

    GIL:全局解释器锁 GIL设计理念与限制: python的代码执行由python虚拟机(也叫解释器主循环,CPython版本)来控制,python在设计之初就考虑到在解释器的主循环中,同时只有一个线 ...

  6. plsql调试存储过程卡住的原因以及处理

    用PLSQL调试存储过程的时候,经常会遇到这个的情况,点调试后,继续点单步都是灰色,想停下来,但是取消也要点很多次才能取消掉. 就像下面的情况: 一直以为是个BUG,直到最近有人告诉我了真相. 出现这 ...

  7. 浅谈 Mysql 中的索引

    文章归属:http://feiyan.info/16.html,我想自己去写了,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基 ...

  8. Ubuntu16.04升级 Ubuntu18.04

    1.更新资源 $ sudo apt-get update $ sudo apt-get upgrade $ sudo apt dist-upgrade 2.安装update-manager-core ...

  9. Scala学习笔记2 (带着问题学习, 逐渐扩展。理解吃透scala.)

    问题: 把 文本字符串"[1, 2, 3, 4, 5]" 转换成一个数组. 答案: val x = "[1, 2, 3, 4, 5]" val y =x sli ...

  10. Python CNN卷积神经网络代码实现

    # -*- coding: utf-8 -*- """ Created on Wed Nov 21 17:32:28 2018 @author: zhen "& ...