Vue3最新的14个常用API

(1)setup

(2)ref

setup 函数也是 Compsition API 的入口函数,我们的变量、方法都是在该函数里定义的

<template>
  <div>
    <p>{
    
    {
    
     msg }}</p>
    <button @click="change">改变msg的值</button>
  </div>
</template>

<script>
import {
    
     ref } from 'vue'
export default {
    
    
  setup() {
    
    
    const msg = ref('hello')
    function change() {
    
    
      msg.value = 'hi world !'
    }
    return {
    
     msg, change }
  }
}
</script>

在这里插入图片描述
注意: 这里指的 .value 是在 setup 函数中访问 ref 包装后的对象时才需要加的,在 template 模板中访问时是不需要的,因为在编译时,会自动识别其是否为 ref 包装过的

(3)生命周期

Vue2 Vue3
beforeCreate setup
created setup
beforeMount onBeforeMount
mounted onBeforeMount
beforeMount onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestory onBeforeUnmount
destoryed onUnmounted
<script>
import {
    
    onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue'
export default {
    
    
  setup() {
    
    
  	BeforeMount(() => {
    
    
      // 在挂载前执行某些代码
    })

    onMounted(() => {
    
    
      // 在挂载后执行某些代码
    })

    onBeforeUpdate(() => {
    
    
      // 在更新前前执行某些代码
    })

    onUpdated(() => {
    
    
      // 在更新后执行某些代码
    })

    onBeforeUnmount(() => {
    
    
      // 在组件销毁前执行某些代码
    })

    onUnmounted(() => {
    
    
      // 在组件销毁后执行某些代码
    })
  }
}
</script>

(4)reactive

<template>
  <div>
    <p>{
    
    {
    
     state.count }}</p>
    <button @click="add">增加</button>
  </div>
</template>

<script>
import {
    
     reactive } from 'vue'
export default {
    
    
  setup() {
    
    
    const state = reactive({
    
     count: 3 })
    function add() {
    
    
      state.count ++
    }
    return {
    
     state, add }
  }
}

建议:
基本类型值(String 、Nmuber 、Boolean 等)或单值对象(类似像 {count: 3} 这样只有一个属性值的对象)使用 ref
引用类型值(Object 、Array)使用 reactive

(5)toRef

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

<script>
// 1. 导入 toRef
import {
    
    toRef} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    count: 3}
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = toRef(obj, 'count')
  
        // 3. 将toRef包装过的数据对象返回供template使用
        return {
    
    state}
    }
}
</script>


<script>
// 1. 导入 ref
import {
    
    ref} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    count: 3}
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = ref(obj.count)
  
        // 3. 将ref包装过的数据对象返回供template使用
        return {
    
    state}
    }
}
</script>

ref 和 toRef 的区别

<template>
    <p>{
    
    {
    
     state1 }}</p>
    <button @click="add1">增加</button>

 <p>{
    
    {
    
     state2 }}</p>
    <button @click="add2">增加</button>
</template>

<script>
import {
    
    ref, toRef} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    count: 3}
        const state1 = ref(obj.count)
        const state2 = toRef(obj, 'count')

        function add1() {
    
    
            state1.value ++
            console.log('原始值:', obj);
            console.log('响应式数据对象:', state1);
        }

        function add2() {
    
    
            state2.value ++
            console.log('原始值:', obj);
            console.log('响应式数据对象:', state2);
        }

        return {
    
    state1, state2, add1, add2}
    }
}
</script>

在这里插入图片描述
可以看到,在对响应式数据的值进行 +1 操作后,

  • 视图未发生改变原始值改变了响应式数据对象的值也改变了,这说明 toRef 是对原数据的一个引用,会影响到原始值,但是响应式数据对象值改变后不会更新视图。
  • ref视图改变了原始值未改变响应式数据对象的值也改变了,这说明 ref 是对原数据的一个拷贝,不会影响到原始值,同时响应式数据对象值改变后会同步更新视图。

总结:

  1. ref 是对传入数据的拷贝;toRef 是对传入数据的引用
  2. ref 的值改变会更新视图;toRef 的值改变不会更新视图

(6)toRefs

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

<template>
  <div>
    <p>{
    
    {
    
     state.name._object.name }}</p>   <!-- 小红书 -->
  </div>
</template>
<script>
// 1. 导入 toRefs
import {
    
    toRefs} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          name: '小红书',
          age: 18,
          gender: 0
        }
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = toRefs(obj)
  
        // 3. 打印查看一下
        console.log(state)
    }
}
</script>

