Vue 3 CompositionAPI

目录

一. reactive

1. 非响应式数据

1.1 数据不是响应式的,可以修改,但是不显示修改的数据

2. reactive API 定义响应式数据

2.1 reactive 只能用于对象或者数组这样的复杂类型数据(不可以为 String、Number、Boolean)

二. ref

1. ref 的使用

1.1 默认情况下,在template 中使用ref 时,vue 会自动对其进行解包(取出其中的value)

2. ref 的浅层解包

2.1 直接的ref 可以进行解包

2.2 对象包裹的ref 的浅层解包

 3. reactive 的深度监听

3.1 默认reactive 和 readonly 都是深度监听的

三. reactive 和 ref 的使用场景

1. reactive 更多的用于对象和数组,用于本地定义的数据

2. ref 更多的用于基本数据类型,用于请求的数据

四. 父子间的通信

1. 父传子

2. 子传父

五. readonly

1. 可传的参数

2. readonly 的本质

3. 使用

 4. readonly 的深度监听

4.1 默认reactive 和 readonly 都是深度监听的

六. isProxy

七. isReactive

八. isReadonly

九. toRaw

十. shallowReactive

十一. shallowReadonly

十二. toRefs 和 toRef

1. 响应式对象在解构之后,其结构出来的值不具有响应式

2. toRefs 解构reactive 对象的多个属性

2.1 解构完成之后仍然具有响应式,可以将reactive 返回的对象中的属性转为ref

3. toRef 解构reactive 对象的一个属性

3.1 解构完成之后仍然具有响应式,可以将reactive 返回的对象中的属性转为ref

十三. unref

十四. isRef

十五. shallowRef

十六. triggerRef

十七. computed

1. reactive

2. ref

3. 对象写法

十八. ref 获取元素和组件

1. ref 获取元素

2. ref 获取组件

3. 使用 ref 在父组件中调用子组件的方法

十九. 生命周期

1. beforeCreate 和 created 被setup 替代

二十. provide 和inject

二十一. watch 侦听器

1. 监听基本数据类型

1.1监听一个数据

1.2 监听多个数据

2. 监听引用数据类型

2.1 监听被proxy 代理的对象

2.2 监听原始对象本身 (通过解构拿到原始对象本身)

二十二. watchEffect

1. 特点

2. 是否有依赖、监听多个依赖、停止监听

2.1 没有依赖(也会立即执行一次)

2.2 有依赖时,自动监听

2.3 可以监听多个依赖,只要有一个依赖变化,就会执行回调函数

2.4 停止侦听

二十三.

1. 定义props

2. 绑定函数, 并发出事件

附:

1. 浏览器插件

1.1 vue devtool


一. reactive

1. 非响应式数据

1.1 数据不是响应式的,可以修改,但是不显示修改的数据

setup() {
    let message = "Hello"
    function changeMessage() {
        // 数据不是响应式的
        // 可以修改,但是不显示修改的数据
        message = "World";    
    }
    return {
        message,
        changeMessage
    }
}

2. reactive API 定义响应式数据

2.1 reactive 只能用于对象或者数组这样的复杂类型数据(不可以为 String、Number、Boolean)

<div> {{ account.name }} - {{ account.age }} </div>
import { reactive } from 'vue'

setup() {
    const account = reactive({
        name: "why",
        age: 18
    })
    function changeAccount() {
        account.name = "coder";
    }
    return {
        account,
        changeAccount
    }
}

二. ref

1. ref 的使用

1.1 默认情况下,在template 中使用ref 时,vue 会自动对其进行解包(取出其中的value)

<template> {{ counter }} </template>
setup() {
    const counter = ref(0);
    function increment() {
        counter.value++
    }
    return {
        counter,
        increment
    }
}

2. ref 的浅层解包

2.1 直接的ref 可以进行解包

<div>{{ counter }}</div>
<button @click="counter++"></button>

setup() {
    const counter = ref(0);
    return {
        counter
    }
}

2.2 对象包裹的ref 的浅层解包

// 只显示时,可以自动解包(对象中的ref)
<div>{{ info.counter }}</div>
// 需要对值进行操作时,不能自动解包(对象中的ref)
<button @click="info.counter.value++">+1</button>

setup() {
    counst counter = ref(0);
    const info = {
        counter
    }
    return {
        info
    }
}

 3. reactive 的深度监听

3.1 默认reactive 和 readonly 都是深度监听的

