vue3.0基础学习

vue3 中的setup

vue3中所有的属性、方法、生命周期等皆定义在setup函数中,可以说setup是vue3中组合api的入口函数

vue3中使用内置的api需要引入

import { ref } from 'vue'

ref

定义一个响应式的简单数据类型(Number,String)

// 模板

import { ref } from 'vue'
export defaule {
    name: 'App',
    setup() {
        let name = ref('张三') // 定义一个响应式的变量
    
    // 定义方法
    function changeName() {
      name.value = '李四' // ref包装后的值,访问必须通过 .value
    }
    // 在vue3中定义的变量,函数模板中使用setup函数必须返回
    return {
      name,
      changeName
    }
    }
}

reactive

定义一个复杂的响应式数据类型(Object,Array)

// 模板

import { reactive } from 'vue'
export defaule {
    name: 'App',
    setup() {
    // 定义一个响应式的person对象
        let person = reactive({
      name: '张三',
      age: 25
    }) 
    
    // 定义方法
    function changeName() {
      person.name = '李四' // reactive包装后的值,可以直接点属性名访问
    }
    // 在vue3中定义的变量,函数模板中使用setup函数必须返回
    return {
     person
    }
    }
}

备注:

ref:用来定义简单类型的响应式数据

reactive: 用来定义复杂的响应式数据,不管嵌套多深vue都可以监测到数据变化

如果用reactive定义简单的数据类型,该数据被改变时将不会触发页面更新,也就是说该数据不是响应式的

vue3 响应式原理

vue3内部借助了Proxy拦截对源对象属性的改变(增删改查)

通过Reflect(反射) 改变源对象的值

// 源对象
let person = {
    name: '张三',
    age: 18
}
// Proxy 接收两个参数,第一个是target代理的目标对象,第二个是实现增删改查的对象
let p = new Proxy(person, {
  // 读取属性值,target目标对象,propName是读取的该对象中属性名
    get(target, propName) {
    // return target[propName]
        return Reflect.get(target,propName)
    },
  // 修改和新增时会触发set方法
  set(target, propName, value) {
    // return target[propName] = value
    return Reflect.set(target, propName, value)
  },
  // 删除时触发
  deleteProperty(target, propName) {
    // return delete target[propName]
    return Reflect.deleteProperty(target, propName)
  }
})

setup函数注意点

1.setup执行的时机是在beforeCreate()之前

2. setup函数接收两个函数

// props,父组件传进来的参数
// context 上下文对象包含了,attrs/emit/slots
props: ['msg']// 子组件必须声明,否则会报警告
setup(props, context) {
  
}

vue3中的computed计算属性

import { reactive, computed } from 'vue'
export default {
  setup() {
    let person = reactive({
      firstName:'张',
      lastName: '三'
    })
    // 简写形式
    let fullName = computed(()=>{
      return person.firstName + person.lastName
    })
    // 完整写法
    let fullName = computed({
      get() {
        return person.firstName + person.lastName 
      },
      set(value) {
        person.firstName = value
        person.lastName  = value
      }
    })
    return {
      fullName
    }
  }
}

vue3中的watch函数

