初学者 Vue.js 实践(第六部分)
当简单的道具不够用时
实际计算属性
方法与计算属性
让我们来讨论一下计算属性。
到目前为止,您已经了解了Vue如何处理其自己的本地状态(我们放入其中的状态)data
,以及组件如何处理其prop
属性(由父级传递下来的属性)。
然而, Vue中有一种称为计算属性的属性。今天我们就来了解一下。
今天我们将从零开始,以便构建一个清晰的示例。代码如下。
<html>
<head>
<title>Vue 101</title>
</head>
<body>
<div id="app">
<age-calculator></age-calculator>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('age-calculator', {
template: `
<p>
NAME has been kicking butt for X days!
</p>
`
});
const app = new Vue({
el: '#app'
});
</script>
</body>
</html>
我已经为一个age-calculator
组件添加了脚手架,现在它只输出一个<p>
带有 X 的标签,我们将在其中执行某种计算。我还将相应的标签添加到<age-calculator>
了div#app
.
如果您需要复习一下基本组件,请查看本系列的第五部分,或者更好的是,深入研究官方文档!
当简单的道具不够用时
在编写任何代码之前,让我们先讨论一下我们想要完成的目标。
我想要一个组件,传入用户的年龄,它就能告诉我们他们吃了多少天牛油果。如果你不喜欢牛油果,那我们的关系就到此为止了,祝你生活愉快。
让我们先解决一些我们已经知道如何完成的简单任务。首先,我们需要一个包含年龄的人员数组,以便循环遍历它并输出一堆组件。让我们添加相应的data
。
const app = new Vue({
el: '#app',
data: {
people: [
{ name: 'Mario', age: 38 },
{ name: 'Luigi', age: 38 },
{ name: 'Samus', age: 31 },
{ name: 'Link', age: 20 },
{ name: 'Marina', age: 32 },
//Add yourself here :)
]
}
});
现在,让我们设置每个v-loop
输出age-calculator
。
<div id="app">
<age-calculator v-for="person in people" :key="person.name"></age-calculator>
</div>
太棒了,现在让我们允许age-calculator
组件接收一个person
,记住我们是用 来实现的prop
。所以首先,让我们将这个 new 添加prop
到组件中。
Vue.component('age-calculator', {
props: {
person: {
type: Object,
required: true
}
},
template: `
<p>
{{ person.name }} has been kicking butt for X days!
</p>
`
});
额外福利!之前你学会了如何声明组件可以接收的 props,你只需要设置一个字符串数组props: ['person']
,这在大多数情况下都可以。但是如果我们想要更多的控制权该怎么办呢?
你也可以像本例一样,将其设置props
为等于一个对象。在这个对象内部,我们可以为每个想要声明的属性创建一个属性。
在属性声明中,在这种情况下person
,我们可以设置一些配置值。
type
来声明我们要传递哪种类型的数据(呃) ,例如Object
,,,。Array
String
Number
required
是一个布尔值,允许我们将此属性标记为组件工作所必需的。
您也可以设置一个default
值,但我们不会在这里使用它。
接下来,查看模板。我们现在将人员姓名输出到标签{{ person.name }}
上<p>
。
不过,在我们真正在浏览器中运行它之前,还有一件事。你能说出我们遗漏了什么吗?
我们仍然需要将实际情况传递person
给age-calculator
组件!
进入渲染循环并传入我们的变量。
<age-calculator
v-for="person in people"
:person="person"
:key="person.name"></age-calculator>
继续在浏览器中运行这个程序,检查一切是否正常。小步前进!
注意在我们继续之前,如果您好奇将 a 设置为必需prop
会为您做什么,请尝试删除我们在将人传递给组件时所做的最后一点,并查看控制台部分中的开发工具。
很方便,不是吗?👌
实际计算属性
好了,设置和回顾就到此为止。
我们的组件中还有一个功能需要解决,我们想要计算每个人存活的天数。
当然,这不是一个很难的计算,我们只需要乘以 365 乘以年数(我们这里不会用 JS Dates 来硬核计算)。事实上,我们可以更直接地把它写进模板里。
template: `
<p>
{{ person.name }} has been kicking butt for {{ person.age * 365 }} days!
</p>
`
这算是可以的。但是当你需要更多逻辑时会发生什么?更复杂的逻辑computation
,比如一些 if/and/or/when/beers 之类的逻辑?那你就麻烦大了,因为你根本没法在模板里放那么多逻辑,否则很快就会变得难以管理。
这就是计算属性的亮点所在。计算属性最终是一个函数,它会执行一些代码并返回一个值。这个值现在被视为一个属性,这意味着我们可以直接在模板中使用它。
让我们看一下如何设置它。首先,让我们将计算包装器添加到我们的组件中。
Vue.component('age-calculator', {
props: {
person: {
type: Object,
required: true
}
},
template: `
<p>
{{ person.name }} has been kicking butt for {{ person.age * 365 }} days!
</p>
`,
computed: {
// Computed props go here
}
});
到目前为止一切顺利,事实上这个结构和我们一直使用的结构完全一样methods
,记得吗?(如果你认为一种方法也可以解决我们的问题,那么你就走在了正确的轨道上——我们稍后会讨论这个问题。)
让我们创建一个名为的新计算属性daysAlive
,它需要是一个函数,并且需要返回一些东西。
computed: {
daysAlive() { //Remember, computed props are functions in the end
return this.person.age * 365
}
}
请注意,就像methods
我们需要访问person
prop 一样this
,只有在模板内部我们才能直接使用它!除此之外,就没什么特别的了。
现在让我们daysAlive
在模板中使用这个新道具。
template: `
<p>
{{ person.name }} has been kicking butt for {{ daysAlive }} days!
</p>
`,
daysAlive
注意,我们输出的是--属性--的值(顿悟时刻)。Vue将计算出的 props 视为 props,所以我们可以像使用 prop 一样使用props
它data
。
事实上,Vue 的设计理念是,如果你需要在 a 内部使用这个 prop method
,你必须通过 来访问它this.daysAlive
。是不是很酷?它真的变成了一个 prop。🤯
耶,在浏览器中运行它并享受你的精彩。
方法与计算属性
你可能已经注意到方法和计算属性之间有很多相似之处,我的意思是,它们在代码层面上基本相同。然而,为了充分利用它们,你需要理解一个核心区别。
计算属性被缓存。
简而言之,Vue会在后台“读取”你的代码并查找响应式依赖项,也就是data
props 和props
props。它会监听这些属性,每当它们发生变化时,Vue就会重新计算计算属性的值。如果它们没有变化,Vue 就会使用缓存/存储的值。
另一方面,方法每次都会运行——没有缓存,没有代码读取,也没有任何魔法。它们只是普通的函数。
这有什么关系?这些函数什么时候被调用?
每次组件/应用重新渲染时(即每次组件的数据发生变化,或其父组件的数据发生变化时),Vue都会判断该数据是否与计算属性绑定。如果没有,则不会再次调用此函数。但对于常规方法,它们每次都会重新运行!
就这个例子来说,我们只是对这几个对象进行一些非常简单的计算,坦白说,这其实无关紧要。但是,当你开始在上千个组件上进行一些重要的代码提升时,你就需要利用这种缓存,否则你的应用在每个渲染周期都会受到冲击。
如果您想了解更多信息,这里有一个关于计算属性的官方文档的链接。
这是今天的完整代码。
<html>
<head>
<title>Vue 101</title>
</head>
<body>
<div id="app">
<age-calculator
v-for="person in people"
:person="person"
:key="person.name"></age-calculator>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('age-calculator', {
props: {
person: {
type: Object,
required: true
}
},
template: `
<p>
{{ person.name }} has been kicking butt for {{ daysAlive }} days!
</p>
`,
computed: {
daysAlive() {
return this.person.age * 365
}
}
});
const app = new Vue({
el: '#app',
data: {
people: [
{ name: 'Mario', age: 38 },
{ name: 'Luigi', age: 38 },
{ name: 'Samus', age: 31 },
{ name: 'Link', age: 20 }
]
}
});
</script>
</body>
</html>
今天就到这里!感谢阅读,下周我们继续watchers
!🕵️♀️👀