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'
        }
    }
})

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

{{ firstName }} {{ lastName }}

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

除了文本插值的方式之外,我们还可以使用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 ,如下:

{{ fullName }}

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

如果你从未接触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() 方法中访问其他方法,只需要末尾插入括号,使其成为方法调用。

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

{{ fullName() }}

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

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

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

使用Vue的 methods 时,在调用 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 的参数传递进去,比如:

{{ fullName(firstName, lastName) }}

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

{{ fullName('大漠', 'w3cplus.com') }}

效果如下:

除了像上面一样,在方法中返回字符串之外,我们还可以返回对象和数组。比如我们重构上面的方法,让这个方法返回一个对象而不是字符串。比如下面的示例,咱们返回一个叫 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实例。当你打开浏览器的控制台时,可以看到有报错信息:

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

现在,我们可以看到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 擅长处理的场景是: 一个数据受多个数据影响

比如我们有一个这样的场景,我本来想用“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 + ')'
        }
    }
})

{{ fullName }}

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

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

在很多时候, computed 是用来处理你使用 methods 的时候无法处理或者是处理起来并不太恰当的情况的。另外可以利用 computed 处理 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()
        }
    }
})

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

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

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

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

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

总结

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

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

大漠

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

W3CPlus稿源:W3CPlus (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 前端开发 » Vue 2.0的学习笔记:Vue的Methods

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录