Vue---第十九章计算属性和监听器

1.我们首先还是来看看代码

 

查看我们的结果

 

 首先我们来解释一下整体的思路:

data的内容和v-model的就不用说了,双向绑定默认值,也可以在input输入框内修改值

v-model调用函数的方法如上诉内容一致,只是需要加一个小括号

然后计算的方式从函数中进行返回显示在页面

为什么要减去一个0呢,是因为用户在页面进行输入的时候默认是string类型,减去一个0是为了字符串转数字运算。

 

 我们来使用属性的方法来做做

 

 

<body>
    <div id="app">
        数学:<input type="text" v-model="mathScore">
        英语:<input type="text" v-model="englishScore">
        语文:<input type="text" v-model="chineseScore"><br/>
        <!--v-model调用函数时不要少了小括号()-->
        总学分(函数):<input type="text" v-model="sumScore()">
        <!--v-model调用属性不要加小括号-->
        总学分(属性):<input type="text" v-model="sumScore1">
    </div>
    <script src="./node_modules/vue/dist/vue.js"></Script>
    <script>
        var vm=new Vue({
            el:'#app',
            data:{
                mathScore: 80,
                englishScore: 90,
                chineseScore: 50
            },
            methods:{
                sumScore:function(){
                    console.log('函数被调用')
                    //this指向的就是vm实例
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                }
            },
            computed:{
                sumScore1:function(){
                    console.log('属性被调用')
                    //this指向的就是vm实例
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                }
            }
        })
    </script>
</body>

 

 

属性:计算值有缓存,如果计算值不发生改变则属性不会重新计算,只有发生改变时才会重新计算
属性和函数的差别,函数只能单向绑定,而属性可以单向也可以双向

 

 

 

 

 

 我们来看看源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/vue/dist/vue.js"></Script>
</head>
<body>
    <div id="app">
        数学:<input type="text" v-model="mathScore">
        英语:<input type="text" v-model="englishScore">
        语文:<input type="text" v-model="chineseScore"><br/>
        <!--v-model调用函数时不要少了小括号()-->
        总学分(函数):<input type="text" v-model="sumScore()">
        <!--v-model调用属性不要加小括号-->
        总学分(属性单向):<input type="text" v-model="sumScore1">
        总学分(属性双向):<input type="text" v-model="sumScore2">
    </div>
    
    <script>
        var vm=new Vue({
            el:'#app',
            data:{
                mathScore: 80,
                englishScore: 90,
                chineseScore: 50
            },
            methods:{
                sumScore:function(){
                    console.log('函数被调用')
                    //this指向的就是vm实例
                    //函数只支持单向绑定
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                }
            },
            computed:{
                sumScore1:function(){
                    //通过set方法支持双向绑定
                    //属性,计算值有缓存,如果计算值不发生改变则属性不会重新计算,只有发生改变时才会重新计算
                    console.log('属性被调用')
                    //this指向的就是vm实例
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                },
                //sumScore2是双向绑定
                sumScore2:{
                    get:function(){
                        return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                    },
                    set:function(newValue){
                        var avgScore = newValue / 3 
                        this.mathScore=avgScore
                        this.englishScore=avgScore
                        this.chineseScore=avgScore
                    }
                }
            }
        })
    </script>
</body>
</html>

 

 监听器 watch 

1. 通过 watch 选项 监听数学分数, 当数学更新后回调函数中重新计算总分sumScore3

2. 通过 vm.$watch() 选项 监听英语分数, 当英语更新后回调函数中重新计算总分sumScore3

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./node_modules/vue/dist/vue.js"></Script>
</head>
<body>
    <div id="app">
        数学:<input type="text" v-model="mathScore">
        英语:<input type="text" v-model="englishScore">
        语文:<input type="text" v-model="chineseScore"><br/>
        <!--v-model调用函数时不要少了小括号()-->
        总学分(函数):<input type="text" v-model="sumScore()"><br> 
        <!--v-model调用属性不要加小括号-->
        总学分(属性单向):<input type="text" v-model="sumScore1"><br> 
        总学分(属性双向):<input type="text" v-model="sumScore2"><br> 
        总分(监听器):<input type="text" v-model="sumScore3"><br> 
        <div>总分(监听器):{{sumScore3}}</div>
    </div>
    
    <script>
        var vm=new Vue({
            el:'#app',
            data:{
                mathScore: 80,
                englishScore: 90,
                chineseScore: 50,
                //通过监听器计算的总得分
                sumScore3:0
            },
            methods:{
                //注意计算函数不需要在上面进行定义,可以直接被调用
                sumScore:function(){
                    console.log('函数被调用')
                    //this指向的就是vm实例
                    //函数只支持单向绑定
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                }
            },
            computed:{
                //注意计算方法/属性不需要在上面进行定义,可以直接被调用
                sumScore1:function(){
                    //通过set方法支持双向绑定
                    //属性,计算值有缓存,如果计算值不发生改变则属性不会重新计算,只有发生改变时才会重新计算
                    console.log('属性被调用')
                    //this指向的就是vm实例
                    return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                },
                //sumScore2是双向绑定
                sumScore2:{
                    get:function(){
                        console.log('sumScore2.get属性被调用')
                        return (this.mathScore-0)+(this.englishScore-0)+(this.chineseScore-0)
                    },
                    set:function(newValue){//value为更新后的值       
                        console.log('sumScore2.set属性被调用')                
                        // 被调用则更新了sumScore2,然后将数学和英语更新为平均
                        var avgScore = newValue / 3 
                        this.mathScore=avgScore
                        this.englishScore=avgScore
                        this.chineseScore=avgScore
                    }
                }
            },
             //监听器方式1:watch选项            
            watch : {                
                //当数学修改后,更新总分sumScore3                
                mathScore : function (newValue, oldValue) {                    
                    //newValue 就是新输入的数学得分
                    console.log('使用监听器监听到了总分')          
                    this.sumScore3 = (newValue-0) + (this.englishScore-0)+ (this.chineseScore-0)
                }      
            },
        //监听器方式2:通过vm对象调用        
        //第1个参数为监听的属性名,第2个回调函数
        })
        vm.$watch('englishScore', function (newValue) {
            //newValue 就是新输入的英语得分
            console.log('监听英语分数计算总分')   
            //this.sumScore3 = (newValue-0) + (this.mathScore-0)+ (this.chineseScore-0)
            return (newValue-0) + (this.mathScore-0)+ (this.chineseScore-0)
        })
        vm.$watch('sumScore2', function (newValue) {
            //newValue 就是新输入的英语得分
            console.log('监听语文分数计算总分')
            var avgScore = newValue / 3 
            this.mathScore=avgScore
            this.englishScore=avgScore
            this.chineseScore=avgScore
            //return this.mathScore
        })
    </script>
</body>
</html>
 

 

posted @ 2021-02-08 17:51  沫笙*  阅读(78)  评论(0编辑  收藏  举报