Vue3.x 全家桶 | 07 - Vue 的 Options API : method

325 阅读3分钟

iShot_2023-12-21_18.33.21.png

一、Vue 的 Options API : method

上篇文章中提到的 Options API 的核心选项之一就包含了 methods 选项,methods 是一个用于定义方法的选项。methods 中包含了一组方法,这些方法可以在 Vue 组件的模板中被调用。每个方法都是一个函数,可以执行一些特定的逻辑。

methods 是一个对象类型,这个对象的每个属性都是一个个的函数,比如在计数器的案例中我们就在 methods 中定义了两个函数。

这些函数可以绑定到模板中,并且可以通过 this 关键字直接访问到 data 选项中返回的对象的属性。

创建一个 HTML 页面,实现一个类似计数器的功能,在该页面中通过两个按钮来对 data 选项中返回的 volume 变量记性操作,通过 methods 选项中定义的两个方法实现,具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
    <div id="app">
      <h1>Tesla Model 3 Sales: {{ volume }}</h1>
      <button v-on:click="increaseSales"> +1000 Sales</button>
      <button v-on:click="decreaseSales"> -1000 Sales</button>
    </div>

  <script src="../lib/vue.js"></script>
  <script>
    const app = Vue.createApp({
      data() {
        console.log("data选项中传入的函数执行了!")
        return {
          volume: 0
        }
      },
      methods: {
        increaseSales(){
          console.log("methods 选项中的 increaseSales 函数被调用了")
          // 输出 this
          console.log(this)
          this.volume+=1000
        },
        decreaseSales(){
          console.log("methods 选项中的 decreaseSales 函数被调用了")
          console.log(this)
          this.volume-=1000
        }
      },
    })
 
    app.mount('#app')
  </script>
</body>
</html>

使用 LiverServer 打开 HTML 页面,点击增加按钮:

image.png

控制台中输出的 this 是一个 Proxy 对象,这个对象指的就是 Vue 实例,可以访问当前实例中定义的数据、计算属性以及其他方法。

但为什么是一个 Proxy 对象呢?这是因为 Vue3.x 引入了 Proxy 来进行数据的劫持和监听,代替了 Vue2.x 中使用的 Object.defineProperty。这个 Proxy 对象的引入有一些重要的意义和优势,有着 更灵活的劫持机制 、深层响应性 、更好的性能 以及 更易扩展。

关于这个 this 官网中也有提到,为什么不能使用箭头函数?

这是因为箭头函数的特性,即不绑定自己的 this 上下文,而是继承自外围的作用域;在 Vue 组件中,如果使用箭头函数定义 methods 中的方法,this 将指向外围的上下文,而不是组件实例。这可能导致你无法访问组件实例中的数据、计算属性、或其他方法。

推荐使用普通函数声明,Vue 在内部会确保在调用这些方法时正确绑定 this,使得 this 指向 Vue 组件实例。

那么这个 this 可不可以是 window 呢?

我们可以在 decreaseSales 方法中使用箭头函数,从而让 this 指向 window:

decreaseSales: () => {
  console.log("methods 选项中的 decreaseSales 函数被调用了")
  console.log(this)
  this.volume-=1000
}

刷新 HTML 页面,点击减少按钮:

Dec-22-2023 01-53-48.gif

可以看到这里并没有修改成功,并且输出的 this 指向的是 window,基于箭头函数 this 的查找规则,这里的 this 会在自己的上层作用域中查找,找到的就是 script 中的 this,也就是 window。

并且因为 window 对象中并没有 volume 属性,所以修改失败。

在 Vue 源码中,Vue 实例绑定 this 的主要是通过 JavaScript 中的 bind 方法。这确保了在方法内部,this 始终指向 Vue 实例。

在 JavaScript 中,this 的绑定规则主要有四种情况,它们分别是:

  • 默认绑定: 当函数被独立调用时,this 会指向全局对象(在浏览器环境中通常是 window)。

  • 隐式绑定: 当函数作为对象的方法被调用时,this 会指向该对象。

  • 显式绑定: 使用 call、apply 或者 bind 方法,手动指定函数调用时的 this 值。

  • new 绑定: 当构造函数被 new 关键字调用时,this 会指向新创建的对象实例。