多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 计算属性 在模板中,我们可以绑定简单的属性键值。但实际上,是为兼容平台差异,uni-app无法支持复杂的 JavaScript 表达式。复杂一点的表达式都需要使用计算属性来实现,合理的使用计算属性可以是增加代码的可读性。 下面的代码段定义了属性name和计算属性message,这里使用了计算属性默认的getter ``` export default { data: { name: '' }, computed: { message() { return `Hello, ${this.name}`; } }, } ``` 模板内的表达式非常便利,uni-app不支持复杂的 JavaScript 渲染表达式,目前可以使用的有`+ - * % ?: ! == === > < [] .`。 ``` <!-- 这种就不支持,建议写 computed --> <view>{{ message.split('').reverse().join('') }}</view> ``` 所以,对于任何复杂逻辑,你都应当使用计算属性。下面的示例声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 reversedMessage 的 getter 函数。 > 计算属性有setter和getter,因为setter很少用到,默认是getter。 ``` <template> <view class="content"> <view> <input type="text" v-model="message" placeholder="消息" /> </view> <view> <text class="message">{{ reversedMessage }}</text> </view> </view> </template> <script> export default { data: { message: 'Hello world!', }, computed: { reversedMessage: function() { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } } </script> <style> .content { display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center; } input { border-bottom: 1upx solid; } .message { font-size: 60upx; font-weight: bold; } </style> ``` 程序在微信小程序模拟器上运行的效果如图所示,右侧的监视器可以看到变量的值。 ![](https://box.kancloud.cn/b469ec9fa0938a1c3d24603ccc400c24_1034x782.png) # watch、model 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 组件的属性(props)通过侦听器可以实现双向绑定的效果,将组件内部的状态变更通知父组件,但是要实现双向绑定,一般还需要配合v-model指令。 首先需要定义v-model指令关联的属性以及促发模型属性更新的事件,实现属性result的双向绑定功能。 ``` model: { prop: 'result', event: 'toFather' }, ``` 为了实现组件内部状态的变更能够实时通知父组件,首先需要创建props属性result的副本—myResult ``` data() { return { myResult: this.result, } }, ``` 组件内部的data要写成函数的形式,然后监听外部对属性result的变更,并同步到组件内的data属性myResult中 ``` watch: { result(val) { this.myResult = val } } ``` 最后,组件内对myResult变更后向外部发送事件通知 ``` watch: { myResult (val) { this.$emit('toFather', val) } } ``` 在父组件中通过监听事件toFather来观察子组件的状态变化。 组件定义代码:components/switch-button.vue ``` <!-- 开关组件代码 --> <template> <view @click='change' style="padding: 20upx; border: #8F8F94 solid 1px;">{{result?'开':'关'}}</view> </template> <script> export default { model: { prop: 'result', event: 'toFather' }, props: { result: { type: Boolean, default: false }, }, methods: { change() { this.result = !this.result; } }, data() { return { myResult: this.result, } }, watch: { result(val) { console.log("inner result" + val); this.myResult = val }, myResult(val) { //通知父组件,状态更新了 this.$emit('toFather', val) } } } </script> ``` 调用组件的代码:pages/lab/gramma/switch-button.vue 外层调用组件方注册变更方法, ``` <template> <view> <!--开关组件--> <switch-button v-model="status" @toFather="toFather"></switch-button> <!--外部控制--> <input type="button" value="外部变更状态" @click="change"> <text>{{ status }}</text> </view> </template> <script> import switchButton from 'components/switch-button.vue' export default { data: { status: true //开关状态数据 }, methods: { change() { this.status = !this.status; }, toFather(status) { console.log(status) } }, components: { switchButton, }, } </script> <style> view { display: block; } </style> ``` ``` <switch-button v-model="status" @toFather="toFather"></switch-button> ``` 将组件内的数据变更,同步到组件外的数据状态中 ``` methods: { toFather(status) { console.log(status); } }, ``` ![](https://box.kancloud.cn/73d632e18587395b539c8ad096460502_338x181.png) 组件内部和外部变更状态内外都会同步。