Vue 2.0的学习笔记:Vue的Methods

发布于 大漠

在前面的学习当中,学会了如何用文本插值输出数据。但如果我们需要根据某些规则或逻辑输出数据呢?在这种情况下,我们可以通地Vue中的计算属性,根据某些规则或逻辑输出数据。这种方式也很方便,但除了这些方式之外,还可以嵌入JavaScript的逻辑函数。有的时候我们还会从远程服务获取数据,使用前面提到的方式也是可以。那么,今天 我们学习一个新方法,使用methods属性向Vue实例引入新属性。该属性应该包含一个对象,其中键(key)为函数的名称,值(value)为函数本身。

在介绍methods之前,咱们先简单的回忆一下。比如我们有下面这个示例,我们的data数据中,有两个属性:firstNamelastName。我们的目的是输出一个fullName

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    }
})

比如我们要在页面中输出全名,我们有两种方式,一种是文本插值方式:

<div id="app">
    <h1>{{ firstName }} {{ lastName }}</h1>
</div>

可以看到输出我们需要的fullName,也就是"Airen Liao"

Vue的Methods

除了文本插值的方式之外,我们还可以使用Vue中的computed属性,可以在computed中创建一个fullName方法。其中键名就是函数名,比如fullName,而键值是函数:

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    computed: {
        fullName: function () {
            return this.firstName + ' ' + this.lastName
        }
    }
})

这个时候,我们在元素中插入fullName,如下:

<div id="app">
    <h1>{{ fullName }}</h1>
</div>

最终输出的也是我们希望要的结果。

如果你从未接触Vue中的计算属性computed,建议你点击这里这里进行了解。

除了上面两种方式,我们还可以添加一个方法,即函数,它也可以为我们做这个。

正如前面提到的,函数必须在Vue中的methods属性下添加,这个有点类似于Vue中的计算属性computed。在Vue中,把methods被命名为方法,它也是让我们调用在对象上下文中的函数,它可以操作对象中包含的数据。在我们这个示例,对象其实就是Vue实例。

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    methods: {
        
    }
})

该对象中的键将是方法的名称。在本例中,fullName就是methods的方法名,其值就是一个函数:

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    methods: {
        fullName: function () {
            
        }
    }
})

实际上,Vue中的方法可用做很多事情,但是现在我们这个示例中的方法只返回一个字符串值,它可以通过文本插值来输出。那么,我们如何访问该方法中的数据属性呢?Vue代理的数据和方法在此上下文中都可用,所以this.firstName就是访问了data中的firstName属性。注意这是必需的。有了这个,我们就可以很容易地连接第一个和最后一个名称并返回结果。

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    methods: {
        fullName: function () {
            return this.firstName + ' ' + this.lastName
        }
    }
})

再次注意了,Vue中的datamethods都是上下文中的变量,所以我们可以通过this.firstName的方式访问data中的firstName属性。如果我们想要,我们可以通过使用相同的方法从fullName()方法中访问其他方法,只需要末尾插入括号,使其成为方法调用。

好了,现在我们已经实现了我们的方法,让我们看看在模板中怎么使用它。事实上也是你期望的那样简单,在方法后面紧跟着圆括号。

<div id="app">
    <h1>{{ fullName() }}</h1>
</div>

事实证明,Vue的methods也可以访问数据对象的属性,也同样能渲染出所需要的字符。如果运行上面的代码,我们应该可以看到我的全名会页面上输出。如下所示:

这个看上去和computed类似。截张图看个对比:

Vue的Methods

这两种方式,只要我们data中的数据做了改变,输出也会做相应的变化。我们可以在控制台上做个测试:

Vue的Methods

使用Vue的methods时,在调用methods定义的方法时,一定得加上小括号(),不然输出的将是整个函数中的字符,类似下图这样:

Vue的Methods

