【学习 vite + vue3 + pinia + ts】应用创建与常用组合api

一、应用创建

2.x

import Vue from 'vue'

import App from './App.vue'

new Vue({

        render: h => h(App)

}).$mount('#app') 

3.x

import { createApp } from 'vue'

import App from './App.vue'

createApp(App).mount('#app')

基于脚手架创建的项目,mian.js中已经创建好应用了,此处了解即可。

二、组合式 API 

除了setup,其余api若用到,需要手动引入

import { ref, reactive, watch, watchEffect, computed, provide, inject,

setup

Vue3.0中一个新的配置项,值为一个函数,是所有组合api放置的容器,组件中所用到的数据、方法等,均要配置在setup中。

参数

props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

context:上下文对象

    - attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs,使用attrs.xxx

    - slots: 收到的插槽内容, 相当于this.$slots,使用slots.xxx

    - emit: 分发自定义事件的函数, 相当于this.$emit

    - expose: 暴露公共属性(函数),当父组件通过模板引用访问该组件的实例时,将仅能访问 expose 函数暴露出的内容

setup(props, { attrs, slots, emit, expose }) {  ...   }

返回值

1.对象。若返回值是一个对象,对象中所有属性、方法,在<template>模板中可以直接使用。

setup(){

        const  msg = '你好'

        return { msg }

}

2.渲染函数。若返回一个渲染函数,则组件渲染内容会是返回值,不再渲染<template>中编写内容

setup(){

        return () => return h('div', '你好啊') //h函数需要引入 import { h } from 'vue'

}

注意

1.尽量不要与Vue2.x配置混用

      - Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。

      - 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。

      - 如果有重名, setup优先。

2.setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

3.setup执行的时机:在beforeCreate之前执行一次,this是undefined

生命周期钩子

组合api中生命周期钩子与vue3中声明周期对比 

 ​​​​​​​

ref 

作用: 定义一个响应式的数据(RefImpl: reference implement 引用实现的实例对象,简称ref对象)

语法: const xxx = ref(initValue)

  - JS中操作数据: xxx.value

  - 模板中读取数据: 不需要.value,直接:<div>{ {xxx}}</div>

备注

  - 接收的数据可以是:基本类型、也可以是对象类型

  - 基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的。

  - 对象类型的数据:内部 求助了Vue3.0中的一个新函数——reactive函数。

reactive

作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)

语法:const 代理对象= reactive(源对象)

- 接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)

- reactive定义的响应式数据是“深层次的”。

- 内部基于 ES6 的 Proxy 实现,通过代理对象Reflect操作源对象内部数据进行操作。

computed 

与2.x中类似,每一个计算属性,都是computed函数的返回值,用法如下:

import { computed } from 'vue'

