• 使用Computed properties(计算得到的属性)和watchers(监听器)
    • 典型例子
    • Computed Properties 与 普通方法的区别。
    • watched property
      • 使用computed 会比watch 更加简洁
    • 为 computed property 的setter (赋值函数)

    使用Computed properties(计算得到的属性)和watchers(监听器)

    很多时候,我们在页面上想要显示某个变量的值时,都需要经过一些计算, 例如:

    1. <div id="example">
    2. {% raw %}{{{% endraw %} some_string.split(',').reverse().join('-') }}
    3. </div>

    越是复杂,到后期越容易出错。

    这个时候,我们就需要一种机制,可以方便的创建这样的通过计算得来的数据。

    所以, Computed Properties 就是我们的解决方案。

    典型例子

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. <p> 原始字符串: {{my_text}} </p>
    8. <p> 通过运算后得到的字符串: {{my_computed_text}} </p>
    9. </div>
    10. <script>
    11. var app = new Vue({
    12. el: '#app',
    13. data: {
    14. my_text: 'good good study, day day up'
    15. },
    16. computed: {
    17. my_computed_text: function(){
    18. // 先去掉逗号,然后按照空格分割成数组,然后翻转,并用'-'来连接
    19. return this.my_text.replace(',', '').split(' ').reverse().join('-')
    20. }
    21. }
    22. })
    23. </script>
    24. </body>
    25. </html>

    可以看到,上面的关键代码是,在 Vue的构造函数中, 传入一个 computed的段落。

    使用浏览器运行后,可以看到结果如下图所示:

    computed properties例子

    我们也打开 console 来查看。

    输入

    1. > app.my_text

    会得到: “good good study, day day up”

    输入

    1. > app.my_computed_text

    会得到转换后的: “up-day-day-study-good-good”

    Computed Properties 与 普通方法的区别。

    根据上面的例子,我们可以使用 普通方法来实现:

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. <p> 原始字符串: {{my_text}} </p>
    8. <p> 通过运算后得到的字符串: {% raw %}{{{% endraw %}my_computed_text() }} </p>
    9. </div>
    10. <script>
    11. var app = new Vue({
    12. el: '#app',
    13. data: {
    14. my_text: 'good good study, day day up'
    15. },
    16. methods: {
    17. my_computed_text: function(){
    18. return this.my_text.replace(',', '').split(' ').reverse().join('-') + ',我来自于 function, 不是computed '
    19. }
    20. }
    21. })
    22. </script>
    23. </body>
    24. </html>

    上面的代码,运行后如下图所示:

    使用function代替computed properties

    可以发现,他们达到的效果是一样的。

    他们的区别在于: 使用computed properties的方式,会把结果“缓存”起来。 每次调用对应的computed properties时,只要对应的依赖数据没有改动,那么就不会变化。

    而使用 “function” 实现的版本,则不存在缓存问题。 每次都会重新计算对应的数值。

    所以, 我们需要按照实际情况,来选择是使用 “computed properties” , 还是使用普通function的形式。

    watched property

    Vuejs 中的property(属性), 是可以要么根据计算发生变化(computed) , 要么根据监听(watch)其他的变量的变化而发生变化

    我们看一下,如何根据监听(watch) 其他的变量而自身发生变化的例子, 如下;

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. <p>
    8. 我所在的城市: <input v-model='city' />(这是个watched property)
    9. </p>
    10. <p>
    11. 我所在的街道: <input v-model='district' />(这是个watched property)
    12. </p>
    13. <p> 我所在的详细一些的地址: {{full_address}} (每次其他两个发生变化,这里就会跟着变化) </p>
    14. </div>
    15. <script>
    16. var app = new Vue({
    17. el: '#app',
    18. data: {
    19. city: '北京市',
    20. district: '朝阳区',
    21. full_address: "某市某区"
    22. },
    23. watch: {
    24. city: function(city_name){
    25. this.full_address = city_name + '-' + this.district
    26. },
    27. district: function(district_name){
    28. this.full_address = this.city + '-' + district_name
    29. }
    30. }
    31. })
    32. </script>
    33. </body>
    34. </html>

    在上面的代码中, 可以看到, watch: { city: ..., district: ...}, 表示, citydistrict 都已经被监听了, 这两个都是 watched properties.

    只要citydistrict发生变化, full_address 就会跟着变化。

    我们用浏览器打开上面的代码,如下图所示,此时 由于 citydistrict 还没有发生变化,所以 full_address的值还是 “某市某区” :

    被监听的属性

    当我在 “街道” 的输入框, 后面加上 “望京街道” 几个字后,可以看到, 下面的“详细地址”, 就发生了变化。 如下图所示:

    发生了变化的监听属性

    使用computed 会比watch 更加简洁

    上面的例子,我们可以使用 computed 来改写, 如下图所示:

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. <p>
    8. 我所在的城市: <input v-model='city' />
    9. </p>
    10. <p>
    11. 我所在的街道: <input v-model='district' />
    12. </p>
    13. <p> 我所在的详细一些的地址: {{full_address}} (这是使用computed 实现的版本) </p>
    14. </div>
    15. <script>
    16. var app = new Vue({
    17. el: '#app',
    18. data: {
    19. city: '北京市',
    20. district: '朝阳区',
    21. },
    22. computed: {
    23. full_address: function(){
    24. return this.city + this.district;
    25. }
    26. }
    27. })
    28. </script>
    29. </body>
    30. </html>

    可以看到, 方法少了一个 , data中定义的属性也少了一个,简洁了不少。 代码简洁,维护起来就容易(代码量越少,程序越好理解)

    为 computed property 的setter (赋值函数)

    原则上来说, computed property 是根据其他的值,经过计算得来的。 是不应该被修改的。

    不过在开发中,确实有一些情况,需要对 “computed property” 做修改, 同时影响某些对应的属性。 (过程跟上面是相反的) .

    我们看下面的代码:

    1. <html>
    2. <head>
    3. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    4. </head>
    5. <body>
    6. <div id='app'>
    7. <p>
    8. 我所在的城市: <input v-model='city' />
    9. </p>
    10. <p>
    11. 我所在的街道: <input v-model='district' />
    12. </p>
    13. <p> 我所在的详细一些的地址: <input v-model='full_address' /> </p>
    14. </div>
    15. <script>
    16. var app = new Vue({
    17. el: '#app',
    18. data: {
    19. city: '北京市',
    20. district: '朝阳区',
    21. },
    22. computed: {
    23. full_address: {
    24. get: function(){
    25. return this.city + "-" + this.district;
    26. },
    27. set: function(new_value){
    28. this.city = new_value.split('-')[0]
    29. this.district = new_value.split('-')[1]
    30. }
    31. }
    32. }
    33. })
    34. </script>
    35. </body>
    36. </html>

    可以看出, 上面代码中,有这样一段:

    1. computed: {
    2. full_address: {
    3. get: function(){
    4. return this.city + "-" + this.district;
    5. },
    6. set: function(new_value){
    7. this.city = new_value.split('-')[0]
    8. this.district = new_value.split('-')[1]
    9. }
    10. }
    11. }

    可以看出, 上面的 get 代码段,就是原来的代码内容。 而 set端中,则定义了,如果 computed property (也就是 full_address) 发生变化的时候,citydistrict 的值应该如何变化。

    用浏览器打开后, 我们在 “最下方的输入框” 中,后面输入一些字,可以看到, 对应的 “街道”发生了变化:

    根据setter影响其他变量的例子