在Vue中,使用methods可以做computed同样的事情,但两者之间还是有所差别的。让我们尝试一种稍微不同的方法。如果我们希望将第一个和最后一个名字传递给方法作为参数,而不是让方法直接访问数据属性,那该怎么办?我们可以很容易地在方法中添加参数,就像我们在JavaScript中的函数传参数那样。

我将对参数使用不同的名称,这样它们就不会和data对象的属性同名,造成一定的混淆,这样做只是为了证明我们不再依赖于数据中的属性。

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    methods: {
        fullName: function (first, last) {
            return first + ' ' + last
        }
    }
})

然后,在模板中,我们只需要通过使用数据对象中的适当属性名作为fullName的参数传递进去,比如:

<div id="app">
    <h1>{{ fullName(firstName, lastName) }}</h1>
</div>

这样也能得到我们想要的结果,在页面上输出我的全名。除此之外,我们还可以像JavaScript的函数调用一样,传一些不在data中的属性做为参数,也能输出到页面上,如:

<div id="app">
    <h1>{{ fullName('大漠', 'w3cplus.com') }}</h1>
</div>

效果如下:

除了像上面一样,在方法中返回字符串之外,我们还可以返回对象和数组。比如我们重构上面的方法,让这个方法返回一个对象而不是字符串。比如下面的示例,咱们返回一个叫name的对象,而这个对象正如你所期望的一样,输出全名。

let app = new Vue({
    el: '#app',
    data () {
        return {
            firstName: 'Airen',
            lastName: 'Liao'
        }
    },
    methods: {
        fullName: function(first, last) {
            return {
                name: first + ' ' + last
            }
        }
    }
})

在模板中,我们仍然像以前一样调用方法。运行代码将打印出对象,这不是我们想要的。在方法调用之后,需要访问fullName对象的name名。再次运行代码将显示相同的结果。这也适用于嵌套对象。

在Vue中使用methods时有一个细节需要注意。如果你试图在方法对象中使用ES6箭头函数,那么你将无法访问其他方法或数据属性。这主要是因为箭头函数被绑定到父上下文(Parent Context),因此这个关键字不会像你期望那样引用Vue实例。因此,你试图以这种方式访问的任何数据属性或方法都将是未定义的。解决方法很简单:在方法对象中使用ES5语法的函数

虽然 ES6的箭头函数非常有用,但在Vue的methods中使用,将会发生什么?我们简单的用示例来演示。将前面示例中的fullName函数改用箭头函数的写法:

methods: {
    fullName:  () => {
        return this.firstName + ' ' + this.lastName
    }
}

运行上面的代码,在页面上并未能如你所期望的一样输出我的全名。这是因为箭头函数被绑定到父上下文,因此这将不是你所期望的Vue实例。当你打开浏览器的控制台时,可以看到有报错信息:

Vue的Methods

报错信息中告诉我们firstNameundefined。我们在代码中添加console.log(this)。正如我们所看到的,this指向的是window对象,这不是我们所期望的。这就是为什么在这种情况下,我们没有firstNamelastName属性。相比之下,我们使用正常函数,看看是什么样子:

Vue的Methods

现在,我们可以看到Vue实例的输出,就像我们最初期望的那样。

这个实例告诉我们不应该在Vue实例属性上使用箭头函数,Vue尝试将其绑定到Vue实例本身。还有时候,你可以使用箭头函数提供所有的好处,例如,如果你将一个函数赋给一个Vue实例的方法中的一个变量。然后你可以在这个箭头函数中访问它,它将指向你所期望的Vue实例。你只要意识到使用箭头函数的地方可能会出现一些奇怪的行为,而不是你所期望的,那么它可能与箭头函数有关。这时需要注意,先尝试把箭头函数改成ES5的函数方式。

Methods vs Computed

前面的示例我们可以看到,methodscomputed都可以处理大量的逻辑代码。有时候他们得到的效果是一样的。虽然如此,但他们各自却有不同之处。从作用机制和性质上看,methodscomputed不太一样,所以我们接下来主要了解两者之间的对比。从两者对比来了解他们之间的不同之处。

