vue3常用的api

本文详细介绍了Vue3中的Composition API,包括setup、reactive、ref、toRef、toRefs、shallowReactive、shallowRef、toRaw、markRaw、provide&inject、watch&watchEffect、computed、useStore、useRouter、getCurrentInstance以及元素ref属性的使用,重点讨论了它们在响应式数据处理和组件间通信中的作用。

vue3使用Composition API,相比于vue2的Options API而言,我们可以按需引入需要使用到的api,而不必引入所有api,从而提高了项目打包构建的速度,减少了项目打包后的体积

1. setup

setup函数是composotion api的入口函数,我们的变量,方法,函数等都是在该函数里定义的

<template>
  <div id="app">
      <p>{{count}}</p>
      <button @click="add">+</button>
  </div>
</template>

<script>
import {ref} from 'vue'    //  引入ref函数
export default {
  name: 'App',
  setup() {
      let count = ref(0)    //  用ref包装一个响应式变量
      const add = () => {
          count.value ++    //  被ref包装的变量取值使用.value
      }
      return {count, add}   //  将count和add返回出去,供template使用
  }
}
</script>

2. reactive

reactive方法是用来创建一个响应式的数据对象,该api很好的解决了vue2通过defineProperty实现数据响应式的缺陷(无法实现新增属性的响应式,无法实现删除属性的响应式,无法实现懒监听...)

<template>
  <div id="app">
    {{ data.count }}
  </div>
</template>

<script>
import {reactive} from 'vue'    //  从vue3中引入reactive 
export default {
  name: 'App',
  setup() {
      const data = reactive({count: 0})    //  创建响应式的数据对象
      return {data}    //  将响应式数据对象return出去,供template使用
  }
}
</script>

3. ref 

ref底层通过reactive包装了一个对象,然后将值传递给该对象的value属性,可以将ref(prop)理解为reactive({value: prop}),所以访问ref所包装的对象时需要加上.value

<script>
import {ref, reactive} from 'vue'
export default {
  name: 'App',
  setup() {
      const data = {count: 0}
      const data1 = ref(obj)
      const data2 = reactive(obj)
      let data3 = ref(0)
  }
}
</script>

当我们的响应式数据是基本类型或者单值对象时可以使用ref,而为引用类型时使用reactive

4. toRef 

toRef是将某个对象中的某个值转化为响应式数据,接受两个参数,第一个参数为obj对象,第二个参数为对象的属性名

<script>
import {toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 0}
        const data = toRef(obj, 'count')
        return {data}
    }
}
</script>

ref跟toRef的区别:

1. ref是对传入数据的拷贝,toRef是对传入数据的引用

2. ref值改变会更新视图,toRef值改变不会更新视图 

5. toRefs

toRefs的作用就是将传入对象所有的属性的值都转化为响应式数据对象,该函数只有一个参数,就是obj对象

<script>
import {toRefs} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 'toRefs'
        }
        const data = toRefs(obj)
        console.log(data)
        return {...toRefs(obj)}
    }
}
</script>

6. shallowReactive

浅层次的reactive,reactive为深层次的,会为对象的每一层属性都使用proxy添加响应式,而shallowReactive只对对象的第一层属性添加响应式,可以进行性能优化

<script>
import {reactive, shallowReactive} from 'vue'
export default {
    setup() {
        const obj1 = {
            propA: 0,
            propB: {
                propC: 1
            }
        }
        const obj2 = {
            propA: 0,
            propB: {
                propC: 1
            }
        }
        const data1 = reactive(obj1)           // obj1.propB.propC为响应式
        const data2 = shallowReactive(obj2)    // obj2.propB.propC不是响应式
    }
}
</script>

7. shallowRef

浅层次的ref,可以类比shallowReactive,这里不做多解释

8. toRaw

toRaw用于获取ref或reactive对象的原始数据

<template>
    <p>{{ data.propA }}</p>
    <p>{{ data.propB }}</p>
    <button @click="change">change</button>
</template>

<script>
import {reactive,toRaw} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 0
        }
        const data = reactive(obj)
        const rawData = toRaw(data)
        const change = () => {
            data.propB ++ 
            console.log(obj)     //  打印原始数据obj
            console.log(data)    //  打印 reactive对象
        }
        console.log(obj === rwaData)    //  true
        return {data, change}
    }
}
</script>

9. markRaw

markRaw可以将原始数据标记为非响应式数据,即便使用ref或者reactive包装后仍然无法实现响应式,接收一个参数,即原始数据,并返回被标记后的数据

<template>
    <p>{{ data.propA }}</p>
    <p>{{ data.propB }}</p>
    <button @click="change">change</button>
</template>

<script>
import {reactive, markRaw} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 0
        }
        // 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
        const rawData = markRaw(obj)
        // 试图用reactive包装raw, 使其变成响应式数据
        const data = reactive(rawData ) 
        const change = () => {
            data.propB ++     // 值被修改但视图不会更新
        }
        return {data, change}
    }
}
</script>

