VUE核心学习笔记(二)

计算属性

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

  2. 原理:底层借助了Object.defineproperty方法提供的getter和setter。

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

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

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

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

  5. 备注:

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

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

// 准备一个容器
<div id="root">
  姓:<input type="text" v-model="firstName"> <br/>
  名:<input type="text" v-model="lastName"> <br/>
  姓名:<span>{{fullName}}</span>
</div>

computed:{
  fullName:{
    // get有什么用? 当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
    // get什么时候调用? 1、初次读取fullName时,2、所依赖的数据发生变化时。
    get(){
      console.log('get被调用了')
      // console.log(this) // 此处的this是vm
      // 切记 get 不要写成箭头函数,否则this指向window 而不是 vm
      return this.firstName + '-' + this.lastName
    },
    // set 什么时候被调用? 当fullName被修改时
    set(value){
      console.log('set',value)
      const arr = value.split('-')
      this.firstName = arr[0]
      this.lastName = arr[1]
    }
  }
}

计算属性的简写

前提:只考虑读取,不考虑修改的情况下,但是我们一般情况下都是读取。

computed:{
  // 直接将属性变成一个方法,当成一个getter使用
  fullName(){
    console.log('get被调用了')
    return this.firstName + '-' + this.lastName
  }
}

监视属性

  1. 监视属性:new Vue时传入watch配置 或者使用 vm.$watch监视

  2. 当被监视的属性发生变化时,回调函数自动调用,进行相关操作

  3. 监视的属性必须存在,才能进行监视!!


1、使用计算属性实现切换天气

// 准备一个容器
<div id="root">
  <h2>今天天气很{{info}}</h2>
  // 绑定事件的时候:@xxx="yyy" yyy可以写一些简单的语句
  // <button @click="isHot = !isHot ">切换天气</button>
  <button @click="changeWeather">切换天气</button>
</div>

data:{
  isHot:true,
},
computed:{
  info(){
    return this.isHot ? '炎热' : '凉爽'
  }
},
methods:{
  changeWeather(){
    this.isHot = !this.isHot
  }
}

2、使用监视属性

// 准备一个容器
<div id="root">
  <h2>今天天气很{{info}}</h2>
  <button @click="changeWeather">切换天气</button>
</div>

data:{
  isHot:true,
},
computed:{
  info(){
    return this.isHot ? '炎热' : '凉爽'
  }
},
methods:{
  changeWeather(){
    this.isHot = !this.isHot
  }
},
watch:{
  isHot:{
    immediate:true, // 初始化时让handler调用一下
    // handler什么时候调用? 当isHot发生变化时。
    handler(newValue,oldValue){
      console.log('isHot被修改了',newValue,oldValue)
    }
  }
}


//=====================================================
使用vm实例在外部监视属性
vm.$watch('isHot'{
  immediate:true, // 初始化时让handler调用一下
    // handler什么时候调用? 当isHot发生变化时。
    handler(newValue,oldValue){
      console.log('isHot被修改了',newValue,oldValue)
    }
})

监视属性的简写

前提:不需要其他配置属性时,如deep、immediate,只使用handler()的功能

// 正常写法
watch:{
  isHot:{
    // deep:true,
    immediate:true, // 初始化时让handler调用一下
    // handler什么时候调用? 当isHot发生变化时。
    handler(newValue,oldValue){
      console.log('isHot被修改了',newValue,oldValue)
    }
  }
}

// 简写方式
watch:{
    isHot(newValue,oldValue){
      console.log('isHot被修改了',newValue,oldValue)
    }
}

vm.$watch的简写方式

//正常方式
vm.$watch('isHot'{
  immediate:true, // 初始化时让handler调用一下
  deep:true,
  handler(newValue,oldValue){
    console.log('isHot被修改了',newValue,oldValue)
  }
})


// 简写方式
// 注意function不能写成箭头函数,否则this的指向不是vm,而是window
vm.$watch('isHot',function(newValue,oldValue){
    console.log('isHot被修改了',newValue,oldValue)
  }
)


深度监测

  1. Vue中的watch默认不监测对象内部值的改变(一层)

  2. 配置deep:true 可以监测对象内部值改变(多层)

  3. 备注:

    (1)、Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!

    (2)、使用watch时根据数据的具体结构,决定是否采用深度监视。

// 准备一个容器
<div id="root">
  <h2>a的值是:{{numbers.a}}</h2>
  <button @click="numbers.a++">点我a+1</button>
  <h2>b的值是:{{numbers.b}}</h2>
  <button @click="numbers.b++">点我b+1</button>
</div>

data:{
  numbers:{
    a:1,
    b:1
  }
},
watch:{
  //监测多级结构中某一个属性的变化
  'numbers.a':{
    handler(){
      console.log('a被改变了')
    }
  },
  //监测多级结构中所有属性的变化
  numbers:{
    deep:true,
    handler(){
      console.log('numberss被改变了')
    }
  }
}


computed 与 watch 比较

computed 与 watch之间的区别:

  • computed能完成的功能,watch都可以完成
  • watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作

两个重要的小原则:

  • 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
  • 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。


绑定样式

  1. class样式

    • 格式:【:class = “xxx”】 xxx可以是字符串、对象、数组

    • 字符串写法适用于:类名不确定,需要动态获取。

    • 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。

    • 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但是不确定用不用。

  2. style样式

    • 格式:【:style = “xxx”】 xxx可以是对象、数组

    • 对象的写法:样式属性如果是单个词组则小写,多个词组使用驼峰式命名。如【:style=“{fontSize:xxx}”】。

    • 数组的写法:数组里面是一个一个的对象。如【:style=“[a , b]”】,a:{fontSize:xxx},b:{color:red}。

