在前面的学习当中,学会了如何用文本插值输出数据。但如果我们需要根据某些规则或逻辑输出数据呢?在这种情况下,我们可以通地Vue中的计算属性,根据某些规则或逻辑输出数据。这种方式也很方便,但除了这些方式之外,还可以嵌入JavaScript的逻辑函数。有的时候我们还会从远程服务获取数据,使用前面提到的方式也是可以。那么,今天 我们学习一个新方法,使用methods
属性向Vue实例引入新属性。该属性应该包含一个对象,其中键(key
)为函数的名称,值(value
)为函数本身。
在介绍methods
之前,咱们先简单的回忆一下。比如我们有下面这个示例,我们的data
数据中,有两个属性:firstName
和lastName
。我们的目的是输出一个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中的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中的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中的data
和methods
都是上下文中的变量,所以我们可以通过this.firstName
的方式访问data
中的firstName
属性。如果我们想要,我们可以通过使用相同的方法从fullName()
方法中访问其他方法,只需要末尾插入括号,使其成为方法调用。
好了,现在我们已经实现了我们的方法,让我们看看在模板中怎么使用它。事实上也是你期望的那样简单,在方法后面紧跟着圆括号。
<div id="app">
<h1>{{ fullName() }}</h1>
</div>
事实证明,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
的参数传递进去,比如:
<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实例。当你打开浏览器的控制台时,可以看到有报错信息:
报错信息中告诉我们firstName
是undefined
。我们在代码中添加console.log(this)
。正如我们所看到的,this
指向的是window
对象,这不是我们所期望的。这就是为什么在这种情况下,我们没有firstName
或lastName
属性。相比之下,我们使用正常函数,看看是什么样子:
现在,我们可以看到Vue实例的输出,就像我们最初期望的那样。
这个实例告诉我们不应该在Vue实例属性上使用箭头函数,Vue尝试将其绑定到Vue实例本身。还有时候,你可以使用箭头函数提供所有的好处,例如,如果你将一个函数赋给一个Vue实例的方法中的一个变量。然后你可以在这个箭头函数中访问它,它将指向你所期望的Vue实例。你只要意识到使用箭头函数的地方可能会出现一些奇怪的行为,而不是你所期望的,那么它可能与箭头函数有关。这时需要注意,先尝试把箭头函数改成ES5的函数方式。
Methods vs Computed
前面的示例我们可以看到,methods
和computed
都可以处理大量的逻辑代码。有时候他们得到的效果是一样的。虽然如此,但他们各自却有不同之处。从作用机制和性质上看,methods
和computed
不太一样,所以我们接下来主要了解两者之间的对比。从两者对比来了解他们之间的不同之处。
从作用机制上看:
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 + ')'
}
}
})
<div id="app">
<h1>{{ fullName }}</h1>
</div>
希望能把“只会写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()
}
}
})
<div id="app">
<button @click="getMethodsDate">Methods Get Date</button>
<button @click="getComputedDate">Computed Get Date</button>
</div>
先来看一个点击button
在控制台的输出:
不难发现,连续点击两次methods
返回的时间是不同的;连续点击两次computed
返回的时间是相同的。
为什么两次点击
computed
返回的时间是相同的呢?new Date()
不是依赖型数据(不是放在data
等对象下的实例数据),所以computed
只提供了缓存的值,而没有重新计算。
只有符合:存在依赖型数据和依赖型数据发生改变这两个条件,computed
才会重新计算。 而methods
下的数据,是每次都会进行计算的。使用官方的描述:
我们可以将同一函数定义为一个方法而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
总结
今天我们主要学习了Vue中的methods
怎么使用。顺便介绍了methods
和computed
两者之间的异同。
由于作者自身是Vue的初学者,如果文中有不对之处,还请各路大婶拍正,如果在这方面有更多的经验,欢迎在下面的评论中与我们一起分享。
如需转载,烦请注明出处:https://www.w3cplus.com/vue/working-with-methods-in-vue.html