// 当info.friend.name 修改时,也会响应式监听
const info = reactive({
    name: "why",
    friend: {
        name: "kobe"
    }
})

三. reactive 和 ref 的使用场景

1. reactive 更多的用于对象和数组,用于本地定义的数据

const account = reactive({
    username: "why",
    password: "coder"    
})

2. ref 更多的用于基本数据类型,用于请求的数据

const music = ref([]);
onMounted(() => {
    const serverMusic = ["a", "b"];
    music.value = serverMusic;
})

四. 父子间的通信

1. 父传子

// 父组件
<show-info :info = "info"></show-info>

// 子组件
props: {
    info: {
        type: Object,
        default: () => ({})
    }
}

2. 子传父

emits: ["changeInfoName"]
setup(props, context) {
    function changeInfobtnClick() {
        context.emit("changeInfoName", "kobe")
    }
    return {
        changeInfobtnClick
    }
}

五. readonly

1. 可传的参数

  1. 普通对象
  2. reactive 返回的对象
  3. ref 的对象

2. readonly 的本质

readonly 返回的对象的setter 方法被劫持了

3. 使用

  • 父传子时,可以将roInfo(readonly) 传给子组件
  • 子组件无法修改roInfo
  • 可以通过emit 事件修改父组件的info 值
  • 进而修改roInfo
const info = reactive({
    name: "why"
})
const roInfo = readonly(info)

 4. readonly 的深度监听

4.1 默认reactive 和 readonly 都是深度监听的

// 当info.friend.name 修改时,也会响应式监听
const info = reactive({
    name: "why",
    friend: {
        name: "kobe"
    }
})

六. isProxy

检查对象是否是由reactive 或 readonly 创建的proxy

七. isReactive

检查对象是否是由reactive 创建的响应式代理,如果该代理是由readonly 创建的,但包裹了由reactive 创建的另一个代理,它也会返回true

// 1.
const info = reactive({
    name: "why"
})

isReactive(info)   // true


// 2.
const obj = readonly({
    name: "kobe"
})

isReactive(obj)    // false

// 3.
const roInfo = readonly(info)
isReactive(roInfo)    // true

八. isReadonly

检查对象是否是由readonly 创建的只读代理

九. toRaw

返回reactive 或 readonly 代理的原始对象

const info = Proxy({})

import { toRaw } from 'vue'

toRaw(info)

十. shallowReactive

创建一个响应式代理,它跟踪其自身property 的响应性,但不执行嵌套对象的深层响应式转换(深层还是原生对象)

reactive 创建的是深层的响应式对象

十一. shallowReadonly

创建一个proxy,使其自身的property 为只读,但不执行嵌套对象的深度只读转换(深层还是可读、可写的)

十二. toRefs 和 toRef

1. 响应式对象在解构之后,其结构出来的值不具有响应式

const info = reactive({
    name: "why",
    age: 18
})
const { name, age } = info

// name 和 age 是reactive 对象解构后的值
// 失去了响应式

2. toRefs 解构reactive 对象的多个属性

2.1 解构完成之后仍然具有响应式,可以将reactive 返回的对象中的属性转为ref

const info reactive({
    name: "why",
    age: 18
})

const { name, age } = toRefs( info )

3. toRef 解构reactive 对象的一个属性

3.1 解构完成之后仍然具有响应式,可以将reactive 返回的对象中的属性转为ref

const info reactive({
    name: "why",
    age: 18
})

const name = toRef( info, "name" );

十三. unref

  • 如果我们想要获取一个ref 引用中的value, 那么也可以通过unref 方法:
  • 如果参数是一个ref ,则返回内部值,否则返回参数本身
  • 这是 val = isRef( val ) ? val.value : val 的值语法糖函数

十四. isRef

判断是否是一个ref 对象

十五. shallowRef

创建一个浅层的ref 对象

const info = shallowRef({
    name: "why"
})


info.value.name = "kobe" 

十六. triggerRef

手动触发和shallowRef 相关联的副作用

const info = shallowRef({ name: "why" });

// 下面的修改不是响应式的
const changeInfo = () => {
    info.value.name = "coderwhy"
    // 手动触发
    triggerRef(info)
}

十七. computed

1. reactive

import { computed } from 'vue'

const names = reactive({
    firstName = "kobe",
    lastName = "bryant" 
})

const fullName = computed(() => {
    return names.firstName + names.lastName
})

2. ref

import { computed } from 'vue'

const score = ref(80)
const scoreLevel = computed(() => {
    return score.value >= 60 ? 及格 : 不及格
})

