likes
comments
collection
share

数据,方法,计算属性和侦听器

作者站长头像
站长
· 阅读数 15

数据

data中return的数据都可以在模板中使用

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
        }
    },
    template: `
        <div>{{message}}</div>
    `
})
const vm = app.mount('#root')

修改data中变量值的方法:

  • vm.$data.message = 'bye'
  • vm.message = 'bye world'

方法

注意:

  • 方法中this指向为vue组件的实例(也就是 Vue.createApp()返回的对象)
  • 不能在methods中使用箭头函数的方法来声明函数,否则this指向就变成了window(箭头函数自己没有this)

vue中的方法不是只可以绑定事件,还可以把调用函数的返回作为表达式放到模板的插值表达式中

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
        }
    },
    methods:{
        formatString(string) {
            return string.toUpperCase()
        }
    },
    template: `
        <div @click="handleClick">{{formatString(message)}}</div>
    `
})
const vm = app.mount('#root')

计算属性

基本使用

计算属性是经过data中关联变量值计算得到的变量,它是属性,而不是方法,同在data中定义的变量一样,只不过它的值是动态的可变的

计算属性定义在computed对象中

eg: 商品的价格和数量计算商品的总价

为了让代码更具有语义化,就不将price和count的乘积放到模板字符串中展示了,而是使用变量total表示总价,但是下面的vue不支持下面total的写法

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
            count: 2,
            price: 5,
            total: count * price
        }
    },
    template: `
        <div>{{total}}</div>
    `
})
const vm = app.mount('#root')

vue为我们提供了计算属性来解决类似上面的问题

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
            count: 2,
            price: 5,
            // 相当于在这声明了total
        }
    },
    computed:{
            total() {
                return this.price * this.count
            }
    },
    template: `
        <div>{{total}}</div>
    `
})
const vm = app.mount('#root')

当total关联的变量countprice 的值发生变化时,则total就自动重新计算,这就是计算属性的作用

计算属性和方法的区别

使用方法重新实现一遍上面的效果

const app = Vue.createApp({
      data() {
          return {
              message: 'hello world',
              count: 2,
              price: 5,
          }
      },
      computed:{
              total() {
                  return this.price * this.count
              }
      },
      methods:{
          getTotal() {
              return this.price * this.count
          }
      },
      template: `
          <div>{{getTotal()}}</div>
      `
  })
const vm = app.mount('#root')

乍一看好像和计算属性实现的效果一样啊

修改下代码或许就能看出它们之间的差异:

使用计算属性实现

const app = Vue.createApp({
   data() {
       return {
           message: 'hello world',
           count: 2,
           price: 5,
       }
   },
   computed:{
           total() {
               return Date.now() + this.count
           }
   },
   methods:{
       getTotal() {
           return Date.now() + this.count
       }
   },
   template: `
       <div>{{message}} --- {{total}}</div>
   `
})
const vm = app.mount('#root')

message值未修改时的时间戳

数据,方法,计算属性和侦听器

message值修改后的时间戳

数据,方法,计算属性和侦听器

我们发现修改message的值页面重新渲染,但是计算属性不会重新执行

使用方法实现

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
            count: 2,
            price: 5,
        }
    },
    computed:{
            total() {
                return Date.now() + this.count
            }
    },
    methods:{
        getTotal() {
            return Date.now() + this.count
        }
    },
    template: `
        <div>{{message}} --- {{getTotal()}}</div>
    `
})
const vm = app.mount('#root')

message值未修改时的时间戳

数据,方法,计算属性和侦听器

message值修改后的时间戳

数据,方法,计算属性和侦听器

使用方法后,当我们修改messgae的值后我们发现返回的时间戳变了,说明getTotal()方法被重新执行了一次

总结: 计算属性和方法的区别

  • 当计算属性依赖的变量发生变更时,才会重新执行计算
  • 只要页面重新渲染,方法就会被重新执行和计算

计算属性的特色是内部带有缓存机制,因此在渲染的时候它会更高效

侦听器watch

基础使用

一般遇到异步的情况可以使用侦听器watch去解决,当侦听器中的变量值发生变化时,侦听器中与变量对应的函数会自动执行

使用watch监听变量的改变,并做一些异步的操作

使用方法:在watch对象中重新定义data中的变量,同计算属性一样,也要写成函数的形式

eg: 监听data中的price,如果它发生变化,2秒后就打印一个值

const app = Vue.createApp({
        data() {
            return {
                message: 'hello world',
                count: 2,
                price: 5,
            }
        },
        watch:{
            price() {
                setTimeout(() => {
                    console.log('data中的price发生了变化');
                }, 2000);
            }
        },
        computed:{
                total() {
                    return Date.now() + this.count
                }
        },
        methods:{
            getTotal() {
                return Date.now() + this.count
            }
        },
        template: `
            <div>{{message}} --- {{getTotal()}}</div>
        `
    })
const vm = app.mount('#root')

数据,方法,计算属性和侦听器

使用侦听器实现之前计算属性的例子

const app = Vue.createApp({
    data() {
        return {
            message: 'hello world',
            count: 2,
            price: 5,
            newTotal: 10
        }
    },
    watch:{
        price(current,prev) {
            this.newTotal = current * this.count
        }
    },
    computed:{
            total() {
                return Date.now() + this.count
            }
    },
    methods:{
        getTotal() {
            return Date.now() + this.count
        }
    },
    template: `
        <div>{{message}} --- {{newTotal}}</div>
    `
})
const vm = app.mount('#root')

price值修改之前

数据,方法,计算属性和侦听器

price值修改之后 数据,方法,计算属性和侦听器

从上面可以发现,当price发生变化时watch侦听器中的price函数会自动执行

侦听器watch实际上是侦听器底层的实现逻辑

那么侦听器watch和计算属性的区别?

如果在侦听器中不做一些异步操作,那么同计算属性比较,实现方式就显得冗余

总结

  • computed计算属性和methods中方法都能实现的功能,建议使用computed,因为计算属性有缓存性能更佳
  • computed计算属性和侦听器watch都是实现的功能,建议使用computed,因为计算属性更加简洁(侦听器的优势是监听数据变化后做一些异步操作)
  • 在实际开发中能用computed计算属性实现的功能,就有计算属性,实现不了的再使用watch侦听器和methods方法