vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作


Posted in Javascript onNovember 16, 2020

vuex数据改变,组件中页面不渲染

相信许多vuex新手都会遇到这样的问题:

vuex数据更新后,插件中使用数据的地方没有更新

这样的代码

data() {
 return {
  tableData: this.$store.state.AdminInfo
 };
 }

然后在 template 中使用 tableData

<el-table :data="tableData" class="tablePst">
 <el-table-column label="登录名" prop="loginname"></el-table-column>
 <el-table-column label="真实姓名" prop="realname"></el-table-column>
</el-table>

这样的话,就会出现数据改变不渲染的问题

问题

要解决问题,就得理解vue生命周期,页面加载前 tableData 获取 store 里的值赋给自己,这样 tableData 只有一初始值,后续vuex中状态发生改变,并不会再次赋值给 tableData ,除非页面刷新重新加载,组件生命周期重新开始,才能拿到最新的值

解决

1.去掉组件中 tableData 的状态,在模板中直接使用 $store.state.AdminInfo 这样就能随时拿到最新的状态值了

<el-table :data="$store.state.AdminInfo" class="tablePst">
 <el-table-column label="登录名" prop="loginname"></el-table-column>
 <el-table-column label="真实姓名" prop="realname"></el-table-column>
</el-table>

2.使用mapState,把vuex中的状态暴露给组件,再使用,具体见文档 vuex mapState官方文档.

补充知识:解决vue修改数据页面不重新渲染问题(Vue中数组和对象更改后视图不刷新)

vue渲染机制和如何解决数据修改页面不刷新问题的多种方法

本文不讲原理,只讲干货易懂易学,(感觉能学到知识,麻烦给小编来个赞!)

首先 第一点,vue底层是 将data对象传人,使用Object.definePropety,转换为getter和setter,所以,vue不支持IE8.

1.简单介绍一下Object.definePropety,

Object.defineProperty(obj, prop, descriptor)

//参数

obj

要在其上定义属性的对象。

prop

要定义或修改的属性的名称。

descriptor

将被定义或修改的属性描述符

var obj = {}
 Object.defineProperty(obj, 'name', {
  get: function() {
   console.log('我的名字叫'+name);
   return name;
  },
  set: function(value) {
   console.log('你叫'+value)
   name = value;
  }
 });
  obj.name ='张三';//你叫张三
  obj.name//我的名字叫张三

从上述我们可以简单发现。当我们对这个对象的name属性赋值的时候,就会触发set方法,获取name属性的时候就会触发get方法;

2.因此在vue中写在data中的属性是是可以转换成getter和setter,换一句话就是响应式的,其他定义在data之外的数据,是无法响应的渲染,意思就是改变数据页面也不会刷新,所以一切要渲染到页面上的数据,必须写在data中,

不需要的,可以定义在this上,

var vm = new Vue({
 data:{
  a:1
 }
})

// `vm.a` 是响应式的

vm.b = 2
// `vm.b` 是非响应式的

3.简单介绍完了,我们来列举几个不刷新的实例当然上述也是一种

第一种:修改对象的某一属性

vue只会将已经在data中声明的属性变为响应,没有声明的是不响应的

<template>
 <div>
   <div v-for='item in list'>{{item}}</div>
   <button @click='click'>改变</button>
   <button @click='hadelClick'>解决方法</button>
 </div>
</template>
<script>
 export default({
  data(){
   return{
    list:{a:'a',b:'b'},
   }
  },
  methods: {
     click() {
     // 未声明不触发渲染
      this.list.c='c'

     },
     hadelClick(){
      // 解决方法,使用vue提供的$set方法来触发渲染
      this.$set(this.list,'d','d')
     }
    }
 })  
</script>

当然如果我们要添加多个属性,可以使用 Object.assign() 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,并返回目标对象。(简单说就是合并到第一个参数中)

this.list = Object.assign({},this.list,{c:'c',d:'d'})

第二种:修改数组对象的某一属性

<template>
 <div>
   <div v-for='item in list'>{{item.a}}</div>
   <button @click='click'>改变</button>
   <button @click='hadelClick'>解决方法</button>
 </div>
</template>
<script>
 export default({
  data(){
   return{
    list:[{a:'vue'},{a:'react'},{a:'js'}],
   }
  },
  methods: {
     click() {
      //想这样直接给数组中的某一个对象直接赋值,是无法动态渲染的(即改变了数据,页面不渲染)
      this.list[0] = {a:'css'} //页面不渲染
      console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
     },
     hadelClick(){
      // 解决方法,使用vue提供的$set方法来触发渲染
      this.$set(this.list[1],'a','css')
      console.log(this.list)//[{a:'css'},{a:'css'},{a:'js'}]
     }
    }
 })  
</script>

当然前文讲过,vue会遍历data中的数据,将对象转换成setter和getter。所以数组中的也不例外,所以上述操作

改成:

click(){
 this.list[0].a = css //依旧能够触发setter。实现数据重新渲染
  }
}

在vue中更多的是数组的操作不刷新,一种是通过索引赋值,一种是修改数组长度,如何解决呢?

vue官方也给了方法

数组的API,中能够改变原始数组的都能触发更新;

1、push()

2、pop()

3、shift()

4、unshift()

5、splice()

6、sort()

7、reverse()

第二种是返回一个新数组的,这种数组在引用地址上已经发生根本改变,这样的赋值操作是能触发更新的(这是处理不刷新的思路,就是改变引用地址,重新赋值触发更新)