作用机制上看:

  • computed是以Vue的依赖追踪机制为基础的,其试图处理这样的一件事情:当某一个数据(依赖数据)发生变化的时候,所有依赖这个数据的相关数据自动发生变化,也就是自动调用相关的函数去实现数据的变动
  • methods里面是用来定义函数的,它需要手动调用才能执行,而不像computed那样,可以自动执行预先定义的函数

methods里面定义的函数是需要主动调用的,而computed里定义的函数会自动调用,完成我们希望完成的作用

性质上看:

  • computed是计算属性,事实上和data对象里的数据属性是同一类的
  • methods里面定义的是函数,要像JavaScript中的function()函数这样去调用它

例如:

computed: {
    fullName: function () {
        return this.firstName + ' ' + this.lastName
    }
}

你在取用的时候,用this.fullName去取用就和取data一样(不要当成函数调用)。

Vue中的computed擅长处理的场景是:一个数据受多个数据影响

Vue的Methods

比如我们有一个这样的场景,我本来想用“W3cplus_大漠(只会写CSS)”来描述自己,但希望能把“只会写CSS”改成“切图仔”,那么我们可以这样来写:

let app = new Vue({
    el: '#app',
    // data数据中:comeFrom, name,professional
    // computed监控数据:fullName
    // 两者关系: fullName = comeFrom + name + professional
    // 所以等式右边三个数据任一改变,都会直接修改fullName
    data () {
        return {
            comeFrom: 'W3cplus',
            name: '大漠',
            professional: '只会写CSS'
        }
    },
    computed: {
        fullName: function () {
            return this.comeFrom + '-' + this.name + '(' + this.professional + ')'
        }
    }
})

<div id="app">
    <h1>{{ fullName }}</h1>
</div>

Vue的Methods

希望能把“只会写CSS”改成“切图仔”,尝试修改data中的professional的值为"切图仔",比如:

Vue的Methods

methods不处理数据逻辑关系,只提供可调用的函数。正如前面的示例所演示的一样。

在很多时候,computed是用来处理你使用methods的时候无法处理或者是处理起来并不太恰当的情况的。另外可以利用computed处理methods存在的重复计算情况,如下图所示:

Vue的Methods

methods里面的函数就是一群“直男”,如果有其他父函数调用它,它会每次都执行并返回结果,即使这些结果很可能是相同的,是不需要的;而computed是一个“心机婊”,它会以Vue提供的依赖追踪系统为基础,只要依赖数据没有发生变化,computed就不会再度进行计算。

比如下面这个时间的示例:

let app = new Vue({
    el: '#app',
    methods: {
        getMethodsDate: function () {
            console.log(new Date())
        },
        getComputedDate: function () {
            console.log(this.computedDate)
        }
    },
    computed: {
        computedDate: function () {
            return new Date()
        }
    }
})

<div id="app">
    <button @click="getMethodsDate">Methods Get Date</button>
    <button @click="getComputedDate">Computed Get Date</button>
</div>

先来看一个点击button在控制台的输出:

Vue的Methods

不难发现,连续点击两次methods返回的时间是不同的;连续点击两次computed返回的时间是相同的。

Vue的Methods

为什么两次点击computed返回的时间是相同的呢?new Date()不是依赖型数据(不是放在data等对象下的实例数据),所以computed只提供了缓存的值,而没有重新计算。

只有符合:存在依赖型数据和依赖型数据发生改变这两个条件,computed才会重新计算。 而methods下的数据,是每次都会进行计算的。使用官方的描述:

我们可以将同一函数定义为一个方法而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。

总结

今天我们主要学习了Vue中的methods怎么使用。顺便介绍了methodscomputed两者之间的异同。

由于作者自身是Vue的初学者,如果文中有不对之处,还请各路大婶拍正,如果在这方面有更多的经验,欢迎在下面的评论中与我们一起分享。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/vue/working-with-methods-in-vue.htmljordans for sale Classic