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 相关文章推荐
汉化英文版的Dreamweaver CS5并自动提示jquery
Nov 25 Javascript
javascript实现文字图片上下滚动的具体实例
Jun 28 Javascript
jquery获取元素索引值index()示例
Feb 13 Javascript
js数组如何添加json数据及js数组与json的区别
Oct 27 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
Jan 18 Javascript
Bootstrap学习笔记之进度条、媒体对象实例详解
Mar 09 Javascript
js实现一个猜数字游戏
Mar 31 Javascript
SpringMVC简单整合Angular2的示例
Jul 31 Javascript
React Native悬浮按钮组件的示例代码
Apr 05 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
Apr 29 Javascript
vue input标签通用指令校验的实现
Nov 05 Javascript
关于vue 结合原生js 解决echarts resize问题
Jul 26 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
解析在apache里面给php写虚拟目录的详细方法
2013/06/24 PHP
php环境无法上传文件的解决方法
2014/04/30 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
2015/10/23 PHP
php进行ip地址掩码运算处理的方法
2016/07/11 PHP
php实现的网页版剪刀石头布游戏示例
2016/11/25 PHP
php微信公众平台示例代码分析(二)
2016/12/06 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
(function(){})()的用法与优点
2007/03/11 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
2012/09/14 Javascript
js优化针对IE6.0起作用(详细整理)
2012/12/25 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
jquery 列表双向选择器之改进版
2013/08/09 Javascript
JavaScript图片放大技术(放大镜)实现代码分享
2013/11/14 Javascript
如何调试异步加载页面里包含的js文件
2014/10/30 Javascript
详解JavaScript逻辑And运算符
2015/12/04 Javascript
JS刷新父窗口的几种方式小结(推荐)
2016/11/09 Javascript
AngularJS表格添加序号的方法
2017/03/03 Javascript
three.js中文文档学习之通过模块导入
2017/11/20 Javascript
vue的安装及element组件的安装方法
2018/03/09 Javascript
微信小程序时间控件picker view使用详解
2018/12/28 Javascript
vue路由传参页面刷新参数丢失问题解决方案
2019/10/08 Javascript
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
使用python实现rsa算法代码
2016/02/17 Python
python读写配置文件操作示例
2019/07/03 Python
Pytorch对Himmelblau函数的优化详解
2020/02/29 Python
HTML5+JS实现俄罗斯方块原理及具体步骤
2013/11/29 HTML / CSS
TripAdvisor土耳其网站:全球知名旅行社区,真实旅客评论
2017/04/17 全球购物
大一学生的职业生涯规划书范文
2014/01/19 职场文书
行政专员的岗位职责
2014/03/10 职场文书
村党支部换届选举方案
2014/05/02 职场文书
公共场所禁烟标语
2014/06/25 职场文书
2014年人力资源工作总结
2014/11/19 职场文书
治庸问责工作总结
2015/08/11 职场文书