资讯专栏INFORMATION COLUMN

Vue 2 | Part 6 计算属性

legendmohe / 1706人阅读

摘要:另外初始化自己手上持有现金。让购入的游戏显示在已入清单中,并从愿望清单中移除直接用方法筛选出所有字段为的游戏,结果绑定到已入清单。计算当前余额最后,使用现金总额减掉已入游戏的总价,就得到当前余额啦。

在这之前,我们往html里面绑定的数据,都是非常直接的。给定一个值,就直接绑定它了。

但是更多的情况下,我们在绑定之前,需要对这些数据做一些处理。这就是计算属性发挥作用的地方了。

有了前面各期知识的加成,这次我们来一个好玩的。我们做一个愿望清单,列表里面是想买的PS4游戏:

点击购买某个游戏之后,它会自动从愿望清单移除,出现在已入游戏列表里面。同时,余额也相应减少:

当然,这里不涉及任何的真实货币结算,只是点击一下按钮,做出余额相应减少和两边列表更新的效果。

注:游戏价格是PSN上面2016圣诞元旦这段期间的价格,查的当时是港元,所以我们整个demo就使用港元作为货币单位了。

为了避免篇幅过长,这一期的代码只截取重点部分,完整的代码请看github代码库的版本。

本期的简单database

我把查询到的数据弄成了一个小DB,放在gamesDB.js文件里面,主要是用来做列表循环,下面是它的样子:

// gamesDB.js
var games = [
    {
        "id"       : 0,
        "name"     : "神秘海域123",
        "img"      : "../static/images/uncharted-collection.jpg",
        "price"    : 160.80,
        "purchased": false
    },
    /* 余下的部分省略 */
]

purchased字段表示该游戏是否已购入,初始时所有为false

HTML拆解

使用大胡子语法绑定余额myBalance

在这个demo里面会全部使用大胡子语法。因为会遇到像下面这样,需要在数据前后加额外文字的情况。如果一些地方用v-text,一些地方用大胡子,代码会很难分辨,所以就统一用大胡子了。

另外,跟金钱有关的部分都会使用toFixed方法来保留两位小数。

v-for循环列表

循环愿望清单wishList

{{ item.name }}

HK$ {{ item.price.toFixed(2) }}

已入游戏列表myGames的循环同理,只是会减少一些UI:

{{ item.name }}

初始的JS

window.games是为了方便,我在gamesDB.js里面直接把db挂了在window对象下。在实际工作用请一定要避免这种做法。引入了gamesDB.js之后,data.games就有了我准备好的数据库里面的数据了。

另外初始化自己手上持有现金5000。



var app = new Vue({
    el: "#app",
    data: {
        games: window.games,
        myCash: 5000
    }
})
处理点击事件

通过ID找到对应的游戏,修改purchased字段为true。ID会在html的绑定中传入:@click="buyGame(item.id)"

var app = new Vue({
    el: "#app",
    data: {
        games: window.games,
        myCash: 5000
    },
    methods: {
        buyGame: function (id) {
            this.games[id].purchased = true
        }
    }
})
让购入的游戏显示在已入清单中,并从愿望清单中移除

直接用filter方法筛选出所有purchased字段为true的游戏,结果绑定到已入清单。同理,愿望清单中只筛选字段值为false的游戏。

var app = new Vue({
    el: "#app",
    data: {
        games: window.games,
        myCash: 5000
    },
    methods: {
        buyGame: function (id) {
            this.games[id].purchased = true
        }
    },
    computed: {
        wishList: function () {
            return this.games.filter(function (game) {
                return !game.purchased
            })
        },
        myGames: function () {
            return this.games.filter(function (game) {
                return game.purchased
            })
        }    
    }
})

在这里大家肯定都有一个疑问,computed里面的方法和methods里面的方法,到底有什么不同?它们看上去都是一样的啊。

区别就在于computed里面的方法会进行缓存,只要方法依赖的数据源不改变,它们就不会被执行。我们用一个很简单的例子快速说明一下:

在我的余额下面插入一个h2:

data.myCash: {{ showCash }}

在计算属性里面增加一个showCash方法,直接console里面log一下就知道它有没有执行过:

var app = new Vue({
    /* 省略其它代码 */
    computed: {
        showCash: function () {
            console.log("showCash in computed properties")
            // 注意这里是myCash,它在这次的例子中是一直不变的
            return this.myCash
        }
    }
})

