IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 计算属性和侦听器 -> 正文阅读

[JavaScript知识库]计算属性和侦听器

一、计算属性

1.1 什么是计算属性

首先通过一个示例来介绍计算属性,需求是把一个字符串倒序显示,具体代码如示例1所示:

<template>
  <div class="hello">
   <h1>{{msg}}转为{{msg.split('').reverse().join('')}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

浏览器显示效果图:

总结:通过浏览器显示效果图可知,在插值表达式中通过调用一系列的字符串方法,把“Welcome to Your Vue.js App”字符串进行了倒序显示。再看示例1的代码,如果插值表达式中的代码过长或者逻辑较为复杂,就会变得臃肿不堪甚至难以阅读和维护,所以在遇到复杂的逻辑时,官方不推荐使用插值表达式,而是使用计算属性把逻辑复杂的代码进行分离。

用计算属性改写示例1的代码,具体代码如下:

<template>
  <div class="hello">
   <h1>计算属性:{{reversedMsg}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  computed:{
    reversedMsg:function(){
      return this.msg.split('').reverse().join('')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

?浏览器效果图:

?通过浏览器中的显示可以看到,利用计算属性依然可以完成字符串的倒序显示,计算属性可以分离逻辑代码,使代码的易维护性增强。以后遇到这种逻辑较为复杂的代码,均可以使用计算属性进行分离。所有计算属性都以函数的形式写在vue实例的compted选项内,最终返回计算后的结果。

1.2 计算属性用法

?????? 在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。除了上面示例中的简单用法外,计算属性还可以依赖多个Vue实例的数据,只要其中任何一个数据变化,计算属性就会重新执行,视图也会更新。下面通过购物车商品总价的示例来展示,具体代码如下:

<template>
  <div class="hello">
   <h1>总价:{{prices}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      package1:[
        {
          name:"iphone8",
          price:5688,
          count:1
        },
        {
          name:"ipad",
          price:2888,
          count:1
        }
      ],
      package2:[
        {
          name:"apple",
          price:3,
          count:5
        },
        {
          name:"banana",
          price:6,
          count:3
        }
      ]
    }
  },
  computed:{
    prices:function(){
      var prices=0;
      for(var i=0;i<this.package1.length;i++){
        prices+=this.package1[i].price*this.package1[i].count;
      }
      for(var i=0;i<this.package2[i].length;i++){
        prices+=this.package2[i].price*this.package2[i].count;
      }
      return prices;
    }
  }
};

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

?1.3 props动态传值与计算属性computed的结合

当props作为需要被转变的原始值传入,这时使用计算属性就可以了。动态加样式改变盒子的宽度。

示例代码(父组件App.vue):

<template>
  <div id="app">
   <Child :width="200"></Child>
  </div>
</template>

<script>
import Child from './components/Child.vue'
export default {
  components: { Child },
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

子组件代码(Child.vue):

<template>
  <div :style="style" class="page">
    组件内容
  </div>
</template>

<script>
export default {
    name:'Child',
    data(){
        return{

        }
    },
    props:['width'],
    computed:{
        style:function(){
            return{
                width:this.width+"px"
            }
        }
    }

}
</script>

<style>
.page{
    border:1px solid #000;
}
</style>

页面效果图:

因为在传递宽度的时候要带单位(px),但每次都要写太麻烦,而且数值的计算一般都不带单位,所以统一在组件内使用计算属性实现。

1.4 计算属性缓存

我们从前面这些案例可以看到,调用methods里面的方法也可以与计算属性起到同样的作用,比如这里把示例1的功能用methods改写。

methods改写后的示例代码:

<template>
  <div class="hello">
 <!-- 这里的reversedMsg是方法,必须要带括号 -->
   <h1>methods改写:{{reversedMsg()}}</h1>
   <h1>methods改写:{{reversedMsg()}}</h1>
   <h1>methods改写:{{reversedMsg()}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  computed:{
    
  },
  methods:{
    reversedMsg(){
      console.log("reversedMsg函数被调用了!")
      return this.msg.split('').reverse().join('')
    }

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

显示效果:

?通过上面的改写,没有使用计算属性,而是在method里面定义了一个方法实现相同的效果,甚至该方法还可以接收参数,使用起来更加灵活。那既然使用methods就可以实现,为什么还要计算属性呢?

原因是计算属性是基于它的依赖缓存的,一个计算属性所依赖的数据发生变化,它才会重新取值,所以msg只要不改变,计算属性就不会更新,只解析一次。但是methods不同,只要重新渲染,它就会被调用,函数就会被执行。

所以,究竟是使用计算属性还是methods取决于是否需要缓存,当遍历大数组和计算量很大时,应当使用计算属性,除非不希望得到缓存。

?二、侦听器

2.1 什么是侦听器

Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动,称为侦听器

下面通过实例代码来讲解侦听器的使用,具体代码如下:

<template>
  <div class="hello">
  <input type="text" v-model="firstName"/>
  <input type="text" v-model="lastName"/>
  <h1>{{fullName}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      firstName:"Foo",
      lastName:"Bar",
      fullName:"Foo Bar"
    }
  },
  watch:{
    firstName:function(val){
      this.fullName=val+" "+this.lastName
    },
    lastName:function(val){
      this.fullName=this.firstName+" "+val
    }

  }
  
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

浏览器效果图:

?2.2? 计算属性VS侦听器

上面示例中的代码是命令式且重复的,将它使用计算属性修改之后进行比较,代码如下所示:

<template>
  <div class="hello">
    <input type="text" v-model="firstName"/>
    <input type="text" v-model="lastName"/>
    <h1>{{fullName}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      firstName:"Foo",
      lastName:"Bar",
    }
  },
  computed:{
    fullName:function(){
      return this.firstName+""+this.lastName
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

?使用计算属性改写后感觉代码更简洁了。那为什么还要使用侦听器呢?

现在有一个需求:文本输入框中中的firstName和lastName其中一个内容发生了改变,fullName过1s钟之后再更新这个变化。

1.使用watch侦听器改写代码

<template>
  <div class="hello">
    <input type="text" v-model="firstName"/>
    <input type="text" v-model="lastName"/>
    <h1>{{fullName}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      firstName:"Foo",
      lastName:"Bar",
      fullName:"Foo Bar"
    }
  },
  // computed:{
  //   fullName:function(){
  //     return this.firstName+""+this.lastName
  //   }
  // }
  watch:{
    firstName(val){
      setTimeout(()=>{
        this.fullName=val+" "+this.lastName  
      },1000)
      
    },
    lastName(val){
      setTimeout(()=>{
        this.fullName=this.firstName+" "+val 
      },1000)
      
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

2.使用计算属性computed改写代码,发现运行不出来结果,无法实现定时功能(异步操作)。

computed和watch之间的区别:
?? ?? 1.computed能完成的功能,watch都可以完成。
?? ?? 2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
两个重要的小原则:
?? 1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
?? 2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:40:43  更:2022-03-21 20:41:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:51:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码