Vue2入门之超详细教程八-计算属性

发布时间 2023-05-03 18:22:41作者: 李荣洋

1、简介

  计算属性:

    1.定义:要用的属性不存在,要通过已有的属性计算得来

    2.原理:底层借助Object.defineproperty方法提供的gettersetter

    3.Get函数什么时候执行?

      (1) 初次读取时会执行一次

      (2) 当依赖的数据发生改变时会被再次调用

    4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调用方便。

    5.备注:

      (1) 计算属性最终会出现在vm上,直接读取使用即可

      (2) 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变

  学习Vue之前最后会一些HTML和CSS的基础知识,HTML基础知识 传送门CSS基础知识 传送门

2、姓名案例

  让用户输入姓、名,自动显示全名,使用三种不同的方式实现。

1. 插值语法实现

  在vscode中创一个新目录,叫“07_计算属性”,在下面创建一个“1姓名案例_插值语法实现.html”文件,在里面输入以下代码:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=`, initial-scale=1.0">

    <title>Document</title>

    <script type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

    <div id="root">

        <input type="text" v-model:value="firstName"><br>

        <input type="text" v-bind:value="lastName"><br>

        全名: <span>{{firstName}} - {{lastName}}</span>

    </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        var vm = new Vue({

            el:'#root',

            data:{

                firstName:"",

                lastName:""

            }

        })

    </script>

</body>

</html>

  以上案例使用插值语法简单实现一个用户分别输入姓和名,然后联动展示的一个效果

  根据运行结果可以看出第一个姓的输入框在全名中有联动变化,但第二个输入框的输入并没有变化,这是因为v-bindv-model的特性,这两个的区别在前面章节有提到过,这边在帮大家加强一下印象

  如果用户给出了特殊定制的需求,姓取值用户输入的前2位,名取值用户输入的前3位,我们该如何作用?很简单,只需要做以下改动即可:

  firstName.slice(0,2)

  lastName.slice(0,3)

  全部代码如下:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=`, initial-scale=1.0">

    <title>Document</title>

    <script type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

    <div id="root">

        <input type="text" v-model:value="firstName"><br>

        <input type="text" v-model:value="lastName"><br>

        全名: <span>{{firstName.slice(0,2)}} - {{lastName.slice(0,3)}}</span>

    </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        var vm = new Vue({

            el:'#root',

            data:{

                firstName:"",

                lastName:""

            }

        })

    </script>

</body>

</html>

 2. Methods语法实现

  在07_计算属性”文件夹下下面创建一个“2姓名案例_methods语法实现.html”文件,在里面输入以下代码:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName()}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            methods:{

                fullName(){

                    return this.firstName + '-' + this.lastName

                }

            }

        })

    </script>

</body>

</html>

3. 计算属性语法实现

  在07_计算属性”文件夹下下面创建一个“3姓名案例_计算属性实现.html”文件,在里面输入以下代码:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            computed:{

                fullName:{

                    //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就会作为fullName的返回值

                    //1.初次读取fullName时,2.所依赖的数据发生变化时

                    get(){

                        return this.firstName + '-' + this.lastName

                    }

                }

            }

        })

    </script>

</body>

</html>

   计算属性除了get方法还有set方法,set方法当数据被改变时被调用,全量代码如下:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        const vm = new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            computed:{

                fullName:{

                    //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就会作为fullName的返回值

                    //1.初次读取fullName时,2.所依赖的数据发生变化时

                    get(){

                        console.log('计算属性方法被调用了')

                        return this.firstName + '-' + this.lastName

                    },

                    //当fullName被修改时被调用

                    set(value){

                        var arr = value.split('-')

                        this.firstName = arr[0]

                        this.lastName = arr[1]

                    }

                }

            }

        })

    </script>

</body>

</html>

4. 计算属性简写方式

  简写方式必须在确定只读取属性,不会改变属性的情况下使用。

  在07_计算属性”文件夹下下面创建一个“4姓名案例_计算属性简写方式.html”文件,在里面输入以下代码:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        const vm = new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            computed:{

                fullName(){

                    console.log('计算属性方法被调用了')

                    return this.firstName + '-' + this.lastName

                }

            }

        })

    </script>

</body>

</html>

3、测试

  以上案例使用插值语法、methods语法和计算属性方法都可以实现,我们使用什么属性呢,建议使用计算属性语法,因为计算属性语法有缓存,当多次调用相同方法时,只会执行一次。

  我们做一下测试,分别使用methods方法和计算属性方法,在页面中多次调用相同方法并输出调用次数

1. Methods方法调用次数

  修改methods方法实现案例代码如下:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName()}}</span>

        全名:<span>{{fullName()}}</span>

        全名:<span>{{fullName()}}</span>

        全名:<span>{{fullName()}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            methods:{

                fullName(){

                    console.log('methods方法被调用了')

                    return this.firstName + '-' + this.lastName

                }

            }

        })

    </script>

</body>

</html>

2. 计算属性方法调用次数

  修改计算属性方法实现案例代码如下:

<!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 type="text/javascript" src="../js/development/vue.js"></script>

</head>

<body>

     <div id="root">

        姓:<input type="text" v-model:value="firstName"><br>

        名:<input type="text" v-model:value="lastName"><br>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

        全名:<span>{{fullName}}</span>

     </div>

    <script type="text/javascript">

        Vue.config.productionTip = false

        new Vue({

            el:'#root',

            data:{

                firstName:'',

                lastName:''

            },

            computed:{

                fullName:{

                    //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就会作为fullName的返回值

                    //1.初次读取fullName时,2.所依赖的数据发生变化时

                    get(){

                        console.log('计算属性方法被调用了')

                        return this.firstName + '-' + this.lastName

                    }

                }

            }

        })

    </script>

</body>

</html>

4、小结

  计算属性比methods方法更有效率

  计算属性的调用方式不需要写(),语法与插值语法相同

  计算属性的简写方式必须在确定不会修改参数的情况下使用