进入页面的时候执行了一次(留意一下,不变的数字是为了说明而新加的h2,用鼠标选中了文字的):

点击购买游戏(图中可以看到神秘海域已经点击购买了,所以不在愿望清单中),console中没有出现新log,说明computed里面的showCash方法没有再次执行:

也就是说,如果showCash方法认为它所依赖的数据this.myCash没有发生变化,它就不会再执行,而是直接返回之前已经计算好的值。

只有在它依赖的数据修改的情况下,才会进行更新:

然后我们修改一下html里面的调用方式,在methods里面增加同样的方法:

记得要先屏蔽掉computed里面的同名方法,否则会报错。

data.myCash: {{ showCash() }}

var app = new Vue({
    /* 省略其它代码 */
    methods: {
        showCash: function () {
            console.log("showCash in methods")
            return this.myCash
        }
    }
})

进入页面的时候执行了一次:

点击购买游戏,log增加:

可见,即使数据源没有改变,methods里面的showCash方法依然会执行多次。

计算当前余额

最后,使用现金总额减掉已入游戏的总价,就得到当前余额啦。

var app = new Vue({
    // 省略其它代码
    computed: {
        myBalance: function () {
            var sum = 0
            this.myGames.forEach(function (item, index) {
                sum += item.price
            })
            return this.myCash - sum
        }
    }
})

这期就到这里,敬请期待下一期:组件。

写在最后

源码地址:https://github.com/levblanc/v...

视频攻略:小的不才,为求一赞,自制 本期视频攻略 在此。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81334.html

相关文章

  • VUE - MVVM - part10 - Computed

    摘要:了解之后我们来实现它,同样的为了方便理解我写成了一个类这里的一般是的实例将属性代理到实例下的构造函数我们实现了代理属性和更新计算属性的值,同时依赖没变化时,也是不会触发的更新,解决了以上的个问题。 看这篇之前,如果没有看过之前的文章,移步拉到文章末尾查看之前的文章。 回顾 先捋一下,之前我们实现的 Vue 类,主要有一下的功能: 属性和方法的代理 proxy 监听属性 watche...

    callmewhy 评论0 收藏0
  • Vue 2 | 基础API系列文章合集

    摘要:在大家的鞭策和鼓励下,这个基础的系列终于完成了。关于更新的频率,因为是我自己一个人在做,文案视频都准备好了才发的话,最快也只能一周一更。最后这几期可以密集地更新,完全是因为公司放假了。不过月份的更新速度真的不能保证,抱歉。 在大家的鞭策和鼓励下,这个基础API的系列终于完成了。所幸是没有真的更到一百期才完结(笑)。最初是因为觉得录视频好玩,才挖的这个坑。也想过中途放弃,关掉专栏,但由于...

    instein 评论0 收藏0
  • Vue 2 | Part 7 组件

    摘要:因为这里会举一连串的例子,就直接用来作为组件名称了。这是一个组件名称定义的时候有一点需要注意的,就是要使用中划线分词。在组件的方法里面返回数据就可以了。在的组件中间定义的内容,就会被插入到的位置中去。敬请期待下一期,组件通信。 界面写多了,大家应该都会想到一个问题:JS的模块写好以后可以在多个地方重复使用,HTML有没有办法做到呢?Vue给了我们这个能力,使用组件,就可以轻松做到。 最...

    xcold 评论0 收藏0
  • Vue 2 | Part 5 列表渲染和事件监听

    之前在vue里面绑定数据,都只是单个地绑定。这期我们来看一下怎样渲染列表,然后通过事件监听方法往列表里面增加item。 列表渲染 废话不多说,直接上代码: {{ item }} var app = new Vue({ el: #app, data: { list: [ ...

    Nekron 评论0 收藏0
  • VUE - MVVM - part5 - Observe

    摘要:具体代码执行方式进入到的目录下,命令行运行即可。确保为一个对象如果对象下有则不需要再次生成函数返回该对象的实例,这里判断了如果该对象下已经有实例,则直接返回,不再去生产实例。这就确保了一个对象下的实例仅被实例化一次。 看这篇之前,如果没有看过之前的文章,可拉到文章末尾查看之前的文章。 回顾 在 step4 中,我们大致实现了一个 MVVM 的框架,由3个部分组成: defineRe...

    xi4oh4o 评论0 收藏0

发表评论

0条评论

legendmohe

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<