ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 计算属性computed如何传参 # 【vue】计算属性computed如何传参 #### 前言 使用计算属性可以让模板内不需要放太多的计算逻辑,使得模板简单维护性强。那么如果希望使用计算属性传入一个参数时该怎么写呢? #### 正文 比如下面的数据,希望循环输出时将`type`的值进行转化,得到具体的用户类型(`1代表学生,2代表老师`) ``` <pre class="calibre13">``` data<span class="token1">:</span> <span class="token1">{</span> userlist<span class="token1">:</span><span class="token1">[</span> <span class="token1">{</span> name<span class="token1">:</span><span class="token4">'张三'</span><span class="token1">,</span> type<span class="token1">:</span><span class="token5">1</span> <span class="token1">}</span><span class="token1">,</span> <span class="token1">{</span> name<span class="token1">:</span><span class="token4">'王二'</span><span class="token1">,</span> type<span class="token1">:</span><span class="token5">2</span> <span class="token1">}</span> <span class="token1">]</span> <span class="token1">}</span><span class="token1">,</span> ``` ``` 如果直接按如下方式给计算属性传参是不行的 ``` <pre class="calibre13">``` <span class="token5"><span class="token5"><span class="token1"><</span>ul</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>li</span> <span class="token4">v-for</span><span class="token2"><span class="token1">=</span><span class="token1">"</span>item,index in userlist<span class="token1">"</span></span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>span</span><span class="token1">></span></span>{{item.name}}<span class="token5"><span class="token5"><span class="token1"></</span>span</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>span</span><span class="token1">></span></span>{{usertype(item.type)}}<span class="token5"><span class="token5"><span class="token1"></</span>span</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"></</span>li</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"></</span>ul</span><span class="token1">></span></span> ``` ``` ``` <pre class="calibre13">``` computed<span class="token1">:</span> <span class="token1">{</span> <span class="token3">usertype</span><span class="token1">(</span>value<span class="token1">)</span><span class="token1">{</span> <span class="token2">var</span> user <span class="token">=</span> <span class="token4">''</span> <span class="token2">return</span> value <span class="token">===</span> <span class="token5">1</span> <span class="token">?</span> user <span class="token">=</span> <span class="token4">'学生'</span> <span class="token1">:</span> user <span class="token">=</span> <span class="token4">'老师'</span> <span class="token1">}</span> <span class="token1">}</span> ``` ``` 结果会报错:`usertype is not a function` **原因** 上图调用计算属性的代码是`usertype(item.type)`,而我们不去传参时是这样调用的`usertype`。说明`usertype`调用了计算属性得到计算属性的`返回值`,然后再执行`返回值(item.type)`,但是这里`返回值`并不是函数无法执行,所以报错:`usertype is not a function`。那么只需要让计算属性`返回一个函数`即可。 **采用闭包的形式**: ``` <pre class="calibre13">``` computed<span class="token1">:</span> <span class="token1">{</span> <span class="token3">usertype</span><span class="token1">(</span><span class="token1">)</span><span class="token1">{</span> <span class="token2">return</span> <span class="token2">function</span> <span class="token1">(</span>value<span class="token1">)</span><span class="token1">{</span> <span class="token2">var</span> user <span class="token">=</span> <span class="token4">''</span> value <span class="token">===</span> <span class="token5">1</span> <span class="token">?</span> user <span class="token">=</span> <span class="token4">'学生'</span> <span class="token1">:</span> user <span class="token">=</span> <span class="token4">'老师'</span> <span class="token2">return</span> user <span class="token1">}</span> <span class="token1">}</span> <span class="token1">}</span> ``` ``` > 这里采用闭包,计算属性返回一个匿名函数,然后执行这个匿名函数并传入参数,将判断结果返回 #### 注意:传参之后结果还会缓存吗? **计算属性的好处:** 我们都知道使用计算属性除了使得模板内容里逻辑简单,便于维护。还有一个最重要的好处,那就是`缓存结果`。这也就是明明我们在`methods`里定义同样的方法函数可以与`computed`得到同样的结果,却不用`methods`的原因。 > - 每次调用`methods`里的函数都要去重新执行,试想一下如果一个函数的逻辑过于复杂,那么每次调用的性能消耗都是巨大的。 > - 而`computed`会将第一次执行的结果缓存,以后每一次调用时都是直接读取缓存结果而不是执行。 > - `计算属性是基于它们的响应式依赖进行缓存`,只有相关的依赖发送改变才会重新求值 **测试:** 同时测试一下传参和不传参,看看它们的结果 代码: ``` <pre class="calibre13">``` <span class="token5"><span class="token5"><span class="token1"><</span>p</span><span class="token1">></span></span>{{time1('传参:')}}<span class="token5"><span class="token5"><span class="token1"></</span>p</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>p</span><span class="token1">></span></span>{{time1('传参:')}}<span class="token5"><span class="token5"><span class="token1"></</span>p</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>p</span><span class="token1">></span></span>不传参:{{time2}}<span class="token5"><span class="token5"><span class="token1"></</span>p</span><span class="token1">></span></span> <span class="token5"><span class="token5"><span class="token1"><</span>p</span><span class="token1">></span></span>不传参:{{time2}}<span class="token5"><span class="token5"><span class="token1"></</span>p</span><span class="token1">></span></span> ``` ``` ``` <pre class="calibre13">``` computed<span class="token1">:</span> <span class="token1">{</span> <span class="token3">time1</span><span class="token1">(</span><span class="token1">)</span><span class="token1">{</span> <span class="token2">return</span> <span class="token2">function</span> <span class="token1">(</span>value<span class="token1">)</span><span class="token1">{</span> <span class="token2">return</span> value<span class="token">+</span>Date<span class="token1">.</span><span class="token3">now</span><span class="token1">(</span><span class="token1">)</span> <span class="token1">}</span> <span class="token1">}</span><span class="token1">,</span> <span class="token3">time2</span><span class="token1">(</span><span class="token1">)</span><span class="token1">{</span> <span class="token2">return</span> Date<span class="token1">.</span><span class="token3">now</span><span class="token1">(</span><span class="token1">)</span> <span class="token1">}</span> <span class="token1">}</span> ``` ``` 代码说明:定义两个计算属性,`time1`传参`time2`不传参,分别执行两次计算属性。观察结果: ![](https://img-blog.csdnimg.cn/20200326020627660.PNG) 结果说明:很明显,传参的计算属性结果并没有缓存,而是重新进行了计算 > 注意:可能你会得到两次传参的计算属性结果一致,那是因为恰好两次计算属性同时执行,多刷新几次 没有传参的计算属性返回的是最终的计算结果,而通过闭包传参之后返回的是一个函数,这个函数执行之后再得到结果,那么这个和使用`methods`仿佛已经没了区别。可以说,传参之后的计算属性已经不能称为计算属性,它甚至不能缓存数据,而使用计算属性的目的之一,就是缓存数据。 #### 总结 说到这里,虽然计算属性可以通过闭包进行传参,但它已经违背了计算属性,所以使用计算属性传参不如使用`methods`。或许这也是为什么官方文档并没有提出计算属性传参的的内容吧!