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. 【github&&git】4、git常用命令(持续更新中)

    git常用命令(持续更新中) 本地仓库操作git int                                 初始化本地仓库git add .                       ...

  2. SQL Server 基本INSERT语句

    1.基本INSERT语句,单行插入 如果没有列出列,则使一一对应. 2.多行插入 3.INSERT INTO ... SELECT 语句 要插入的语句是从其他表中查询出来的. 注意:数据类型得相同或者 ...

  3. 前端面试(原生js篇) - 精确运算

    一.面试题 问:开发的时候有用到过 Math 吗? 答:很多啊.比如生成 GUID 的时候,就会用到 Math.random() 来生成随机数. 问:别的呢?比如向下取整.向上取整? 答:向下取整是  ...

  4. React-classnames库

    今天在项目中看到了大佬引入了classnames,之前没用过所以去搜了搜,感觉还真的是挺好用的,搜到一篇很不错的文章,跟原创作者交流了一下就转载过来了! 下面废话不多说,我们直接来看文章吧 首先我们我 ...

  5. 【转】用yum只下载rpm包而不安装

    转自:http://liucheng.name/1950/ CentOS用yum安装软件是非常方便的,有时,我们只需要下载其中的rpm包,而不直接安装时咋办呢? 一般情况下,yum是不提供只下载的功能 ...

  6. python并发编程之线程

    操作系统线程理论 参考资料:http://www.cnblogs.com/Eva-J/articles/8306047.html 线程和python 理论知识 全局解释器锁GIL Python代码的执 ...

  7. npm install node-sass 本地安装失败

    $ npm install --save node-sass --registry=https://registry.npm.taobao.org --disturl=https://npm.taob ...

  8. Install Google Chrome on Fedora 28/27, CentOS/RHEL 7.5 (在 fedora 28 等 上 安装 chrome)

    今天在使用 fedora 安装 chrome 的时候遇到了问题,今天进行将安装过程进行记录下来.需要安装第三方软件仓库. 我们需要进行安装 fedora-workstation-repositorie ...

  9. Hibernate 中的 idclass mapping 问题

    关于出现 idclass mapping 运行错误 @IdClass 注释通常用于定义包含复合键id的Class.即多个属性的关键复合. @IdClass(CountrylanguageEntityP ...

  10. WampServer 安装使用详解

    WampServer集成环境的搭建.安装.使用.配置 什么是WampServer WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去 ...