1、绑定class样式

// 准备一个容器
<div id="root">
 <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
 <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/>
 
  <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
 <div class="basic" :class="classArr" @click="changeMood">{{name}}</div> <br/>
 
  <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
 <div class="basic" :class="classObj" @click="changeMood">{{name}}</div> <br/>
</div>

data:{
  name: '样式绑定',
  mood: 'normal', // 动态绑定的class名称
  classArr: ['class1','class2','class3'], // 将多个class名称动态绑定在div上
  classObj: {
    class1: false, // 可以通过改变对象中的class的状态,决定该样式是否生效
    class2: false
  }
},
methods:{
  changeMood(){
    // 1、修改动态绑定的class,字符串方式
    this.mood = 'happy'; // 将动态的class名称改为 happy
    
    // -------------------------------------------------
    // 2、修改动态绑定的class,随机方式
    const arr = ['class1','class2','class3']
    const index = Math.floor(Math.random()*3)
    this.mood = arr[index]
    
  }
}

2、绑定style样式

 <!-- 绑定style样式--对象写法 -->
 <div class="basic" :style="styleObj" >{{name}}</div> <br/>
  <!-- 绑定style样式--数组写法 -->
 <div class="basic" :style="styleArr">{{name}}</div> <br/>
 
 data:{
   name: '样式绑定',
   styleObj:{
     fontSize: '40px',
     color:'red',
   },
   styleArr:[
      {
        fontSize: '40px',
        color:'red',
      },
      {
        backgroundColor:'gray'
      }
    ]
 }


条件渲染

  • v-if

    (1)、v-if=“表达式”

    (2)、v-else-if=“表达式”

    (3)、v-else=“表达式”

    适用于:切换频率较低的场景

    特点:将不展示的DOM元素直接移除

    注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被“打断”。


  • v-show

    写法:v-show=“表达式”

    适用于:切换频率较高的场景

    特点:将不展示的DOM元素使用样式来控制隐藏,不移除元素


  • 备注:1、使用v-if时,元素可能无法获取到,而使用v-show时一定可以获取到。

       2、在vue中template可以和v-if配合使用,且不改变DOM的层级结构,但是template不能和v-show配合使用。

// 在使用v-if的时候可能出现以下这种情况,这种情况下当num满足num===1时还会继续执行下面的判断
<div v-if="num === 1">1</div>
<div v-if="num === 2">2</div>
<div v-if="num === 2">3</div>

// 建议使用以下方式,这种情况下当num满足num===1时就不会继续执行下面的判断了
<div v-if="num === 1">1</div>
<div v-else-if="num === 2">2</div>
<div v-else >3</div>

列表渲染

  • v-for指令

    (1)、用于展示列表数据

    (2)、语法:v-for=“(item,index) in xxx” :key = “yyy”

    (3)、可以遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

<div>
  <!-- 在这里遍历的时候 可以用 【in】或者【of】 -->
  <h2>人员列表(数组遍历)</h2>
  <ul>
    <li v-for="(p,index) of persons" :key="index">
      {{p.name}}-{{p.age}}
    </li>
  </ul>
  
  <!-- 遍历对象的时候,key就是【对象属性名称】,value就是【对象属性值】 -->
  <h2>汽车信息(对象遍历)</h2>
  <ul>
    <li v-for="(value,key) of car" :key="key">
      {{key}}-{{value}}
    </li>
  </ul>
  
  <!-- 遍历字符串的时候,char就是【字符串的每个字符】,index就是【索引值】 -->
   <h2>字符串测试(字符串遍历)</h2>
  <ul>
    <li v-for="(char,index) of str" :key="index">
      {{char}}-{{index}}
    </li>
  </ul>
  
  <!-- 遍历数字的时候,num就是【当前次数值,从1开始】,index就是【索引值】 -->
   <h2>指定次数遍历</h2>
  <ul>
    <li v-for="(num,index) of 5" :key="index">
      {{num}}-{{index}}
    </li>
  </ul>
</div>


data:{
  persons:[
    {name:'Bob',age:10},
    {name:'Alice',age:11},
    {name:'Jame',age:12}
  ],
  car:{
    name:'汽车名称',
    price:'100W'
  },
  str:'hello',
}

key的作用

面试题:react、vue中的key有什么作用?(key的内部原理)

  1. 虚拟DOM中的作用:

    key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,

    随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

  2. 对比规则

    (1)、旧虚拟DOM中找到了与新虚拟DOM相同的key:

      1、若虚拟DOM中内容没变,直接使用之前的真实DOM;

      2、若虚拟DOM内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。

    (2)、旧虚拟DOM中未找到与新虚拟DOM相同的key:创建新的真实DOM,随后渲染到页面。

  3. 用index作为key可能会引起的问题:

    1、若对数据进行:逆序添加、逆序删除等破坏顺序操作:

     			会产生没有必要的真实DOM更新 ==> 界面效果没有问题,但是效率低。
    

    2、如果结构中还包含输入类的DOM:

     			会产生错误DOM更新 ==> 界面有问题。
    
  4. 开发中如何选择key?:

    1、最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。

    2、如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示。使用index作为key是没有问题的。


VUE核心学习笔记(二)


VUE核心学习笔记(二)


参考学习视频:https://www.bilibili.com/video/BV1Zy4y1K7SH

上一篇:ArrayList删除操作


下一篇:JVM学习-CAS与原子类