返回的是一个对象,对象里包含了每一个包装过后的响应式数据对象
在这里插入图片描述

(7)shallowReactive

将 obj 作为参数传递给 reactive 生成响应式数据对象时,若 obj 的层级不止一层,那么会将每一层都用 Proxy 包装一次

<script>
import {
    
    reactive} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          a: 1,
          first: {
    
    
            b: 2,
            second: {
    
    
              c: 3
            }
          }
        }
        
        const state = reactive(obj)

        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>

在这里插入图片描述
设想一下如果一个对象层级比较深,那么每一层都用 Proxy 包装后,对于性能是非常不友好的
接下来我们再来看看 shallowReactive

<script>
import {
    
    shallowReactive} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          a: 1,
          first: {
    
    
            b: 2,
            second: {
    
    
              c: 3
            }
          }
        }
        
        const state = shallowReactive(obj)

        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>

在这里插入图片描述
结果非常的明了了,只有第一层被 Proxy 处理了,也就是说只有修改第一层的值时,才会响应式更新,代码如下:

<template>
 <p>{
    
    {
    
     state.a }}</p>
 <p>{
    
    {
    
     state.first.b }}</p>
 <p>{
    
    {
    
     state.first.second.c }}</p>
 <button @click="change1">改变1</button>
 <button @click="change2">改变2</button>
</template>
<script>
import {
    
    shallowReactive} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          a: 1,
          first: {
    
    
            b: 2,
            second: {
    
    
              c: 3
            }
          }
        }
        
        const state = shallowReactive(obj)
  
        function change1() {
    
    
          state.a = 7
        }

        function change2() {
    
    
          state.first.b = 8
          state.first.second.c = 9
          console.log(state);
        }

        return {
    
    state}
    }
}
</script>

在这里插入图片描述
触发change1函数,a的值发生改变
在这里插入图片描述
触发了change2,值改变了,但是视图并没有更新
在这里插入图片描述
但我们再去触发change1,整个视图进行了更新
在这里插入图片描述
由此可说明,shallowReactive 监听了第一层属性的值,一旦发生改变,则更新视图。

(8)shallowRef

这是一个浅层的 ref,与 shallowReactive 一样是拿来做性能优化的
shallowReactive 是监听对象第一层的数据变化用于驱动视图更新,那么 shallowRef 则是监听 .value 的值的变化来更新视图的

<template>
	<div>
 		<p>{
    
    {
    
     state.a }}</p>
 		<p>{
    
    {
    
     state.first.b }}</p>
 		<p>{
    
    {
    
     state.first.second.c }}</p>
 		<button @click="change1">改变1</button>
 		<button @click="change2">改变2</button>
   	</div>
</template>

<script>
import {
    
    shallowRef} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          a: 1,
          first: {
    
    
            b: 2,
            second: {
    
    
              c: 3
            }
          }
        }
        
        const state = shallowRef(obj)
        console.log(state);
  
        function change1() {
    
    
          // 直接将state.value重新赋值
          state.value = {
    
    
            a: 7,
            first: {
    
    
              b: 8,
              second: {
    
    
                c: 9
              }
            }
          }
        }

        function change2() {
    
    
          state.value.first.b = 8
          state.value.first.second.c = 9
          console.log(state);
        }

        return {
    
    state, change1, change2}
    }
}
</script>

触发了change2发现数据确实被改变了,但是视图并没随之更新;
再点击change1发现数据确实被改变了,视图就立马更新了;
这么一看,未免也太过麻烦了,改个数据还要重新赋值,不要担心,此时我们可以用到另一个API,叫做 triggerRef ,调用它就可以立马更新视图,其接收一个参数 state ,即需要更新的 ref 对象
在这里插入图片描述

<template>
	<div>
 		<p>{
    
    {
    
     state.a }}</p>
 		<p>{
    
    {
    
     state.first.b }}</p>
 		<p>{
    
    {
    
     state.first.second.c }}</p>
 		<button @click="change">改变</button>
   	</div>
</template>

<script>
import {
    
    shallowRef, triggerRef} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          a: 1,
          first: {
    
    
            b: 2,
            second: {
    
    
              c: 3
            }
          }
        }
        
        const state = shallowRef(obj)
        console.log(state);
  
        function change() {
    
    
          state.value.first.b = 8
          state.value.first.second.c = 9
          // 修改值后立即驱动视图更新
          triggerRef(state)
          console.log(state);
        }

        return {
    
    state, change }
    }
}
</script>

在这里插入图片描述

(9)toRaw

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

