Vue 3 相关知识点

setup 方法

Vue3中的setup 中可写data 里面的数据,methods 方法 但需要通过return 将存储的数据和方法return 出去,页面才能进行访问。

  export default {
    setup(){
    let name="张三"
  return {
      name,
    };
    }
  }

注意点:
setup执行的时机
在beforeCreate之前执行依次,this 是undefined
setup的参数
props 值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象
attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this. a t t r s s l o t s 收到的插槽内容,相当于 t h i s . attrs slots 收到的插槽内容,相当于this. attrsslots收到的插槽内容,相当于this.slots
emit 分发自定义事件的函数,相当于this.$emit

ref

作用: Vue2 中ref 绑定属性 ,还保持,但Vue3 是方法。 是将普通数据变为响应式数据

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-08 09:31:27
 * @LastEditors: 莲白
-->
<template>
  <ul>
    <li>{{ name }}</li>
    <li>{{ age }}</li>
    <li><button @click="changInfo">修改人的信息</button></li>
  </ul>
</template>

<script>
import {ref} from 'vue' //1.引入ref 方法
export default {
  name: "App",
  setup() {
    let [name, age] = [ref(`张三`),ref(18) ]; //2 套用ref 方法
    function changInfo() {
 console.log(name, age); 
 name.value='张氏'
 age.value=20  
    } //3.因为使用ref 方法,会将原本变量变为对象,需要通过 数据.value 进行访问
    return {
      name,
      age,
      changInfo,
    };
  },
};
</script>

reactive 函数

import {reactive} from 'vue' //1.引入ref 方法
    let [job,] = [reactive({
   type:'前端',
      salary: '30k',
    }), ];//2 套用reactive 方法
      job.salary='20k'  //修改

总结:
ref 函数 作用:定义一个响应式的数据
语法 const xxx=ref(initValue)
1.创建一个包含响应式数据的引用对象(reference 对象)
2.js 中操作数据 : xxx.value
3.模板中读取数据,不需要value ,直接:

{{xxxx}}

备注:
1.接受的数据可以是:基本类型,也可以是对象类型
2.基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的
3.对象类型的数据:内部 求助了Vue3.0中的一个新函数----reactive函数
reactive 函数
作用定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象=reactive(源对象)接收一个对象(或数组),返回一个代理对象(proxy对象简称proxy对象)
reactive定义响应式数据是深层次的
内部给予ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作。

计算属性computed 与Vue2 中的类似

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-08 11:26:42
 * @LastEditors: 莲白
-->
<template>
  <ul>
    <li>
      姓:<input type="text" v-model="person.firstName">
      <br>
      名:<input type="text" v-model="person.lastName">
      <br>
      <span>{{person.fullName}}</span>
      </li>
  </ul>
</template>

<script>
import { reactive,computed} from 'vue' //1.引入ref 方法
export default {
  name: "App",
  setup() {
let person=reactive({
  firstName:'张',
  lastName:'三'
})

//计算属性-完整写法 (考虑读和写)
 person.fullName=computed({
  get(){
    return person.firstName+'-'+person.lastName 
  },
  set(value){
    const nameArr=value.split('-')
    person.firstName=nameArr[0];
    person.firstName=nameArr[1];
  }
})
    return {
      person,
    };
  },
};
</script>

侦听器watch(与Vue2.x中的watch配置功能一致)

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-08 16:54:21
 * @LastEditors: 莲白
-->
<template>
<h2> 当前求和为:{{sum}}</h2>
<button @click="sum++"> 点击加1</button>
<h2>当前的信息为:{{msg}}</h2>
<button @click="msg+='!'"> 点击加1</button>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<button @click="person.name+='@'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</template>