10. provide&inject

与vue2中的provide&inject的作用是一样的,在vue3中需要手动引入

provide:向子组件以及子孙组件传递数据,接收两个参数,第一个参数是key,即数据名,第二个参数为value,即数据值

inject:接收父组件或祖先组件传递过来的数据,接收一个参数key,父组件或祖先组件传递的数据名

// C是B的子组件,B是A的子组件
// A.vue
<script>
import {provide} from 'vue'
export default {
    setup() {
        const data = {
            prop: 'vue3'
        }
        // 向子组件以及子孙组件传递名为data的数据
        provide('data', data)
    }
}
</script>

// B.vue
<script>
import {inject} from 'vue'
export default {
    setup() {   
        // 接收A.vue传递过来的数据
        inject('data')  // {prop: 'vue3'}
    }
}
</script>

// C.vue
<script>
import {inject} from 'vue'
export default {
    setup() {   
        // 接收A.vue传递过来的数据
        inject('data')  // {prop: 'vue3'}
    }
}
</script>

11. watch&watchEffect 

用来监视某项数据变化从而执行指定的操作

1. watch(source, cb, [options]):

source:可以是表达式或函数,用于指定监听的依赖对象

cb: 依赖对象变化后执行的回调函数

options: 可选参数,可以配置的属性有immediate(立即触发回调函数),deep(深度监听)

watch方法会返回一个stop方法,如果需要停止监听,可以直接执行stop方法

<script>
import {ref, reactive, watch} from 'vue'
export default {
    setup() {
        // 监听ref  
        const data1 = ref(0)
        watch(data1, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`, `新值为${newValue}`)
            // 1秒后打印结果:原值为0,新值为1
        })
        setTimeout(() => {
            data1.value ++
        }, 1000)
        
        // 监听reactive 
        const data2 = reactive({prop: 0})
        watch(() => data2.prop, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`, `新值为${newValue})
            // 1秒后打印结果:原值为0,新值为1
        })
        setTimeout(() => {
            data2.prop ++
        }, 1000)

        // 监听多个数据
        const data3 = reactive({ propA: 0, propB: 'vue3' })
        watch(
            [() => data3.propA, () => data3.propB], 
            ([newPropA, newPropB], [oldPropA, oldPropB]) => {
                console.log(oldPropA, newPropA, oldPropB, newPropB)
                // 1秒后打印结果:0, 1, vue3, hello vue3
            }
        )
        setTimeout(() => {
          data3.propA ++
          data3.propB = 'hello vue3'
        }, 1000)
    }
}
</script>

2. watchEffect

watchEffect跟watch不同,它不需要手动传入依赖,每次初始化的时候就会执行一次回调函数来自动获取到依赖,无法获取到原始值,只能获取改变后的值

<script>
import {reactive, watchEffect} from 'vue'
export default {
    setup() {   
        const data = reactive({propA: 0, propB: 'vue3'})
        watchEffect(() => {
            console.log(data.propA, data.propB)
            console.log(state.name)
            // 初始化打印:0 vue3
            // 一秒后打印:1 hello vue3
        })
        setTimeout(() => {
          data.propA ++
          data.propB = 'hello vue3'
        }, 1000)
    }
}
</script>

12. computed

<template>
  <div>
    <p><input type="text" v-model="propA"></p>
    <p><input type="text" v-model="propB"></p>
  </div>
</template>

<script>
import { computed, ref } from 'vue'
export default {
  setup() {
    const propA = ref(0)
    const propB = computed(() => {
      return propA.value + 1
    })
    return { 
      propA,
      propB
    }
  }
}

13. useStore

vue3中使用vuex的方式跟vue2不一样,需要使用vuex中的useStore方法

import Vuex from 'vuex'

const store = Vuex.createStore({
    state: {
        propA: 'vue3'
    },
    mutations: {
        ……
    }
})

<script>
import {useStore} from 'vuex'
export default {
    setup() {   
        const store = useStore()
        console.log(store)
    }
}
</script>

14. useRouter

vue3中使用路由的方式跟vue2不一样,需要使用router中的useRouter方法

<script>
import {useRouter} from 'vue-router'
export default {
    setup() {   
        const router = useRouter()
        router.push({
            path: `/`
        })
    }
}
</script>

15. getCurrentInstance

vue3中获取实例的方式跟vue2不一样,需要使用getCurrentInstance方法

<template>
    <p></p>
</template>
<script>
import {getCurrentInstance} from 'vue'
export default {
    setup() {   
        const instance = getCurrentInstance()
        console.log(instance)
        return {}
    }
}
</script>

16. 元素ref属性

元素ref属性可以获取到标签的元素或组件

<template>
  <div>
    <div ref="el">div元素</div>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
export default {
  setup() {
      // 创建一个DOM引用,名称必须与元素的ref属性名相同
      const el = ref(null)
      // 在挂载后才能通过 el 获取到目标元素
      onMounted(() => {
          console.log(el.value)
      })
      return {el}
  }
}
</script>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值