前言:

数据变更之后,vue如何渲染dom?

实际场景:

更新数据之后,再设置滚动条的位置为什么设置无效?

为什么将隐藏的元素设置为显示状态之后,读取元素状态读取不到?

改变了对象/数组中的值,页面没有更新最新的值?

关于vue中的数据改变没有触发视图更新的现象:

    需要知道的一些细节

vue中data中定义的变量,vue才能监听到其的变化。

vue中无法监听到对象的属性的添加、修改和删除。

vue中对数组,通过下标修改的属性值无法响应(不能触发视图更新)。

˙针对上面的一些解决方案

    1、给对象添加属性,通过$set(obj, propname, propvalue)或Object.assign({},obj,{...})添加

2、对数组中的对象属性做修改,比如要给一个定义在data中的数组(响应式变量)中的值(一个对象类型的值)添加一个属性,

直接通过点或[]的方式添加这个属性,这个属性值修改之后也可以触发视图更新。

3、对于数组,在给数组通过push、shift、splice等方法给数组添加/删除值,可以触发视图更新,但是通过下标方式去给数组添加值,是不能触发视图更新的。

还有一种情况:变量是响应式的却还是没有触发视图更新。因为vue中数据的更新是异步的,如果希望数据变化之后及时更新dom可以放在this.$nextTick()中。

这里举个数据变化但不触发视图更新的一个例子:

组件中之间传递值时数据不触发视图更新问题

1、限制输入框字符数的功能,通过:value给表单框初始化值,

                <input
class="remark-modify"
maxlength="32"
type="text"
:value="username"
@blur="saveRemark"
@keypress.enter="saveRemark"
@keyup="limitLength"
autofocus v-else>

 2、keyup监听输入,当字符串达到32时,将32后的字符串裁剪掉,因为不能直接修改组件中props中的变量,所以只能通过向父组件抛事件或通过sync标识符来修改父组件中变量的值然后再传到子组件中。子组件中接受了父组件中的变量的值但是却没有渲染。

  limitLength(e) {
const input = e.target;
const value = input.value
const split = value.split('');
const map = split.map((s, i) => {
return (value.charCodeAt(i) >= 0 && value.charCodeAt(i) <= 128) ? 1 : 2;
});
let n = 0;
const charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
const count = accumulator + currentValue;
if (count === 31 || count === 32) {
n = index;
}
if (count > 32) { this.$emit('update:username',split.slice(0, n+1).join('') )
this.$emit("setUserName",split.slice(0, n+1).join(''));
}
return count
}); },

这里的没有渲染和vue中的值修改是异步渲染的有关。

解决方案:

1、input的值通过v-model来绑定值,v-model相当于:value赋值和oninput事件的集合

        <input
class="remark-modify"
maxlength="32"
type="text"
v-model="name"
@blur="saveRemark"
@keypress.enter="saveRemark"
@keyup="limitLength"
autofocus v-else>

2、computed定义name变量,用于在输入框中显示内容,通过定义set()和get()方法来修改值和读取值(props中定义username)

computed: {
name: {
set(value) {
this.$emit("setUserName", value);
},
get(value) { return this.username
}
}
},

3、限制字符数的方法里面裁剪内容之后直接将新值赋值给name变量,会触发name中的set方法

limitLength(e) {
const input = e.target;
const value = input.value
const split = value.split('');
const map = split.map((s, i) => {
return (value.charCodeAt(i) >= 0 && value.charCodeAt(i) <= 128) ? 1 : 2;
});
let n = 0;
const charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
const count = accumulator + currentValue;
if (count === 31 || count === 32) {
n = index;
}
if (count > 32) {
this.name = split.slice(0, n+1).join('')
// this.$emit('update:username',split.slice(0, n+1).join('') )
// this.$emit("setUserName",split.slice(0, n+1).join(''));
}
return count
});

vue系列日志中我会总结如下内容:

1、vue中异步渲染数据问题

2、computed定义变量,变量中定义set/get方法和没有定义的区别

3、vue中的响应式数据机制

4、javascript中的定义对象属性的Object.definedProperty()

  

 