3. 对象写法

import { computed } from 'vue'
const fullName = computed({
    set: function(newValue) {
        const tempNames = newValue.split(" ")
        names.firstName = tempNames[0]
        names.lastName = tempNames[1]
    },
    get: function() {
        return names.firstName + lastName
    }
})

十八. ref 获取元素和组件

1. ref 获取元素

<h2 ref="titleRef"></h2>

setup() {
    const titleRef = ref(null)
    onMounted(() => {
        console.log(titleRef.value)
    })
} 

2. ref 获取组件

<show-info ref="showInfoRef"/>

const showInfoRef = ref(null)

3. 使用 ref 在父组件中调用子组件的方法

<show-info ref="showInfoRef"/>

const showInfoRef = ref(null)

showInfoRef.value.showInfoFoo()

十九. 生命周期

1. beforeCreate 和 created 被setup 替代

( setup 函数即表示beforeCreate 和 created )

v2.                    v3.

beforeCreate           无
created                无
beforeMount        onBeforeMount
mounted            onBeforeMount
beforeUpdate       onBeforeUpdate   
updated            onUpdated
beforeUnmount      onBeforeUnmount
unMounted          onUnmounted

activated          onActivated
deactivated        onDeactivated

二十. provide 和inject

// 父组件

import { provide } from 'vue'
setup(){

    const counter = ref(100)
    const info = reactive({
        name: "why",
        age: 18
    })
    
    provide("counter", counter)
    provide("info", info)
}


// 子组件
import { inject } from 'vue'
setup() {
    // (key, default)
    const name = inject("name", coder)
}

二十一. watch 侦听器

1. 监听基本数据类型

1.1监听一个数据

const name = ref("why")

watch(name, (newValue, oldValue) => {})

1.2 监听多个数据

const name = ref("why")
const age = ref(18)

watch([name,age], (newValue, oldValue) => {})

2. 监听引用数据类型

2.1 监听被proxy 代理的对象

const info = reactive({
    name: "why",
    friend: { 
        name: "coder"
    }
})

watch(info, (newValue, oldValue) => {
    {
        immediate: true,
        deep: true
    }
}

2.2 监听原始对象本身 (通过解构拿到原始对象本身)

watch(() => (
    {...info}), 
    (newValue, oldValue) => {},
    {
        immediate: true,
        deep: true
    }
)

二十二. watchEffect

1. 特点

  1. 会立即执行一次, 不管是否有依赖
  2. 会自动收集依赖

2. 是否有依赖、监听多个依赖、停止监听

2.1 没有依赖(也会立即执行一次)

import { watchEffect } from 'vue'

setup() {
    
    watchEffect(() => {
        console.log("abc")
    })
}

2.2 有依赖时,自动监听

import { watchEffect } from 'vue'

setup() {
    const counter = ref(0)
    
    watchEffect(() => {
        console.log(counter.value)
    })
}

2.3 可以监听多个依赖,只要有一个依赖变化,就会执行回调函数

import { watchEffect } from 'vue'

setup() {
    const counter = ref(0)
    const name = ref("why")
    watchEffect(() => {
        console.log(counter.value, name.value)
    })
}

2.4 停止侦听

import { watchEffect } from 'vue'

setup() {
    const counter = ref(0)
    
    const stopWatch = watchEffect(() => {
        console.log(counter.value)
    })

    if( counter.value > 10 ) {
        stopWatch()
    }
}

二十三. <script setup>

1. 定义props

<script setup>
    // 定义props 
    const props = defineProps({
        name: {
            type: String,
            default: "默认值"
        },
        age : {
            type: Number,
            default: 0
        } 
    })
</script>

2. 绑定函数, 并发出事件

<script setup>
    const emits = defineEmits(["infoBtnClick"])
    function showInfoBtnClick() {
        // (事件名, 传递的参数)
        emits("infoBtnClick", "发生了点击")    
    }
</script>

3. defineExpose()

使用<script setup>  的组件是默认关闭的

通过模板ref 或者$parent 链获取到组件的公开实例,不会暴露任何在<script setup>中声明的绑定

通过defineExpose 编译器宏来显式指定在<script setup> 组件中要暴露出去的property

function foo() {
    console.log("foo")
}

defineExpose({
    foo
})
const showInfoRef = ref(null)
function callShowInfo() {
    showInfoRef.value.foo()
}


附:

1. 浏览器插件

1.1 vue devtool

yarn install

yarn build

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值