Vue 改变数组中对象的属性不重新渲染View的解决方案
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的解决方案的更多相关文章
- array排序(按数组中对象的属性进行排序)
使用array.sort()对数组中对象的属性进行排序 <template> <div> <a @click="sortArray()">降序& ...
- 利用KVC的方式更方便地获取数组中对象的属性的最值平均值等
直接上代码 输出结果也在相应的代码里标注出来了 //main.m文件 #import <Foundation/Foundation.h> #import "Student.h&q ...
- JS 取Json数据中对象特定属性值
解析JSON JSON 数据 var str = '[{"a": "1","b": "2"}, {"a&quo ...
- 仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大
仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大 1.介绍 先看图 今天在项目中遇到了一个问题,例如我现在需要传一些数据到后端,数组例如是 let arr = [ {" ...
- js sort方法根据数组中对象的某一个属性值进行排序(实用方法)
js sort方法根据数组中对象的某一个属性值进行排序 sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr = [ {nam ...
- js对象数组中的某属性值 拼接成字符串
js对象数组中的某属性值 拼接成字符串 var objs=[ {id:1,name:'张三'}, {id:2,name:'李四'}, {id:3,name:'王五'}, {id:4,name:'赵六' ...
- JavaScript中对象的属性
在JavaScript中,属性决定了一个对象的状态,本文详细的研究了它们是如何工作的. 属性类型 JavaScript中有三种不同类型的属性:命名数据属性(named data properties) ...
- Day_12【集合】扩展案例1_利用集合的知识对长度为10的int数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序
分析以下需求,并用代码实现 1.定义一个长度为10的int数组,并存入10个int类型的数据,其中有一些数据是重复的 2.利用集合的知识对数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序 3 ...
- java 对list中对象按属性排序
实体对象类 --略 排序类----实现Comparator接口,重写compare方法 package com.tang.list; import java.util.Comparator; publ ...
随机推荐
- lucene 核心概念及入门
lucene Lucene介绍及核心概念 什么是Lucene Lucene是一套用于全文检索和搜索的开放源代码程序库,由Apache软件基金会支持和提供.Lucene提供了一个简单却强大的应用程序接口 ...
- 【Java并发编程】21、线程池ThreadPoolExecutor源码解析
一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...
- 在UAP中如何通过WebView控件进行C#与JS的交互
最近由于项目需求,需要利用C#在UWP中与JS进行交互,由于还没有什么实战经验,所有就现在网上百度了一下,但是百度的结果显示大部分都是在Android和IOS上面的方法,UWP中的几乎没有.还好微软又 ...
- Maven的pom.xml文件详解【转载】
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 【Mybatis】一对一实例
①创建数据库和表,数据库为mytest,表为father和child DROP TABLE IF EXISTS child; DROP TABLE IF EXISTS father; CREATE T ...
- array.js
// “最后加” concat 连接两个或更多的数组,并返回结果. var a = ['a','b','c']; var b = ['x','y','z']; var c = a.concat(b,t ...
- 前端开发面试题-HTML(转载)
本文由 本文的原作者markyun 收集总结了一些前端面试题,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习.透彻学习,形成自己的知识链.万不可投机取巧,临时抱佛脚只求面试侥幸混过关是错误的! ...
- 安全测试 web应用安全测试之XXS跨站脚本攻击检测
web应用安全测试之XXS跨站脚本攻击检测 by:授客 QQ:1033553122 说明 意在对XSS跨站脚本攻击做的简单介绍,让大家对xss攻击有个初步认识,并能够在实际工作当中运用本文所述知识做些 ...
- Linux 学习笔记之超详细基础linux命令 Part 3
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 2----------------- ...
- 安卓开发之Room实体定义数据
使用Room实体定义数据 在Room库中,entities(实体)代表着相关字段集.每一个entity(实体)代表着相关联数据库中的一个表.entity 类必须通过Database 类中的entiti ...