VUE入门到实战--Vue计算属性,方法和侦听器

1、计算属性

1.1、初识计算属性

1、为了防止数据冗余,我们使用实例属性computed来解决,computed是缓存机制,这个缓存机制就是作为参数用来计算的变量没有改变,那么就不会重复计算。

2、什么意思?比如说下面的fullName由firstName和lastName计算,页面开始的时候会计算一次fullName的值并缓存下来,在页面刷新或者过程中firstName和lastName没有发生变化,那么fullName一直用的是缓存的值。但是一但firstName和lastName发生了改变,那么fullName就会重新计算一次,并缓存下来。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue计算属性,方法和侦听器</title>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="app">
        {{ fullName }}
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: "Dell",
                lastName: "Lee",
            },
            //计算属性:解决数据的冗余
            computed: {
                fullName: function() {
                    console.log("计算了一次fullName");
                    return this.firstName + " " + this.lastName ;
                }
            },
        })
    </script>
</body>
</html>

1.2、计算属性的setter和getter

1、由于我们的上面的例子中fullName是计算属性中的,所以是依赖firstName和lastName,我们不能直接给fullName赋值来改变他,必须通过改变firstName和lastName的值来改变它,所以出现了setter和getter。

2、计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算属性的setter和getter</title>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="app">
        {{ fullName }}
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Dell',
                lastName: 'Lell',
            },
            computed: {
                fullName: {
                    get: function() {
                        return this.firstName + " " + this.lastName;
                    },
                    set:function(value) {
                        var arr = value.split(" "); //以空格为分隔符,将arr分隔为字符串数组
                        this.firstName = arr[0];
                        this.lastName = arr[1];
                    }
                }
            }
        })
    </script>
</body>
</html>

2、方法

1、上面我们通过计算属性的方式来实现,实际上通过方法也能够实现同样的效果。但是注意的是,在插值表达式中使用methods中的方法要记得带上括号。如下所示:

2、虽然使用方法能和计算属性达到相同的效果,但是不如计算属性性能好,因为使用了方法,即使firstName或者lastName没有发生变化,如下列中你改变age这个和fullName完全不相关的变量,fullName也会重新计算一次,这种就很烦躁。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue计算属性,方法和侦听器</title>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="app"> <!--插值表达式中使用methods的方法要记得带上括号-->
        {{ fullName() }}
        {{ age }}
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: "Dell",
                lastName: "Lee",
                age: 22,
            },
            methods: {
                fullName: function() {
                    console.log("计算了一次fullName");
                    return this.firstName + " " + this.lastName ; 
                }
            }
        })
    </script>
</body>
</html>

3、侦听器(watch)

1、除了我们上面使用的两种方法,还有第三种放法可以实现这样的效果,侦听器,当数据发生变化,我们使用一个函数来写变化导致的操作。

2、watch这种方式和computed相比,也存在缓存机制,但是缺点也很明显,很复杂,而且需要侦听所有会导致fullNname变化的参数。所以这三个方法我们还是推荐computed这种方法,简洁,性能高

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue侦听器</title>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="app">
        {{ fullName }}
        {{ age }}
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                firstName: 'Dell',
                lastName: 'Lell',
                fullName: 'Dell Lell',
                age: 22,
            },
            //侦听器
            watch: {
                //监听firstName的变化,当firstName变化重新计算fullName
                firstName: function() {
                    console.log("firstName导致的计算") ;
                    this.fullName = this.firstName + " " + this.lastName ; 
                },
                lastName: function() {
                    console.log("lastName导致的计算") ;
                    this.fullName = this.firstName + " " + this.lastName ;
                },
            }
        })
    </script>
</body>
</html>

3、虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。下面这个是官方的例子,很有用:(这个例子就是在一个输入框中输入内容,每次的输入都会导致question的改变,由于使用了watch来监听,每次的输入都会去执行getAnswer函数,而这个函数中就是先判断有没有“?”,没有就自动return,认为你还没有输入完,当你输入?后,就开始去访问API,然后返回获得的数据)

<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 发生改变,这个函数就会运行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
    // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
    // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
    // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
    // 请参考:https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})
</script>

4、在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值