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

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数据改变,组件中页面不渲染操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解决vuex刷新数据消失问题

    前言 vue构建的单页大型项目中,可能会用到Vuex .Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新. 但是有一个问题就是:vuex的存储的数据只是在页面的中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态.但是这个情况有时候并不是我们所希望的. 比如,用户已经登录了,我把登录状态放到state中了,一刷新页面,还要重新登录?购物车里的添加的数据,一刷新要重新添加? 解

  • 解决vue数据不实时更新的问题(数据更改了,但数据不实时更新)

    一.在我们使用vue进行开发的过程中,可能会遇到一种情况: 当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: 向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新.它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 ,需要用vue内置的方法 二.Vue.set() 响应式新增与修改数据 此时我们需要知道Vue.set()需要哪些参数,官方API:https://cn.vuejs.org/v2/api/#Vue-set 调用方法:

  • vue 组件中添加样式不生效的解决方法

    如何产生 在开发项目中遇到在组件中添加样式不生效的情况.具体场景如下 //// vue 组件 <template> <div class="box" data-v-33f8ed40></div> <template> //我用js在上面div标签中插入一个<p class='text'>text goes here</p> <script> export default { ... mounted(){

  • 解决vuex改变了state的值,但是页面没有更新的问题

    当state里属性定义为obj类型时,有时候出现:在其他页面修改完state值之后,其他页面并没有同步更新. 这时候需要转换一下.JSON.parse(JSON.stringify(obj)) this.$store.dispatch("setGlobalUserInformation",JSON.parse(JSON.stringify(obj))) 补充知识:一个"错误"的vuex写法:vuex刷新了数据但是视图没有刷新 这是个很尴尬的问题,让我猜猜看你的代码是

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

    vuex数据改变,组件中页面不渲染 相信许多vuex新手都会遇到这样的问题: vuex数据更新后,插件中使用数据的地方没有更新 这样的代码 data() { return { tableData: this.$store.state.AdminInfo }; } 然后在 template 中使用 tableData <el-table :data="tableData" class="tablePst"> <el-table-column labe

  • C#.NET中如何批量插入大量数据到数据库中

    在WEB项目开发过程中有时会碰到批量插入数据到数或者是将EXCEL文件据入到数据库中.为了方便实现可以先将EXCEL导入到GRIDVIEW中然后一次批量插入.实现代码如下: 前台代码 <asp:GridView ID="dgBom" runat="server" AutoGenerateColumns="false" CellPadding="1" CellSpacing="2"> <He

  • 浅析JS中什么是自定义react数据验证组件

    我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题.如果用户提交的数据不合法,例如格式不正确.非数字类型.超过最大长度.是否必填项.最大值和最小值等等,我们需要在相应的地方给出提示信息.如果用户修正了数据,我们还要将提示信息隐藏起来. 有一些现成的插件可以让你非常方便地实现这一功能,如果你使用的是knockout框架,那么你可以借助于Knockout-Validation这一插件.使用起来很简单,例如我下面的这一段代码: ko.validation.locale('zh-CN');

  • 封装一个vue中也可使用的uniapp的全局弹窗组件(任何页面都可以弹出)

    目录 效果图: 场景: 思路: 第一步: 第二步: 第三部:使用 总结 效果图: 场景: 当你对接websocket时,或者轮询也好,你需要获取到最新的信息,并且在任何页面弹出一个组件进行后续操作 思路: 1.先封装好要弹出的公共组件 2.向vue原型上挂载全局方法,拿到组件真实dom,从而对组件进行显隐操作 第一步: 创建一个公共组件,以下是组件全部的结构及样式,你需要把html中的两个image标签的路径换掉或者直接注释掉也行,html 和 css就不做解释了 invite.vue <tem

  • 在vue中对数组值变化的监听与重新响应渲染操作

    在我们项目开发过程中,实例中的数据类型可以是对象.数组等.在对象中,某个属性值发生更改时,我们可以通过对象的深度监听,以达到重新渲染页面的需求.或者查阅这篇文章 例如: <script> export default { data(){ return { objVal: { name: 'obj', type: 'obj' } } }, watch:{ objVal:{ handler(val,oldval){ }, deep: true, } }, methods:{ changeObj()

  • vue组件中的数据传递方法

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递.组件之间传递数据大致分为三种情况: 父组件向子组件传递数据,通过 props 传递数据. 子组件向父组件传递数据,通过 events 传递数据. 两个同级组件之间传递数据,通过 event bus 传递数据. 一.父组件向子组件传递数据 子组件部分: <template> <div class="child"> {{ msg }} </

  • Java 如何从list中删除符合条件的数据

    目录 从list中删除符合条件的数据 删除list中某个特定元素 从list中删除符合条件的数据 在Java语言使用中经常会遇到需要从list中去除一些数据,但是初学者经常会遇到如下的坑: Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 4 at java.util.ArrayList.rangeCheck(Unknown Source) at java.util.Array

  • 使用加载图片解决在Ajax数据加载中页面出现短暂空白的问题(推荐)

    在项目中用ajax异步获取数据后有时会因为数据问题或者网络问题,页面一直显示空白,现在用加载图片来过渡这种状态: <script> $(function(){ $.ajax({ url:'',//提供接口的文件地址链接 dataType:'json', type:'POST', beforeSend: function(){ $('#loading').html("<img src=\"images/loading.gif\" width=\"15

  • 微信小程序自定义组件传值 页面和组件相互传数据操作示例

    本文实例讲述了微信小程序自定义组件传值 页面和组件相互传数据操作.分享给大家供大家参考,具体如下: 要想在组件中调到页面中的方法,并且想要组件中传数据到页面去,emmmm,可以酱紫: 用组件事件 triggerEvent! 首先,在页面中定义组件 ,json文件中记得加上: { "usingComponents": { "user-btn": "/pages/component/userInfo/userInfo" } }, 然后,index.w

  • 解决vue 单文件组件中样式加载问题

    在写单文件组件时,一般都是把标签.脚本.样式写到一起,这样写个人感觉有点不够简洁,所以就想着把样式分离出去. 采用import加载样式 在局部作用域(scoped)采用@import加载进来的样式文件,想法是美好的.以为这样加载进来的样式文件也只对当前组件有效:可现实是残酷的,这样加载进来的样式无法限制其作用域. <style scoped> @import "样式文件"; </style> 解决方案 采用 src属性加载样式. <style src=&q

随机推荐