import { ref, watch, reactive } from "vue";
export default {
  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        address: "长沙",
        hobby: {
          number: "篮球"
        }
      }
    });
    // 以下是监听ref包装的简单数据
    // 情况一,简单监听, vue3中watch是一个函数
    // watch(sum, (newValue, oldValue) => {
    //   console.log(newValue, oldValue);
    // });

    // 情况二 vue3中watch监听多个值
    // watch([sum, msg], (newValue, oldValue) => {

    //   console.log(newValue, oldValue);//[0, "你好!"] [0, "你好"]
    // });

    //情况三, 开启监听的配置项
    // watch(sum, (newValue, oldValue) => {
    //   console.log(newValue, oldValue)
    // }, {
    //   immediate: true, // 监听的值没有改变页面已加载就触发一次
    //   deep: true // 开启深度监听
    // })
    /* 
      watch监听reactive响应式数据
      // 情况1 默认强制开始深度监听deep,无法改变。且监测不到oldValue
    */
    //  watch(person, (newValue, oldValue) => {
    //    console.log(newValue, oldValue)
    //  })
    /* 
      watch监听reactive响应式数据
      // 情况2 想要监听对象中某一个值,第一个参数必须是一个函数且要返回要监听的属性
    */
    // watch(
    //   () => person.name,
    //   (newValue, oldValue) => {
    //     console.log(newValue, oldValue)
    //   }
    // );
    /* 
      watch监听reactive响应式数据
      // 情况3 想要监听对象中某一个属性时,且该属性是又是一个对象,需要开启deep才能生效
    */
    watch(
      () => person.job,
      (newValue, oldValue) => {
        console.log(newValue, oldValue)
      },
      { deep: true }
    );
    return {
      sum,
      msg,
      person
    };
  }
}
  

vue3中的watchEffect函数

  1. 该函数也用于监听,和watch不同的是,该函数参数只有一个回调函数,监听的对象取决于回调函数中所用到的有哪些属性

  2. 该函数和computed属性有些类似,不同点在于computed属性必须有返回值,注重的是返回的结果。watchEffect函数没有返回值,注重的是函数执行时的逻辑过程。

import { reactive,watchEffect } from "vue";
export default {
  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        address: "长沙",
        hobby: {
          number: "篮球"
        }
      }
    });
    // 只有一个参数回调函数,监听取决于回调函数中用到的属性。sum和hobby改变会被监听到
    watchEffect(() =>{
      const x1 = sum.value
      const x2 = person.job.hobby.number
    })
    return {
      person
    };
  }
}
  

vue3 生命周期

和vue2相比vue3生命周期函数有两个改变

1. beforeDestroy >>> beforeUnmount // 卸载之前

2. destroyed >>> unmounted // 卸载之后

组合API中使用生命周期函数

import {  onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from "vue";
export default {
  setup() {
   onBeforeMount(()=>{
    console.log("挂在之前")
   })
   onMounted(()=>{
    console.log("挂在之后")
   })
  }
}

备注:

  1. 在setup函数中使用钩子函数,名称有所改变如上所示。
  2. 之前的配置项写法生命周期依然可用,两种写法同时存在时,组合API中的写法优先级高!但不建议两种写法同时存在!
  3. 组合API中beforeCreate、created => setup()

vue3中的toRef/toRefs

作用:把一个对象或者属性转变为ref响应式数据

语法:toRef(person,'name')

toRefs,批量转换,同时把多个转换为ref类型

语法:toRefs(person),转换后为一个对象,使用时通过 ...toRefs(person)展开

vue3中的shallowReactive/shallowRef

shallowReactive: 定义复杂数据对象时,只有第一层数据是响应式的,里面嵌套的数据改变不会响应。

shallowRef: 定义数字类型数据是响应式的,定义对象数据类型时,不是响应式的,数据改变但页面不会响应。

vue3 中的readonly/shallowReadonly

let person = reactive({
  name: '张三'
  hobby: {
    sports:'篮球'
    }
})

const person1 = readonly(person)
return { person1 }

作用: 把一个响应式的数据变为只读(不可修改)

场景:当一个数据是外部引入的,多个地方要用,但在某个地方只能读不能改时。

provide/inject

作用:用于祖组件和后代组件传递数据

// 祖组件传值
import { provide, reactive} form 'vue'
export default {
    setup() {
        let car = reactive({name:'宝马',price:'40W'})
    provide('car',car) // 传递
  }
}
// 后代组件接收
import { inject } form 'vue'
export default {
    setup() {
        let car = inject('car')
    return {car}
  }
}

备注: provide传递的数据是响应式的数据

teleport

作用:vue3内置组件,可以用来包括一组标签,通过to=“#app”属性,把包括的标签脱离原来的文本流显示在对应位置


你可能感兴趣的:(vue3.0基础学习)