您现在的位置是:首页 >其他 >三、vue_options之data、methods属性选项网站首页其他

三、vue_options之data、methods属性选项

覆水难收呀 2023-05-24 20:00:02
简介三、vue_options之data、methods属性选项

一、data属性

data属性是传入一个函数,并且该函数需要返回一个对象:

  • 在Vue2.x的时候,也可以传入一个对象(虽然官方推荐是一个函数);
  • 在Vue3.x的时候,必须传入一个函数,否则就会直接在浏览器中报错;

data中返回的对象会被Vue的响应式系统劫持,之后对该对象的修改或者访问都会在劫持中被处理 

  • 所以我们在template或者app中通过{{counter}}访问counter,可以从对象中获取到数据
  • 所以我们修改counter的值时,app中的{{counter}}也会发生改变

具体这种响应式的原理,我们后面会有专门的篇幅来讲解。

(1)案例

我们现在有个button按钮,我怎么通过点击这个button按钮去改变message的值?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <h2>{{message}}</h2>
      <button @click="changeMessage">改变message</button>
    </div>
    <script src="./lib/vue.js"></script>

    <script>
      const app = Vue.createApp({
        // data: option api
        data: function () {
          return {
            message: 'Hello World',
          };
        },
        // methods: option api
        methods: {
          changeMessage: function () {
            this.message = '奥利给';
          },
        },
      });

      app.mount('#app');
    </script>
  </body>
</html>

 

二、methods属性

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <h2>当前计数: {{counter}}</h2>
      <button @click="increment">+1</button>
      <button @click="decrement">-1</button>
    </div>
    <script src="./lib/vue.js"></script>
    <script>
      const app = Vue.createApp({
        data: function () {
          return {
            counter: 0,
          };
        },
        methods: {
          increment: function () {
            console.log(this);
            this.counter++;
          },
          decrement: function () {
            this.counter--;
          },
        },
      });

      app.mount('#app');
    </script>
  </body>
</html>

有同学很好奇,这里methods里面的调用的this是什么?

如果我们只单纯这么看,这里的this能知道指向的是什么吗?很明显不能。因为这里的this具体是什么,取决于这个函数到底是如何被调用的。

  • 如果这个函数直接这么调用 increment() ,那这里的this指向的是window。
  • 那如果我们把increment函数放到obj里面,我们直接obj.increment,那就等同于increment。
  • 如果obj.increment(),这样子绑定的就是obj对象。(隐式绑定)

我们来重新考虑一下我们大概要实现一个什么样子的功能?因为我们需要改变counter的值,我们通过点击按钮触发increment这个函数,然后要在这个函数里面通过this去访问data里面的counter,改掉这个值之后上面的计数{{counter}}值才会发生改变。

 

那我们这里可以用window.counter++吗?明显不行。

  • window有counter吗?明显没有。
  • window可以改变上面的counter吗?明显也不可以。 

其实函数有下面三种写法, 方法1和方法2其实是一样的。我们重点看方法3。

methods: {
          // 方法1
          increment: function () {
            console.log(this);
            this.counter++;
          },
          // 方法2,es6的写法
          increment() {  
          },
          // 方法3
          increment: () => {
            console.log(this);
          },
        },

首先我们了解一下箭头函数是什么意思。

箭头函数是一种简写的函数语法,可以更容易地创建匿名函数。它通常使用箭头 => 来代替函数关键字和return语句。例如,(x) => x * 2 可以代替 function(x) { return x * 2 }。这使得代码更简洁、更容易理解。

箭头函数会绑定this吗?不会,那他就去找谁?他就会去找他上层作用域里面的this。那他上层作用域是什么?难道是methods吗?很明显不是,methods是一个对象类型,没有自己作用域这一说。我们继续往上找,methods上面是什么?是不是vue创建app实例的时候需要传入的一个对象?那他也是一个对象肯定也没有自己作用域这一说。然后他继续往上层作用域里面找,再上面一层是不是就是全局作用域了。所以你在全局作用域里面打印this,肯定和箭头函数打印的this是同一个this。

 

 


看完箭头函数中的this指向,我们再来看下下面这个this指向什么?我们点击触发一下。

 

大家看一下,是不是一个代理对象。为什么又是一个代理对象呢?其实本质上前面跟大家讲到过,

当前的这种对象会被代理,代理之后我们是不是可以通过这个代理对象对里面的counter进行修改?当然可以。(后续会更深层次的继续讲原理)。

其实这个this在内部,如果你是一个普通函数的话,他是可以绑定this的,也就是说在执行increment这个函数的时候,他是会给你绑定一个this的。

 

this到底指向什么?

 

  

  

 

 

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。