前言:

数据变更之后,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. POJ3525:Most Distant Point from the Sea(二分+半平面交)

    pro:给定凸多边形,求凸多边形内的点到最近边界的最远距离. sol:显然是二分一个圆,使得圆和凸多边形不相交,但是这样很难实现. 由于是凸多边形,我们可以把二分圆转化为二分凸多边形的移动. 如果每一 ...

  2. 第六课cnn和迁移学习-七月在线-cv

    ppt 参数共享终于把拿一点想清楚啦,一定要知道w是矩阵! 在传统BP中,w前后连接时是all的,辣么多w使得你给我多少图片我就能记住多少信息-->导致过拟合-->cnn当中权值共享 激励 ...

  3. python scrapy 爬虫实例

    1 创建一个项目 scrapy startproject basicbudejie 2 编写爬虫 import scrapy class Basicbudejie(scrapy.Spider): na ...

  4. Centos6.7 64位安装配置kvm虚拟化

    首先,需要我们的cpu支持虚拟化,有的机器支持但是并未在bios开启,这个需要事先开启. 1. Dell R710安装centos6.7 64位 ,Dell R710在开机后按F2进入BIOS,Pro ...

  5. MySQL--使用innodb_force_recovery修复数据库异常

    当MySQL服务异常重启失败后,可以通过配置参数innodb_force_recovery来对MySQL服务进行修复启动. 参数innodb_force_recovery选项: 1 (SRV_FORC ...

  6. immutable-styles 新的css style 开发模式

    immutable-styles 是一个开源的library,可以方便我们开发强壮以及可预测的web 界面,不用担心其他css 的影响 特性 编译时错误提示 防止css 覆盖 分离破坏点 严格继承 重 ...

  7. sofa graphql 2 rest api框架

    sofa 是一个出发点不一样的工具,提供了从graphql 2 rest 的处理,一般现有的框架都在 关注的是rest 2 graphql (大部分还是基于swagger.open api 标准进行设 ...

  8. egg-init 知识点

    Create a simple type application $ egg-init --type simple [dest]

  9. sql语句实战

    1,排名,自身连接,用count,去重用distinct 2,累加,和上面一样,自身连接,用sum 3,count函数不用group by只有一组

  10. pyquery的使用

    常用的三种初始化方法: 1.字符串初始化: from pyquery import PyQuery as pq html=""" <html> <hea ...