<h2>{{...">
最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue3学习 --- 计算属性和watch

    正文概述 掘金(coderwxf)   2021-07-31   428

    计算属性

    在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

    模板中书写表达式

    <template id="template">
      <h2>{{ `${user.firstName} ---- ${user.lastName}` }}</h2>
      <h2>{{ `${user.firstName} ---- ${user.lastName}` }}</h2>
      <h2>{{ `${user.firstName} ---- ${user.lastName}` }}</h2>
    </template>
    
    <script>
      Vue.createApp({
        template: '#template',
    
        data() {
          return {
            user: {
              firstName: 'Klaus',
              lastName: 'Wang'
            }
          }
        }
      }).mount('#app')
    </script>
    

    缺点:

    1. 模板中存在大量的复杂逻辑,不便于维护(模板中表达式的初衷是用于简单的计算)

    2. 当有多次一样的逻辑时,存在重复的代码

    3. 多次使用的时候,很多运算也需要多次执行,没有缓存;

    methods中的实现

    <template id="template">
      <h2>{{ getFullname() }}</h2>
      <h2>{{ getFullname() }}</h2>
      <h2>{{ getFullname() }}</h2>
    </template>
    
    <script>
      Vue.createApp({
        template: '#template',
    
        data() {
          return {
            user: {
              firstName: 'Klaus',
              lastName: 'Wang'
            }
          }
        },
    
        methods: {
          getFullname() {
            return `${this.user.firstName} ---- ${this.user.lastName}`
          }
        }
      }).mount('#app')
    </script>
    

    缺点:

    1. 我们仅仅只是想要在界面上展示对应的值,但是变成了多次的方法调用
    2. 多次使用方法的时候,没有缓存,也需要多次计算

    computed

    <template id="template">
        <h2>{{ fullName }}</h2>
        <h2>{{ fullName }}</h2>
        <h2>{{ fullName }}</h2>
      </template>
    
      <script>
        Vue.createApp({
          template: '#template',
    
          data() {
            return {
             user: {
               firstName: 'Klaus',
               lastName: 'Wang'
             }
            }
          },
    
          computed: {
            fullName() {
              return `${this.user.firstName} ---- ${this.user.lastName}`
            }
          }
        }).mount('#app')
      </script>
    

    计算属性 VS Methods

    <template id="template">
    <h2>{{ fullName }}</h2>
    <h2>{{ fullName }}</h2>
    <h2>{{ fullName }}</h2>
    
    <h2>{{ getFullname() }}</h2>
    <h2>{{ getFullname() }}</h2>
    <h2>{{ getFullname() }}</h2>
    </template>
    
    <script>
      Vue.createApp({
        template: '#template',
    
        data() {
          return {
            user: {
              firstName: 'Klaus',
              lastName: 'Wang'
            }
          }
        },
    
        computed: {
          fullName() {
            return `${this.user.firstName} ---- ${this.user.lastName}`
          }
        },
    
        methods: {
          getFullname() {
            return `${this.user.firstName} ---- ${this.user.lastName}`
          }
        }
      }).mount('#app')
    </script>
    

    计算属性本质上是一个对象

    完整写法

    computed: {
      fullName: {
        set() {
          return `${this.user.firstName} ---- ${this.user.lastName}`
        },
    
          get(v) {
            const names = v.split(' --- ')
            this.firstName = names[0].trim()
            this.lastName = names[1].trim()
          }
      }
    }
    
    methods: {
      // 写成方法的时候,其实是计算属性的语法糖,即只实现了get方法,而没有实现set方法
      getFullname() {
        return `${this.user.firstName} ---- ${this.user.lastName}`
      }
    }
    

    watch

    开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中

    当数据变化时,template会自动进行更新来显示最新的数据

    但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,并实现相应的处理逻辑

    这个时候就需要用侦听器watch来完成

    watch: {
      // 参数1: 新值 参数2: 修改之前的旧值
      fullName(newV, oldV) {
        console.log(newV, oldV)
      }
    }
    

    配置选项

    watch: {
      fullName: {
        // 深度监听,默认vue对于复杂数据类型只会对引用地址进行监听
        // 所以当一个对象的属性发生改变的时候,是没有办法被监听到的
        // 如果需要被监听到,就必须使用深度监听
        deep: true, 
         
        // 监听器的执行是在渲染完毕以后,对应值发生改变的时候
        // 如果我们希望初次渲染的时候,即刻执行,可以设置immediate为true
        // 此时侦听器就会在初次渲染的时候被执行(也就意味着oldV的值是undefined)
        immediate: true,
        handler(newV, oldV) {
          console.log(newV, oldV)
        }
      }
    }
    

    其它写法

    字符串形式

    watch: {
      // 即将handler函数抽离到methods中进行定义
      fullName: 'handleWatch'
    },
    
    methods: {
      handleWatch(newV, oldV) {
        console.log(newV, oldV)
      }
    }
    

    数组写法

    watch: {
      fullName: [
        'handlefullNameChange',
        
        // vue会自动遍历数组中的值并执行,所以这里的函数可以是一个匿名函数
        function(newV, oldV) {
          console.log(newV, oldV)
        },
    
        {
          immediate: true,
          handler(newV, oldV) {
            console.log('immediate', newV, oldV)
          }
        }
      ]
    },
    

    监听属性

    watch: {
      'user.name'(newV, oldV) {
        console.log('immediate', newV, oldV)
      }
    }
    

    但是vue是无法监听数组对象成员的变化的

    // 下面这种写法是错误的, 值会发生改变,但是并不会触发监听操作
    watch: {
      'user[0].name'(newV, oldV) {
        console.log('immediate', newV, oldV)
      }
    }
    

    深度监听对象

    Vue.createApp({
      template: '#template',
    
      data() {
        return {
          users: [
            {name:'Klaus'},
            {name:'Steven'},
            {name:'James'}
          ]
        }
      },
    
      watch: {
        users: {
          deep: true,
          handler(newV, oldV) {
            // 在引用数据类型的监听中 oldV是没有任何的意义的,
            // 对于引用数据类型中的旧值和新值, 仅仅只是引用地址上的赋值,并没有做浅拷贝或深拷贝
            console.log(newV === oldV) // => true
          }
        }
      },
    
      methods: {
        handleClick() {
          this.users[0].name = 'Alex'
        }
      }
    }).mount('#app')
    

    $set

    created() {
      // $watch 的设置方式和在watch option中的设置 效果是一致的
      // 这里第二个handler函数可以是箭头函数,因为外层作用域是created函数,其内部this就是当前组件data的proxy对象
      this.$watch('fullName', (newV, oldV) => console.log(newV, oldV), {
        immediate: true,
        deep: true
      })
    }
    

    Tips: vue3已经移除了侦听器,可以使用计算属性,方法(定义在组件中的局部方法或定义在app.config.globalProperies的全局方法)替代

    // 使用计算属性替换过滤器,来为价格前面加上¥
    filterBooks() {
      return this.books.map(item => {
        // 为了避免需要展示的数据污染旧的实际进行逻辑判断的数据,
        // 需要对这些复杂类型数据进行浅拷贝
        const newItem = Object.assign({}, item);
        newItem.price = "¥" + item.price;
        return newItem;
      })
    }
    

    起源地下载网 » Vue3学习 --- 计算属性和watch

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元