problem:vue之数据变更没有触发视图更新问题的更多相关文章

  1. Vue.set() this.$set()引发的视图更新思考

    引文 vue文档列表渲染中有条注意事项: 这里提到的两种情况实际改变了数据但是没有触发视图更新. 由此引出Vue.set(),先上文档API: this.$set()和Vue.set()本质方法一样, ...

  2. Vue.set 向响应式对象中添加响应式属性,及设置数组元素触发视图更新

    一.为什么需要使用Vue.set? vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ Vu ...

  3. VUE 动态给对象增加属性,并触发视图更新。

    在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 根据官方文档定义 ...

  4. vue数组对象修改触发视图更新

    直接修改数组元素是无法触发视图更新的,如 this.array[0] = { name: 'meng', age: 22 } 修改array的length也无法触发视图更新,如 this.array. ...

  5. Vue 动态修改data 值 并触发视图更新

    Vue 动态修改data 值 并触发视图更新 this.$set(obj, key, '') // Vue 动态修改或者添加data key 并触发视图更新

  6. Vue 改变数组触发视图更新

    最近给table做了一个点击排序的功能,数组更改以后发现data数据变了,但是视图不更新 写惯了js的我们随手一串代码 this.items[2]={message:"Change Test ...

  7. problem: vue之数组元素中的数组类型值数据改变却无法在子组件视图更新问题

    问题:给父组件上的一个数组中的某个元素中的数组类型值,添加值后,数据没有在子组件上更新. 对元素添加值之后,vue的数据其实已经更新了并传给了子组件,子组件中没有立即更新. 那么这里有个问题,在子组件 ...

  8. vue的data里面的值是数组时,在更改其某一项的时候,怎么触发视图的重新渲染?

    1. 设置对象或数组的值:Vue.set(target,key,value) :2.删除对象或数组中元素: Vue.delete ( target,key) ;3. 数组对象直接修改属性,可以触发视图 ...

  9. vue实现数据双向绑定的原理

    一.知识准备Object.defineProperty( )方法可以直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象.Object.defineProperty(obj,pr ...

随机推荐

  1. Sublime Text 3(中文)在Windows下的配置、安装、运行

    Sublime Text 3(中文)下载.安装.运行! 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 具体 ...

  2. inner join 与一般笛卡尔积的区别

    inner join 与一般笛卡尔积的区别:inner join是笛卡尔积的特殊形式.如果有表a和表b,表a有m条记录,表b有n条记录,则一般笛卡尔积后得到的记录条数是m*n条,记录之间的组合是随意的 ...

  3. Failed to start component [StandardEngine[Catalina].stadardHost[loclahost].StandardContent[/GarageMgtB]]

    错误如图: 新导入的一个web工程,在problems中显示错误是:Target runtime Apache Tomcatv8.0 is not defined. 终于找到解决方法.方法是:在工程目 ...

  4. linux lamp编译环境安装

    apache 安装:http://blog.csdn.net/wplblog/article/details/52172128 编译安装 mysql安装:http://www.centoscn.com ...

  5. 《DSP using MATLAB》Problem 5.34

    第1小题 代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  6. LeetCode - Beautiful Array

    For some fixed N, an array A is beautiful if it is a permutation of the integers 1, 2, ..., N, such ...

  7. tailor+ skipper 实现micro-frontends 简单试用

    tailor 在Mosaic 框架中扮演fragment 模版layout的处理,后端fragment可以用任何服务编写 tailor 主要就是进行layout的处理.tailor的是类似facebo ...

  8. 算法导论 (Thomas H.Cormen / Charles E.Leiserson / Ronald L.Rivest / Clifford Stein 著)

    第一部分 基础知识 第1章 算法在计算中的作用 第2章 算法基础 第3章 函数的增长 第4章 分治策略 第5章 概率分析和随机算法 第二部分 排序和顺序统计量 第6章 堆排序 第7章 快速排序 第8章 ...

  9. GlusterFS学习

    环境准备 3台机器,每个机器双网卡,每个机器还需要额外添加1个10GB的磁盘用于测试 机器系统版本是centos6.6 [root@gluster-1-1 ~]# uname -rm 2.6.32-5 ...

  10. 寻找“最好”(4)——不等约束和KKT条件

    不等约束 上篇文章介绍了如何在等式约束下使用拉格朗日乘子法,然而真实的世界哪有那么多等式约束?我们碰到的大多数问题都是不等约束.对于不等约束的优化问题,可以这样描述: 其中f(x)是目标函数,g(x) ...