uniapp更改组件值页面不更新怎么回事

uniapp更改组件值页面不更新怎么回事

在uniapp开发中,页面的数据处理是必不可少的,我们需要动态地改变页面中某些组件的值。但有时候发现,即使我们已经更改了组件的值,但是页面并没有更新,那么这种情况是因为什么呢?接下来就让我们来探讨一下uniapp更改组件值页面不更新的问题。

1. uniapp数据响应式系统

首先,我们需要了解uniapp的数据响应式系统是什么。我们知道,在vue框架中,数据响应式系统利用了ES5的Object.defineProperty()方法来实现双向绑定。而在uniapp当中,虽然在底层也是用了Object.defineProperty()方法,但是在使用过程中会有所不同。在uniapp中,我们使用的是this.setData()方法来更新数据,而this.setData()方法则会调用内部的响应式系统,决定了组件如何更新。

从这里我们也可以看到,uniapp中的数据处理是非常重要的。除了this.setData()方法外,还有computed属性、watcher等。注意,这些特性,只有组件的data中的属性才能享受到他们的便利。

2. 引用类型的数据在setData()中的问题

在uniapp中,我们需要注意的是,在this.setData()方法中仅会触发那些有对应 setData() 的数据改变。因此,this.setData() 只能改变组件中根 data 下的数据,而无法改变嵌套的对象或数组。这里的嵌套对象或数组指的是类似于以下代码的情况。

data: {

obj: {

name: 'Jack',

age: 18

}

},

// 更改obj的数据

this.setData({

obj: {

name: 'Tom'

}

})

这种情况下,更改数据的操作是不会生效的,因为在setData()方法中,只会更新根data中的数据。

那如果需要在setData()中修改嵌套对象或数组的数据怎么办呢?这时我们需要借助ES6的扩展运算符将原对象解构出来,然后修改其指定的属性,最后再使用this.setData()来更新。

// 更改obj的数据

this.setData({

obj: {

...this.data.obj,

name: 'Tom'

}

})

3. 封装组件导致页面不更新的问题

与引用类型的数据有关的问题解决了,但还有一种情况,就是使用封装组件时,会出现页面不更新的问题。

假设我们有以下简单的组件:

<template>

<view class="my-component">

<view>组件中的数据:{{msg}}</view>

<button @click="changeMsg">改变数据</button>

</view>

</template>

<script>

export default {

data() {

return {

msg: '这是组件的数据'

}

},

methods: {

changeMsg() {

// 改变组件数据

this.msg = '改变后的数据'

}

}

}

</script>

<style>

.my-component {

background-color: #ddd;

padding: 10px;

text-align: center;

}

</style>

我们可以发现,在这个组件中,点击按钮会触发changeMsg()方法,改变this.msg的值。

changeMsg() {

this.msg = '改变后的数据'

}

但是,如果我们在外部使用这个自定义组件,发现点击按钮并没有改变 {{msg}} 的值。屏幕上的文本仍然是“这是组件的数据”。

这是因为自定义组件中如果需要更改自身数据,必须使用 this.$emit() 方法触发自定义事件,然后从父级传递参数给自身组件,这样才能达到更新数据的效果。这就是自定义组件的数据更新问题。

<template>

<view class="my-component">

<view>组件中的数据:{{msg}}</view>

<button @click="changeMsg">改变数据</button>

</view>

</template>

<script>

export default {

data() {

return {

msg: '这是组件的数据'

}

},

methods: {

changeMsg() {

// 触发事件改变数据

this.$emit('changeMsg', '改变后的数据')

}

}

}

</script>

<style>

.my-component {

background-color: #ddd;

padding: 10px;

text-align: center;

}

</style>

在父组件中,我们需要监听自定义事件,并在事件处理程序中调用 this.setData() 方法更新组件的数据。

<template>

<view>

<my-component :msg="content" @changeMsg="changeMsg"></my-component>

</view>

</template>

<script>

import MyComponent from '@/components/MyComponent.vue';

export default {

components: {

MyComponent

},

data() {

return {

content: '从父组件中传递的数据'

}

},

methods: {

changeMsg(val) {

this.setData({

content: val

})

}

}

}

</script>

<style scoped>

page {

background-color: #fff;

padding: 10px;

}

</style>

这样以来,就完成了自定义组件数据更新过程。

总结

在uniapp开发过程中,组件的数据处理是非常重要的。采用this.setData()方法来更新数据时,需要注意数据的嵌套类型以及自定义组件的数据更新,以免页面不更新的问题。

引用类型的数据需要注意,采用ES6的扩展运算符来解构对象,并修改变化的属性。而在封装组件时,需要使用 this.$emit() 方法触发自定义事件,并在事件处理程序中调用 this.setData() 方法来更新父组件传递的数据。