简单说,用数组的API就是直接用原数组接收改变的数组,

<template>
 <div>
   <div v-for='item in list'>{{item.a}}</div>
   <button @click='click'>改变原数组</button>
   <button @click='hadelClick'>不改变原数组</button>
 </div>
</template>
<script>
 export default({
  data(){
   return{
    list:[{a:'vue'},{a:'react'},{a:'js'}],
   }
  },
  methods: {
     click() {
      //改变数组刷新页面
       this.list.push({a:'css'})
     },
     hadelClick(){
    //重新赋值刷新页面   
      this.list = this.list.map(item=>{
         item.a = 'css'
         return item
        })
    }
 })  
</script>

最后提供解决思路(以上都搞不定的话)

对象和数组都是引用传递,要变成新数组,来接受,就需要改变源,

第一种

let arr = []//新数组
this.list.forEach(item=>{ //需要渲染的数组
  //执行你的操作,最后用放到arr中
  arr.push(item)
})
this.list = arr //相当于返回一个新数组可以触发渲染

第二种

//想要直接改变渲染数组中的数据,但没有渲染
//解决方法:
let arr = this.list.slice(0);//深拷贝,(等价一个新的数组)
arr.forEach(item=>{
  //执行你的操作
})
//赋值操作
this.list = arr

当然这里只是简单介绍了,有关深拷贝的详细介绍,还请自行百度

上述如果都无法执行,但你的数据缺实修改了,可以使用this.$forceUpdate()方法 (强制刷新)

//this.$forceUpdate();//强制刷新

<template>
 <div>
   <div v-for='item in list'>{{item.a}}</div>
   <button @click='click'>改变</button>
   <button @click='hadelClick'>解决方法</button>
 </div>
</template>
<script>
 export default({
  data(){
   return{
    list:[{a:'vue'},{a:'react'},{a:'js'}],
   }
  },
  methods: {
     click() {
      this.list[0] = {a:'css'} //页面不渲染
      console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
     },
     hadelClick(){
      this.list[0] = {a:'css'} //页面不渲染
      console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
       this.$forceUpdate();//强制刷新
     }
    }
 })
  
</script>

以上这篇vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery isType() 类型判断代码
Feb 14 Javascript
Jquery显示、隐藏元素以及添加删除样式
Aug 09 Javascript
Javascript实现简单二级下拉菜单实例
Jun 15 Javascript
深入分析js的冒泡事件
Dec 05 Javascript
js如何判断输入字符串长度
Dec 16 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
Oct 27 Javascript
从零学习node.js之模块规范(一)
Feb 21 Javascript
Vue.js 60分钟快速入门教程
Mar 28 Javascript
vue-ajax小封装实例
Sep 18 Javascript
Vue.directive 自定义指令的问题小结
Mar 04 Javascript
详解mpvue开发小程序小总结
Jul 25 Javascript
vue前端框架—Mint UI详解(更适用于移动端)
Apr 30 Javascript
基于Vue+Webpack拆分路由文件实现管理
Nov 16 #Javascript
小程序实现上下切换位置
Nov 16 #Javascript
小程序实现点击tab切换左右滑动
Nov 16 #Javascript
微信小程序实现滚动Tab选项卡
Nov 16 #Javascript
小程序实现tab标签页
Nov 16 #Javascript
vue+Element-ui实现登录注册表单
Nov 17 #Javascript
Vue+Element-U实现分页显示效果
Nov 15 #Javascript
You might like
颠覆常识!无色透明的咖啡诞生了(中日双语)
2021/03/03 咖啡文化
实现php加速的eAccelerator dll支持文件打包下载
2007/09/30 PHP
Yii中render和renderPartial的区别
2014/09/03 PHP
一个经典的PHP验证码类分享
2014/11/18 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
基于jQuery的动态表格插件
2011/03/28 Javascript
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
2014/05/29 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
浅谈javascript回调函数
2014/12/07 Javascript
jQuery检测返回值的数据类型
2015/07/13 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
2016/12/28 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
2017/07/18 Javascript
JavaScript原型链与继承操作实例总结
2018/08/24 Javascript
Vue核心概念Action的总结
2019/01/18 Javascript
VUE.js实现动态设置输入框disabled属性
2019/10/28 Javascript
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
2020/05/14 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
Vue性能优化的方法
2020/07/30 Javascript
Python代码调试的几种方法总结
2015/04/15 Python
python3实现全角和半角字符转换的方法示例
2017/09/21 Python
Python scipy的二维图像卷积运算与图像模糊处理操作示例
2019/09/06 Python
python lambda表达式(匿名函数)写法解析
2019/09/16 Python
tensorflow 实现自定义梯度反向传播代码
2020/02/10 Python
python实现银行账户系统
2021/02/22 Python
怎样实现H5+CSS3手指滑动切换图片的示例代码
2019/05/05 HTML / CSS
初中三好学生自我鉴定
2014/04/07 职场文书
《画杨桃》教学反思
2014/04/13 职场文书
爱护公共设施演讲稿
2014/09/13 职场文书
科技馆观后感
2015/06/08 职场文书
教师师德工作总结2015
2015/07/22 职场文书
Android中View.post和Handler.post的关系
2022/06/05 Java/Android
nginx sticky实现基于cookie负载均衡示例详解
2022/12/24 Servers