• 技术文章 >web前端 >Vue.js

    Vue计算属性computed可以做什么?应用场景浅析

    青灯夜游青灯夜游2022-08-10 15:56:18转载5096
    Vue计算属性computed可以做什么?又能应用于什么场景呢?下面本篇文章就来带大家了解一下Vue computed属性,并将其与methods、watch对比一下,希望对大家有所帮助!

    大前端零基础入门到就业:进入学习

    Vue中的计算属性是所有属性的计算,而这些计算都是变向的在过滤值,通过数据的不断变化计算出来不同的值和操作不同的方法. 而在Vue中,会使用到计算属性的场景常见的有:

    以上三者的主要优势是简洁。如果只是一个小操作,比如说一些简单的数值++,字符拼接,三元表达式,那么使用相当方便。当然,以上方式也有自己的劣势。一旦要处理的逻辑复杂,代码量就会变得大得多,而且难于维护。比如说用到if语句来控制流程。那么这个时候可能会想到用filter,咱们来看一个简单的示例。

    <div id="app">
        <button @click="count++">{{count + '分'}}</button>
        <div>
            <input v-model="message" />
        </div>
        <p>{{ message.split(' ').reverse().join(' ') }}</p>
    </div>
    let app = new Vue({
        el: '#app',
        data () {
            return {
                count: 0,
                message: ''
            }
        }
    })

    效果如下:

    从上面的示例中我们可以看出:

    p标签中对message进行计算转换的时候,是不是觉得语义不是很强烈,那么用什么办法更好呢?这就需要我们使用到前面提到的filter。

    使用 filter

    我们可以使用filter来修改前面的示例。事实下,在Vue中使用filter具有自己的优势,也具有自己的劣势:

    把上面的示例,用filter修改之后就像下面这样:

    <div id="app">
        <button @click="count++">{{count + '分'}}</button>
        <div>
            <input v-model="message" />
        </div>
        <p>{{ message | reverseString }}</p>
    </div>
    
    let app = new Vue({
        el: '#app',
        data () {
            return {
                count: 0,
                message: ''
            }
        },
        filters: {
            reverseString (value) {
                if (!value) return ''
                value = value.split('').reverse().join('')
                return value
            }
        }
    })

    在这个示例中,我们使用filter来实现,很明显代码量多了那么一点点,但整体的语意化就变得相当明显了,让人一看这里就要进行一些过滤计算,看到reverseString就知道是字符串反转。

    computed

    前面说了这么多,其实我们都是为了给computed的应用场景做一个铺垫。那问题又来了,computed可以做些什么?又能应用于什么场景呢?

    Vue中的computed其实规避了模板语法和filter两个所有的劣势,他的优势在于通过计算所有依赖的数据进行计算,然后返回一个值,记住可以依赖方法里所有的数据,只要一个数据发生变化,则会重新计算,来更新视图的改变。是不是很意思,迫切的想知道它是怎么玩。

    咱们还是拿使用场景来说事吧。先给大家演示一个简单实用的应用场景,后面再做一个更好玩一点的应用场景。

    大家是否还记得,我们在玩微博的时候,发微博会有一个字数限制,比如说只限输入140个字符。为了让用户体验更好,在文本域中输入内容的时候,同时有一个提示信息,告诉用户你还能输入多少字符。那么使用Vue来做这样的事情就会显得容易的多。比如下面这个示例:

    <div id="app">
        <div class="twitter">
            <img :src="imgUrl" />
            <div class="content">
                <textarea v-model="content" :maxlength="totalcount">有什么新鲜事情?</textarea>
                <p>您还可以输入{{ reduceCount }}字</p>
            </div>
        </div>
    </div>
    
    let app = new Vue({
        el: '#app',
        data () {
            return {
                imgUrl: '//pbs.twimg.com/profile_images/468783022687256577/eKHcWEIk_normal.jpeg',
                totalcount: 140, // 总共只给输入140字
                content: ''
            }
        },
        computed: {
            reduceCount () {
                return this.totalcount - this.content.length
            }
        }
    })

    效果如下:

    你可以尝试在文本域中输入内容,你将体验的效果类似下图一样:

    1.gif

    computed创建了一个reduceCount,一直在监听文字的字符长度,来再次进行计算,返回值给视图,让视图进行变化。这也是一个很简单的示例。前面也提到过,我们可以监听多个数据,只要一个数据变了,整个方法就会重新计算,然后反馈到视图,这个方法只是一个简单的应用。咱们再来看一个示例,这样会更好的帮助我们理解。

    这个示例是一个足球比赛记分的示例。简单的对示例进行分析:

    第三个数据相对而言比较复杂,也是比较关键的数据。那么我们用什么方式来维护,可以说比赛情况是多样化的,用一个数据去定死,这样不符合我们的场景。那么我们先列出将会改变的地方:

    这样我们就要不断的监听两个维护的数据,一是比赛时间,二是比赛两队进球数。

    <div id="app">
        <h1>比赛时间:{{ time }}s</h1>
        <h2>直播播报:{{ result }}</h2>
        <div class="team">
            <div>
                <span>中国队进球数:{{ team.china }}</span>
                <button @click="team.china++">点击中国队进一球</button>
            </div>
            <div>
                <span>韩国队进球数:{{ team.korea }}</span>
                <button @click="team.korea++">点击韩国队进一球</button>
            </div>
        </div>
    </div>
    
    let app = new Vue({
        el: '#app',
        data () {
            return {
                time: 0,
                team: {
                    china: 0,
                    korea: 0
                }
            }
        },
        created () {
            let time = setInterval(() => {
                this.time++
                if (this.time == 90) {
                    clearInterval(time)
                }
            }, 1000)
        },
        computed: {
            result () {
                if (this.time < 90) {
                    if (this.team.china > this.team.korea) {
                        return '中国队领先'
                    } else if (this.team.china < this.team.korea) {
                        return '韩国领先'
                    } else {
                        return '双方僵持'
                    }
                } else {
                    if (this.team.china > this.team.korea) {
                        return '中国队赢'
                    } else if (this.team.china < this.team.korea) {
                        return '韩国队赢'
                    } else {
                        return '平局'
                    }
                }
            }
        }
    })

    看到的效果如下:

    注:这里时间90分钟是一个写死的时间值。如果要让Demo更为完美,这个时间我们可以写一个90分钟的倒计时效果。如果你感兴趣的话,可以自己动手修改上面的Demo,然后在下面的评论中与我们一起分享。

    这个示例中,用了点击事件来进行双方进球数,这个Demo帮助我们能能更充分的理解Vue中的computed的含义。说到底是观察一个或多个数据,每当其中一个数据改变的时候,这个函数就会重新计算,还有就是通过观察所有数据来维护一个状态,就是所谓的返回一个状态值。从上面这个Demo,我们就可以很容易的知道computed到底用在什么场景,如何去维护返回一个多状态的场景。

    methods vs computed

    在Vue中,使用methods可以做computed同样的事情,不同的是,computed可以进行缓存。什么意思呢?就是在上个例子中我们对比赛时间和两个球队的进球数进行了检测数据。如果随着时间的改变,但是球数没动,对于computed来说只会重新计算这个球数,进入缓存,而不会再次计算,而重新计算的是这个时间,而且页面的DOM更新也会触发methods来重新计算属性。所以,如果不想让计算属性进入缓存,请使用methods,但我个人更推荐使用computed,语义化会更好一点。毕竟是什么选项里就应该做什么事,methods里面就是应该来管事件的。

    computed vs watch

    computedwatch都可以做同一件事,就像跑步运动员都可以跑步,但是分100米和1000米,术业有专攻嘛,两个选项都是对数据进行时时监听,但是两个的适用场景就不一样了:

    我们可以通过这些变化也可以去维护一个状态,但是不符合场景。那么watch主要用于什么地方呢?其主要用于监听一个数据来进行复杂的逻辑操作。

    <div id="app">
        <h1>比赛时间:{{ time }}s</h1>
        <h2>直播播报:{{ result }}</h2>
        <div class="team">
            <div>
                <span>中国队进球数:{{ team.china }}</span>
                <button @click="team.china++">点击中国队进一球</button>
            </div>
            <div>
                <span>韩国队进球数:{{ team.korea }}</span>
                <button @click="team.korea++">点击韩国队进一球</button>
            </div>
        </div>
    </div>
    
    
    let app = new Vue({
        el: '#app',
        data () {
            return {
                time: 0,
                team: {
                    china: 0,
                    korea: 0
                },
                result: '双方僵持'
            }
        },
        created () {
            let time = setInterval(() => {
                this.time++
                if (this.time == 90) {
                    clearInterval(time)
                }
            }, 1000)
        },
        wacth: {
            time (value, oldval) {
                if (value < 90) {
                    if (this.team.china > this.team.korea) {
                        this.result = '中国队领先'
                    } else if (this.team.china < this.team.korea) {
                        this.result = '韩国队领先'
                    } else {
                        this.result = '双方僵持'
                    }
                } else {
                    if (this.team.china > this.team.korea) {
                        this.result = '中国队赢'
                    } else if (this.team.chian < this.team.korea) {
                        this.result = '韩国队赢'
                    } else {
                        this.result = '平局'
                    }
                }
            },
            team (value, oldval) {
                if (this.time < 90) {
                    if (value.china > value.korea) {
                        this.result = '中国队领先'
                    } else if (value.china < value.korea) {
                        this.result = '韩国队领先'
                    } else {
                        this.result = '双方僵持'
                    }
                } else {
                    if (value.china > value.korea) {
                        this.result = '中国队赢'
                    } else if(value.chian < value.korea) {
                        this.result = '韩国队赢'
                    } else {
                        this.result = '平局'
                    }
                }
            }
        }
    })

    以上代码和computed产生的效果是一模一样,但是很明显,就像我对computedwatch阐述过了应用场景,这个场景只是维护了一个比赛状态,而不牵扯到逻辑操作。虽然也能完成,但无论从代码量的比对还是可读性,还是可维护性的都不胜于computed。但说到底谁更强大呢?我还是老实说watch更强大,哪里有然他有场景的局限性,但是他可以做牵扯到计算属性的一切操作,缺点是watch只能一个一个监听。

    watch应用场景

    我相信图片预加载大家肯定都有接触过,当图片量大的时候,为了保证页面图片都加载出来的时候,才渲染页面,再进行一些 Ajax请求,或者逻辑操作。那些时你用computed对这种监听一个数据然后进行一系列逻辑操作和Ajax请求,那watch再适合不过了,如果用computed的话,那是无法实现的。

    <template>
        <div v-show=show>
            <img src="https://img.alicdn.com/simba/img/TB14sYVQXXXXXc1XXXXSutbFXXX.jpg" alt="">
            <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt="">
            <img src="https://img.alicdn.com/simba/img/TB1C0dOPXXXXXarapXXSutbFXXX.jpg" alt="">
            <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt="">
        </div>
    </template>
    
    <script>
        export default {
            mounted () {
                var _this = this
                let imgs = document.querySelectorAll('img')
                console.log(imgs)
                Array.from(imgs).forEach((item)=>{
                    let img = new Image()
                    img.onload = ()=>{
                        this.count++
                    }
                    img.src=item.getAttribute('src')
                })
            },
            data () {
                return {
                    count : 0,
                    show : false
                }
            },
            watch : {
                count (val,oldval) {
                    if(val == 4){
                        this.show = true
                        alert("加载完毕")
                        //然后可以对后台发送一些ajax操作
                    }
                }
            }
        }
    </script>

    我们可以发现四张图片都加载完毕的时候,页面才渲染出来。

    Vue官方有一句话说得很重要:

    虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的watcher。这是为什么Vue提供一个更通用的方法,使用wacth来响应数据的变化。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。

    基于这个描述,我对computedwatch的总结:

    其实,computedwatch这几个都不是有多难,如果从表层上来说都很易理解,但从深层面上看,很多时候还是会存在问题。比如说会滥用,混用。这篇文章通过一些示例来讲解Vue的计算属性,并且对其做了一定的分析。我想这些对学习Vue的初级人员或许会有一些帮助。

    原文地址:https://www.w3cplus.com/vue/vue-computed.html

    (学习视频分享:web前端开发编程基础视频

    以上就是Vue计算属性computed可以做什么?应用场景浅析的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:w3cplus,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:Vue 计算属性 computed
    上一篇:聊聊vue生命周期钩子函数有哪些以及什么时候触发 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 通俗易懂!详解VUEX状态仓库管理• 实例介绍Vue通过$emit方法实现子父组件通信• 一文解析VUEX getters计算属性的基本使用• 深入了解Vue计算属性computed的使用• Vuex状态管理之Mutation的使用详解• Vue详解之增加组件扩展性的slot• Vuex状态管理之Action异步操作详解
    1/1

    PHP中文网