<script>
import { ref, watch,reactive} from 'vue' //1.引入ref 方法
export default {
  name: "App",
  setup() {
let sum =ref(0)
let msg =ref('你好')
let person =reactive({
  name:`莲白`,
  age:18,
  job:{
    js:{}
  }

})
// 情况1监视
// watch(sum,(newValue,oldValue)=>{
//   console.log(newValue,oldValue);
// })
//情况2监视多个响应式数据
// watch([sum ,msg],(newValue,oldValue)=>{
//   console.log(`sum ,msg`,newValue,oldValue);
// },{immediate:true,})
//监视reactive 所定义的一个响应式数据,注意:
/**
 * 此处无法正确的获取oldValue
 * 2.注意,强制开启了深度监视(deep配置无效)
 */
watch(person,(newValue,oldValue)=>{
  console.log(`person`,newValue,oldValue);
},{deep:false}) //此处配置无效
/**
 * 监视reactive 所定义的一个响应式数据,某个属性
 */
// watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
//   console.log(`person`,newValue,oldValue);
// },) //此处配置无效
/**
 * 特殊监视
 */
watch([()=>person.job,],(newValue,oldValue)=>{
  console.log(`person`,newValue,oldValue);
},{deep:true}) //此处由于监视的是reactive定义的对象中的某个属性,所以deep 属性仍然有效
    return {
      sum,
      msg,
      person
    };
  },
};
</script>

两个小坑:
1,监视reactive定义的响应式数据时,pldValue无法正确获取,强制开启了深度监视(deep配置失效).
2.监视reactive定义的响应式数据中某个属性时,deep配置任然有效

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-08 17:09:45
 * @LastEditors: 莲白
-->
<template>
<h2> 当前求和为:{{sum}}</h2>
<button @click="sum++"> 点击加1</button>
<h2>当前的信息为:{{msg}}</h2>
<button @click="msg+='!'"> 点击加1</button>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<button @click="person.name+='@'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</template>

<script>
import { ref, watch} from 'vue' //1.引入ref 方法
export default {
  name: "App",
  setup() {
let sum =ref(0)
let msg =ref('你好')
let person =ref({
  name:`莲白`,
  age:18,
  job:{
    js:{}
  }
})
console.log(`sum`,sum );
console.log(`msg`,msg );
console.log(`person`,person );
watch(sum,(newValue,oldValue)=>{
  console.log(`newValue`, newValue,`oldValue`,oldValue);
},{immediate:true})
/**
 * ref 监视对象
 */
//方法1
// watch(person.value,(newValue,oldValue)=>{
//   console.log(`newValue1`, newValue,`oldValue1`,oldValue);
// },{immediate:true})
//方法2
watch(person,(newValue,oldValue)=>{
  console.log(`newValue2`, newValue,`oldValue2`,oldValue);
},{immediate:true},{deep:true})
    return {
      sum,
      msg,
      person
    };
  },
};
</script>

watchEffect 函数

watch的套路是:既要指明监视属性,也要指明监视的回调
watchEffect的套路是:不用监视那个属性,监视的回调中用到那个属性,就监视那个属性
watchEffect 有点像computed:
但computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值
而watchEffect 更注重的是过程(回调函数的函数题),所以不用写返回值

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-08 17:28:56
 * @LastEditors: 莲白
-->
<template>
<h2> 当前求和为:{{sum}}</h2>
<button @click="sum++"> 点击加1</button>
<h2>当前的信息为:{{msg}}</h2>
<button @click="msg+='!'"> 点击加1</button>
<h2>姓名:{{person.name}}</h2>
<h2>年龄:{{person.age}}</h2>
<button @click="person.name+='@'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</template>

<script>
import { ref, reactive,watchEffect} from 'vue' //1.引入ref 方法
export default {
  name: "App",
  setup() {
let sum =ref(0)
let msg =ref('你好')
let person =reactive({
  name:`莲白`,
  age:18,
  job:{
    js:{}
  }
})
console.log(`sum`,sum );
console.log(`msg`,msg );
console.log(`person`,person );

// watch(sum,(newValue,oldValue)=>{
//   console.log(`sum`,newValue,oldValue );
// },{immediate:true,deep:true})
watchEffect(()=>{
  const x1=sum.value
  const x2=person.name
   const x3=person.age
  console.log(`watchEffect所执行的回调`,x1,x2,x3);
})
    return {
      sum,
      msg,
      person
    };
  },
};
</script>

生命周期

在这里插入图片描述

自定义hook 函数

