zoukankan      html  css  js  c++  java
  • problem:vue之数据变更没有触发视图更新问题

    前言: 

    数据变更之后,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()

      

     

  • 相关阅读:
    IIS6.0应用程序池回收和工作进程
    SQL Server 中的 bit 类型的使用
    VS2008 SP1简体中文版下载与.Net Framework 3.5 SP1简体中文版下载
    C#技术教程:http://www.cftea.com/docs/asp.net/csharp/
    C#中得到程序当前工作目录和执行目录的一些方法
    C#中 ? 运算符 和 ??运算符
    dhl:页面中调用 通过类返回SqlDataReader类型的对象
    C# 枚举(enum)-设计
    CnBlogs博文排版技巧 写博文了~~
    金山快译2007版
  • 原文地址:https://www.cnblogs.com/yy95/p/9872534.html
Copyright © 2011-2022 走看看