vue 获取到数据但却渲染不到页面上

能获取到数据 数据却渲染不到页面上

问题描述: 数据改变了,数据打印出来都正确,但是页面里面就是不显示、没变化。

很多时候对数据进行处理了,但是页面上就是没变化,没效果,用 console.log 打印数据都没问题,特别是数组、对象容易出现这个问题;

解决方法

1、 this.$set( xxx )

Vue.set( target, propertyName/index, value )
//this.$set(item, 'pics', pics) 

保存变量,(向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性)

2、 this.$delete( xxx )

Vue.delete( target, propertyName/index ) 

删除对象的属性,(如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它)

3、this.$forceUpdate( xxx )

强制更新,迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

问题原因

这个就需要了解 Vue 是如何实现数据的响应式, vue响应式实现分为两块:对象和数组

对象

Vue 让 对象 数据变得“可观测” 是通过重写 Object.defineProperty()方法中的 get 和 set 方法; 在getter中收集依赖,在setter中通知依赖更新,至于怎么创建的、怎么去通知 dom 更新有兴趣的同学可以去看看源码;

不足: 虽然 vue 递归了对象属性并添加了依赖,但是当我们向object数据里添加一对新的key/value或删除一对已有的key/value时,它是无法观测到的,导致当我们对object数据添加或删除值时,无法通知依赖,无法驱动视图进行响应式更新;为了解决这一问题,Vue增加了两个全局API:Vue.set和Vue.delete;

数组

Vue 让 数组 数据变得“可观测” 与对象类似,Vue 中创建了一个数组操作方法的拦截器 push,pop,shift,unshift,splice,sort,reverse 重写了这些操作数组的方法,当调用这些方法时也是在getter中收集依赖,在setter中通知依赖更新;

不足: 通过数组下标修改数组中的数据、通过修改数组长度清空数组,这种操作方式来修改数组是无法侦测到的,但是同样可以使用Vue.set和Vue.delete 来解决这个问题; Object.defineProperty 举例:

在这里插入图片描述

代码如下

let data = {}
let title= '动态变化的标题'
Object.defineProperty(data, 'title', {
  enumerable: true,
  configurable: true,
  get(){
    console.log('title属性被读取了')
    return title
  },
  set(newVal){
    console.log('title属性被修改了')
    // 去更新dom
    title= newVal
  }
}) 
Vue中使用axios获取数据成功却无法渲染页面,可能存在以下原因: ### 上下文问题 在axios的回调函数里,`this` 指向可能并非Vue实例。像下面的代码: ```javascript axios.get("/baseData") .then(function (data) { // 此this或许并非指向Vue实例 this.reelSizeMap = data.data.reelSizeMap; }); ``` 在这种情况下,`this` 指向的是 `then` 函数内部,而非Vue实例。可以采用箭头函数或者提前保存 `this` 来解决该问题: ```javascript // 使用箭头函数 axios.get("/baseData") .then((data) => { this.reelSizeMap = data.data.reelSizeMap; }); // 提前保存this const self = this; axios.get("/baseData") .then(function (data) { self.reelSizeMap = data.data.reelSizeMap; }); ``` ### 数据响应式问题 Vue的响应式系统依赖于对象属性的初始化。若在数据对象里未预先定义属性,之后添加的属性可能不会触发视图更新。例如: ```javascript export default { data() { return { // 这里没有定义reelSizeMap }; }, mounted() { axios.get("/baseData") .then((data) => { // 此操作可能不会触发视图更新 this.reelSizeMap = data.data.reelSizeMap; }); } }; ``` 要在 `data` 函数中预先定义属性: ```javascript export default { data() { return { reelSizeMap: {} }; }, mounted() { axios.get("/baseData") .then((data) => { this.reelSizeMap = data.data.reelSizeMap; }); } }; ``` ### 生命周期钩子问题 若在错误的生命周期钩子中发起请求,可能会致使数据获取后无法正确渲染。例如,在 `created` 钩子中发起请求,但此时DOM尚未挂载,可能会出现问题。建议在 `mounted` 钩子中发起请求: ```javascript export default { data() { return { userInfo: {} }; }, mounted() { axios.get('/path/to/data.json') .then(response => { this.userInfo = response.data; }) .catch(error => { console.error(error); }); } }; ``` ### 异步操作问题 axios是异步操作,若在数据还未获取到之前就进行渲染页面可能显示为空。要保证在数据获取完成后再进行渲染,可以使用 `v-if` 指令: ```html <template> <div> <div v-if="userInfo.name"> <h1>{{ userInfo.name }}</h1> <p>Age: {{ userInfo.age }}</p> <p>Email: {{ userInfo.email }}</p> </div> <div v-else> Loading... </div> </div> </template> ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值