本质是一个函数,把Setup 函数中使用的Composition API 进行封装
类似与Vue2.x 中的minxin
自定义hook的优势,复用代码,让setup 中的逻辑更清楚易懂
步骤1: 创建usePoint.js 文件 代码如下:

/*
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-10-08 18:02:43
 * @LastEditTime: 2022-10-08 18:06:30
 * @LastEditors: 莲白
 */
import { reactive, onMounted,onBeforeUnmount } from "vue"; 
  export default  function (){
  //实现鼠标打点相关的数据
  let point = reactive({
    x: 0,
    y: 0,
  });
    //实现鼠标打点相关的方法
  function savePoint(event){
      point.x = event.pageX;
      point.y = event.pageX;
      console.log(event.pageX, event.pageY);

  }
      //实现鼠标打点相关的钩子周期
  onMounted(() => {
    window.addEventListener("click",savePoint);
  });
  onBeforeUnmount(()=>{
    window.removeEventListener("click",savePoint)
  })
  return  point
}

步骤二: 引入功能封装文件

import usePoint from './hooks//usePoint'

步骤三: 声明变量接收 抛出的函数 在setup 定义

  setup() {
    let sum = ref(0);
     let point=usePoint()
    return {
      sum,
      point
    };
  },

toRef

作用:创建一个ref 对象,其value 值指向灵台一个对象中的某个属性
语法:const name=toRef(person,‘name’)
应用:要将响应式对象中的某个属性单独提供给外部使用时.
扩展:toRefs 与toRef功能一致,但可以批量创建多个ref对象语法 toRefs(person)

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-09 09:42:02
 * @LastEditors: 莲白
-->
<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{job.j1.salary }} K</h2>
  <button @click="name += '~'">修改姓名</button>
  <button @click="age += 1">增长年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import { reactive,toRef, toRefs } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: `莲白`,
      age: 20,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    console.log(`toRef`, toRef(person,'name'));
    return {
      person,
      // name: toRef(person,'name'),
      // age:toRef(person,'age'),
      // salary:toRef(person.job.j1,'salary'),
      ...toRefs(person)
    };
  },
};
</script>

其他Composition API

shallowReactive与shallowRef

shallowReactive :只处理对象最外层属性的响应式(浅响应式)
shallowRef: 只处理基本数据类型的响应式,不进行对象的响应式处理
什么时候使用
如果有一个对象数据,结构比较深,但变化时只是外层属性变化===》shallowReactive
如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换===>shallowRef
ref 和shallowRef的区别:
ref 处理对象形式的数据
shallowRef 不去处理对象形式的数据

<!--
 * @Description: 
 * @Author: 莲白
 * @Date: 2022-09-25 11:27:41
 * @LastEditTime: 2022-10-09 10:10:00
 * @LastEditors: 莲白
-->
<template>
<h2>x的值:{{x.x}}</h2>
<button @click="x.x ++"> 增加x的值</button>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ job.j1.salary }} K</h2>
  <button @click="name += '~'">修改姓名</button>
  <button @click="age += 1">增长年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import { toRef, toRefs, shallowReactive, ref, } from "vue";
export default {
  name: "App",
  setup() {
    let person = shallowReactive({
      name: `莲白`,
      age: 20,
      job: {
        j1: {
          salary: 20,
        },
      },
    });
    //只考虑第一层数据的响应式
    let x = ref({
      y:0,
      x:0
    })
    console.log(`toRef`, toRef(person, "name"));
    return {
      person,
      ...toRefs(person),
      x,
    };
  },
};
</script>

readonly 与shallowReadonly

readonly:让一个响应式数据变为只读的(深只读)
shallowReadonly :让一个响应式数据变为只读的(浅只读)
应该场景:不希望数据被修改时

toRaw与markRaw

toRaw:作用:将一个由reactive生成的响应式对象转化为普通对象
使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新.
marRaw:
作用:标记一个对象, 使其永远不会再称为响应式对象
应用场景:
1.有些值不应该被设置为响应式的,例如复杂的第三方类库等
2.当渲染具有不可变数据元 的大列表时,跳过响应式转换可以提高性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值