<template>
	<div>
 		<p>{
    
    {
    
     state.name }}</p>
 		<p>{
    
    {
    
     state.age }}</p>
 		<button @click="change">改变</button>
   	</div>
</template>

<script>
import {
    
    reactive, ref, toRaw} from 'vue'
export default {
    
    
    setup() {
    
    
        const obj = {
    
    
          name: '小红书',
          age: 18
        }
        
        const state = reactive(obj)
        const raw = toRaw(state) 
        const state1 = ref(obj) 
        const raw1 = toRaw(state1.value)  //  接收的参数是 ref 对象时,需要.value 才能获取到原始数据对象
  
        function change() {
    
    
          state.age = 90
          console.log(obj); // 打印原始数据obj
          console.log(state);  // 打印 reactive对象
          console.log(raw);  // 打印toRaw
          console.log(raw1 );
          console.log(raw === obj);  // true
          console.log(raw1 === obj);  // true
        }

        return {
    
    state, change }
    }
}
</script>

在这里插入图片描述

(10)markRaw

<template>
	<div>
 		<p>{
    
    {
    
     state.name }}</p>
 		<p>{
    
    {
    
     state.age }}</p>
 		<button @click="change">改变</button>
   	</div>
</template>

<script>
import {
    
    reactive, markRaw} from 'vue'
export default {
    
    
    setup() {
    
    
    	const obj = {
    
    
          name: '小红书',
          age: 18
        }
        // 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
        const raw = markRaw(obj)   
        // 试图用reactive包装raw, 使其变成响应式数据
        const state = reactive(raw) 

        function change() {
    
    
          state.age = 90
          console.log(state);
        }

        return {
    
    state, change }
    }
}
</script>

从图中可以看到,即使我们修改了值也不会更新视图了,即没有实现数据响应式
在这里插入图片描述

(11)getCurrentInstance

在Vue2的任何一个组件中想要获取当前组件的实例可以通过 this 来得到,而在Vue3中我们大量的代码都在 setup 函数中运行,并且在该函数中 this 指向的是 undefined,这时就需要使用getCurrentInstance

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

        return {
    
    num}
    }
}
</script>

在这里插入图片描述
在这里插入图片描述
可以看到 ctx 和 proxy 的内容十分类似,只是后者相对于前者外部包装了一层 proxy,由此可说明 proxy 是响应式的

(12)useStore

在Vue2中使用 Vuex,我们都是通过 this.$store 来与获取到Vuex实例,但上一部分说了原本Vue2中的 this 的获取方式不一样了,并且我们在Vue3的 getCurrentInstance().ctx 中也没有发现 $store 这个属性,这就要通过 vuex 中的一个方法了,即 useStore

// store 文件夹下的 index.js
import Vuex from 'vuex'

const store = Vuex.createStore({
    
    
    state: {
    
    
      name: '前端印象',
      age: 22
    },
    mutations: {
    
    
      ……
    },
    ……
})

// example.vue
<script>
// 从 vuex 中导入 useStore 方法
import {
    
    useStore} from 'vuex'
export default {
    
    
    setup() {
    
     
        // 获取 vuex 实例
        const store = useStore()

        console.log(store)
    }
}
</script>

在这里插入图片描述

(13)获取标签元素

最后再补充一个 ref 另外的作用,那就是可以获取到标签元素或组件
在Vue2中,我们获取元素都是通过给元素一个 ref 属性,然后通过 this.$refs.xx 来访问的,但这在Vue3中已经不再适用了
接下来看看Vue3中是如何获取元素的吧

<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(() => {
    
    
      el.value.innerHTML = '内容被修改'
    })

    // 把创建的引用 return 出去
    return {
    
    el}
  }
}
</script>

获取元素的操作一共分为以下几个步骤:

  1. 先给目标元素的 ref 属性设置一个值,假设为 el
  2. 然后在 setup 函数中调用 ref 函数,值为 null,并赋值给变量 el,这里要注意,该变量名必须与我们给元素设置的 ref 属性名相同
  3. 把对元素的引用变量 el 返回(return)出去

补充:设置的元素引用变量只有在组件挂载后才能访问到,因此在挂载前对元素进行操作都是无效的

(14)readonly

只可读,不可修改

<template>
  <div>
    <p>{
    
    {
    
     money }}</p>
    <button @click="money++">增加</button>
  </div>
</template>

<script>
import {
    
     readonly, ref } from 'vue'
export default {
    
    
  setup() {
    
    
    const money = ref(100)
    return {
    
     
      money: readonly(money)
    }
  }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lannieZ/article/details/110221731