setup(){

    //简写方式

    let fullName = computed(() => { return p.firstName+'-'+p.lastName }) //函数

    //完整方式

    let fullName = computed({  //对象

        get(){ return p.firstName+'-'+p.lastName },

        set(value){ 

              const nameArr = value.split('-')

              person.firstName = nameArr[0]

              person.lastName = nameArr[1]

        }

}

watch 

情况一:监视ref定义的响应式数据

watch(sum, (newValue,oldValue)=>{

  console.log('sum变化了',newValue,oldValue)

},{immediate:true})

情况二:监视多个ref定义的响应式数据 

watch([sum, msg], (newValue,oldValue)=>{

  console.log('sum或msg变化了',newValue,oldValue)

})

情况三:监视reactive定义的响应式数据

- 无法正确获得oldValue

- 强制开启了深度监视

watch(person, (newValue, oldValue)=>{

    console.log('person变化了',newValue,oldValue)

},{immediate:true,deep:false}) //此处的deep配置不再奏效

 情况四:监视reactive定义的响应式数据中的某个属性

- 此时 deep配置有效

- 此时 能正确获取oldValue的值

watch(()=>person.job, (newValue,oldValue)=>{

  console.log('person的job变化了',newValue,oldValue)

},{immediate:true,deep:true})

情况五:监视reactive定义的响应式数据中的某些属性 

watch([()=>person.job, ()=>person.name], (newValue,oldValue)=>{

  console.log('person的job变化了',newValue,oldValue)

},{immediate:true,deep:true})

注意

1.若监视的是reactive对象中的某个属性,而这个属性恰好是个对象,此时需要配置{ deep: true }

2.监视ref定义的基本类型时,不需要.value, 直接watch(变量名, ()=>{})即可

   监视ref定义的对象类型时,需要.value,watch(变量名.value, ()=>{}) 或者 配置 { deep: true }

watchEffect 

watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调,默认开启了immediate

watchEffect(()=>{

    const x1 = sum.value

    const x2 = person.age

    console.log('watchEffect配置的回调执行了')

})

- watch的套路是:既要指明监视的属性,也要指明监视的回调。

- watchEffect的套路是:不指明监视哪个属性,监视的回调中用到哪个属性,就监视哪个属性。

- watchEffect有点像computed:

    - 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

    - 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

toRef 与 toRefs

创建一个ref对象,其value值指向另一个对象中的某个属性。

const person = reactive({

        name: `tom',

        job: {

                salary: 2000,

        }

})

在模板中用到salary时,要 person.job.salary , 可以通过toRef设置,在模板中直接使用salary

toRef 一次只能处理一个对象中的一个属性 

const salary = toRef(person.job, `salary`)  // 此时 salary 与 person.job.salary会同步

salary.value ++

toRefs 可以批量处理一个对象中的所有属性,将对象中所有属性都变成ref对象,此时支持结构赋值的写法

const p = toRefs(person)

const { name, job } = p //此时 name,job都是ref对象,与 state中属性值同步,不丢失响应性

name.value = `jerry`

job.value.salary ++

shallowRef 与 shallowReactive

 shallowRef: 只处理基本类型的响应式,不进行对象的响应式处理,用于不会修改对象属性,而是生成新的对象来替换的情况

shallowReactive: 只处理对象最外层属性的响应式(浅响应式),用于对象结构比较深,但变化时只是外层属性变化的情况

readonly 与 shallowReadonly

readonly: 让一个响应式数据变为只读的(深层次)

shallowReadonly:  让一个响应式数据变为只读的(浅层次)

不希望数据被修改时使用

toRaw 与 markRaw 

toRaw:

- 将一个由 reactive 定义的响应式数据,转换为普通对象

- 用于读取响应式对象的普通对象,对这个对象的所有操作,不会引起页面更新

markRaw

- 标记一个对象,使其永远不会再变成响应式对象

- 用于不应被设置为响应式的值,eg:第三方类库

- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

setup(){

        const person = reactive{

                name: `tom`

        } // 此时person是响应式的,再添加不存在的属性也会变成响应式

        function addCar(){

                ... //获取car信息,用于展示,car中数据不会响应式变化

                let car = { name: `ben`, price: `40w` }

                person.car = markRaw(carInfo)

        }

}

customRef 

用于创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制 

实现 防抖效果

<script setup lang="ts">
  import { customRef } from 'vue'

  //自定义一个ref-名为myRef
  function myRef (value, delay = 2000) {
    let timeout
    return customRef((track, trigger)=>{
      return {
        get () {
          track()
          return value
        },
        set (newValue) {
          clearTimeout(timeout)
          timeout = setTimeout(() => {
            value = newValue
            trigger()
          }, delay)
        }
      }
    })
  }

  let inputValue = myRef(`hello`)
</script>

provide 与 inject

用于祖孙组件间通讯。父组件用provide选项提供数据,子组件用inject选项使用数据

 父

setup(){

        provide(propName, propValue)

setup(){

        let variable = inject(propName) // variable是响应式的

响应式数据的判断

isRef: 检查一个值是否是ref对象

isReactive: 检查一个对象是否是由 reactive 创建的响应式代理

isReadonly: 检查一个对象是否是由 readonly 创建的只读代理

isProxy: 检查一个对象是否是由 reactive 或 readonly 或 shallowReactive 或 shallowReadonly 创建的代理


更多详细介绍,请查看官方文档:

组合式 API:setup() | Vue.js

猜你喜欢

转载自blog.csdn.net/weixin_59128282/article/details/126423737