Vue3 新增常用API

vue3 中,vue 暴露了很多新的 api ,我们可以根据自己的需求按需引入,这样打包模块时会减小体积

setup

setup 函数也是 Composition API 的入口函数

<template>
  <div id="test">
    <div>{{ number }}</div>
    <button @click="add">Add</button>
  </div>
</template>

<script>
// 1. 从 vue 中引入 ref 函数
import { ref } from 'vue'

export default {
  name: 'Test',
  setup() {
      // 2. 用 ref 函数包装一个响应式变量 number
      let number = ref(0)
      // 3. 设定一个方法
      // number是被ref函数包装过了的,其值保存在.value中
      cosnt add = () => number.value ++
      // 4. 将 number 和 add 返回出去,供template中使用
      return {
        number,
        add
      }
  }
}
</script>

setup 函数还有两个参数,分别是 propscontext,前者存储着定义当前组件允许外界传递过来的参数名称以及对应的值;后者是一个上下文对象,能从中访问到 attremitslots

其中 emit 就是我们熟悉的 Vue2 中与父组件通信的方法,可以直接拿来调用

生命周期

Vue2Vue3
beforeCreatesetup
createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestoryonBeforeUnmount
destoryedonUnmounted

使用,直接在 vue 中导入,再进行直接调用

<template>
  <div id="app"></div>
</template>

<script>
// 从 vue 中引入 多个生命周期函数
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, unMounted } from 'vue'
export default {
  name: 'App',
  setup() {
    onBeforeMount(() => {
        // 在挂载前执行某些代码
    })

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

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

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

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

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

    return {

    }
  }
}
</script>

reactive

reactive 方法是用来创建一个响应式数据对象,该 API 也很好的解决了 vue2 通过 defineProperty 实现数据响应的缺陷

<template>
  <div id="app">
   <!-- 4. 访问响应式数据对象中的 count  -->
   {{ state.count }}
  </div>
</template>

<script>
// 1. 从 vue 中导入 reactive 
import { reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    // 2. 创建响应式的数据对象
    const state = reactive({ count: 3 })

    // 3. 将响应式数据对象state return 出去,供template使用
    return {state}
  }
}
</script>

ref

ref 就是通过 reactive 包装了一个对象 ,然后是将值传给该对象中的 value 属性,这也就解释了为什么每次访问时我们都需要加上 .value
我们可以简单地把 ref(obj) 理解为这个样子 reactive({value: obj})

<script>
import { ref, reactive } from 'vue'

export default {
  name: 'App',
  setup() {
    const obj = { count: 3 }
    const state1 = ref(obj)
    const state2 = reactive(obj)

    console.log(state1)
    console.log(state2)
  }
}
</script>

.value 是在 setup 函数中访问 ref 包装后的对象时才需要加的,在 template模板中访问时是不需要的,因为在编译时,会自动识别其是否为 ref 包装过的

建议

  • 基本类型值(StringNmuberBoolean 等)或单值对象(类似像 {count: 3} 这样只有一个属性值的对象)使用 ref
  • 引用类型值(ObjectArray)使用 reactive

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>

总结

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

toRefs

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

<script>
// 1. 导入 toRefs
import { toRefs } from 'vue'
export default {
  setup() {
    const obj = {
      name: 'sanm',
      age: 33
    }
    // 2. 将 obj 对象中属性count的值转化为响应式数据
    const state = toRefs(obj)

    // 3. 打印查看一下
    console.log(state)
  }
}
</script>

toRef

shallowReactive

一个浅层的 reactive,一个用于性能优化的API
reactive 包裹一个对象时,如果对象层级不止一层,那么每层都会用 Proxy 包装
如果用 shallowReactive 包裹,只有在第一层包装 Proxy

shallowRef

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

结合 triggerRef 调用后会里面更新视图

toRaw

toRaw 方法是用于获取 refreactive 对象的原始数据的

<script>
import { reactive, toRaw } from 'vue'
export default {
  setup() {
    const obj = {
      name: 'sanm',
      age: 33
    }

    const state = reactive(obj) 
    const raw = toRaw(state)

    console.log(obj === raw)   // true
  }
}
</script>

toRaw 方法入参是 ref 对象时,需要加上 .value 才能获取到原始数据对象

markRaw

markRaw 方法可以将原始数据标记为非响应式,既使用 refreactive 将其包装,仍无法实现数据响应式,其接收一个参数,即原始数据,并返回被标记后的数据

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

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

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

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

改变后,不会更新视图,既没有实现数据响应

provideinject

Vue2 中的 provideinject 作用相同,只不过在 Vue3 中需要手动从 vue 中导入

  • provide :向子组件以及子孙组件传递数据。接收两个参数,第一个参数是 key,即数据的名称;第二个参数为 value,即数据的值
  • inject :接收父组件或祖先组件传递过来的数据。接收一个参数 key,即父组件或祖先组件传递的数据名称
// A.vue
<script>
import { provide } from 'vue'
export default {
  setup() {
    const obj= {
      name: 'sanm',
      age: 33
    }

    // 向子组件以及子孙组件传递名为info的数据
    provide('info', obj)
  }
}
</script>

// B.vue
<script>
import { inject } from 'vue'
export default {
    setup() { 
      // 接收A.vue传递过来的数据
      inject('info')  // {name: 'sanm', age: 33}
    }
}
</script>

// C.vue
<script>
import { inject } from 'vue'
export default {
  setup() { 
    // 接收A.vue传递过来的数据
    inject('info')  // {name: 'sanm', age: 33}
  }
}
</script>

watch && watchEffect

watchwatchEffect 都是用来监视某项数据变化从而执行指定的操作的,但用法上还是有所区别

watchwatch( source, cb, [options] )

参数说明:

  • source:可以是表达式或函数,用于指定监听的依赖对象
  • cb:依赖对象变化后执行的回调函数
  • options:可参数,可以配置的属性有 immediate(立即触发回调函数)、deep(深度监听)

当监听 ref 类型时:

<script>
import { ref, watch } from 'vue'
export default {
  setup() { 
    const state = ref(0)

    watch(state, (nV, oV) => {
      console.log(`原值为${oV}`)
      console.log(`新值为${nV}`)
    })

    setTimeout(() => {
      state.value ++
    }, 1000)
  }
}
</script>

当监听 reactive 类型时:

<script>
import { reactive, watch } from 'vue'
export default {
  setup() { 
    const state = reactive({ count: 0 })

    watch(() => state.count, (nV, oV) => {
      console.log(`原值为${oV}`)
      console.log(`新值为${nV}`)
    })

    setTimeout(() => {
      state.count ++
    }, 1000)
  }
}
</script>

当同时监听多个值时:

<script>
import { reactive, watch } from 'vue'
export default {
  setup() { 
    const state = reactive({ count: 0, name: 'sanm' })

    watch(
      [() => state.count, () => state.name], 
      ([nC, nN], [oC, oN]) => {
        console.log(oC)
        console.log(nC)
        console.log(oN)
        console.log(nN)
      }
    )

    setTimeout(() => {
      state.count ++
      state.name = 'sanmzh'
    }, 1000)
  }
}
</script>

watch 方法的第一个参数我们已经指定了监听的对象,因此当组件初始化时,不会执行第二个参数中的回调函数,若我们想让其初始化时就先执行一遍,可以在第三个参数对象中设置 immediate: true
watch 方法默认是渐层的监听我们指定的数据,例如如果监听的数据有多层嵌套,深层的数据变化不会触发监听的回调,若我们想要其对深层数据也进行监听,可以在第三个参数对象中设置 deep: true

补充
watch 方法会返回一个 stop 方法,若想要停止监听,便可直接执行该 stop 函数


watchEffect,它与 watch 的区别:

  • 不需要手动传入依赖
  • 每次初始化时会执行一次回调函数来自动获取依赖
  • 无法获取到原值,只能得到变化后的值
<script>
import {reactive, watchEffect} from 'vue'
export default {
  setup() { 
    const state = reactive({ count: 0, name: 'sanm' })

    watchEffect(() => {
      console.log(state.count)
      console.log(state.name)
      // 会有一次初始化打印
      // 0
      // sanm
      // 一秒后
      // 1
      // sanmzh
    })

    setTimeout(() => {
      state.count ++
      state.name = 'sanmzh'
    }, 1000)
  }
}
</script>

getCurrentInstance

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

<template>
 <p>{{ num }}</p>
</template>
<script>
import {ref, getCurrentInstance} from 'vue'
export default {
  setup() { 
    const num = ref(3)
    const instance = getCurrentInstance()
    console.log(instance)
    // 主要使用 ctx 和 proxy

    return {num}
  }
}
</script>

useStore && useRouter && useRoute

参考:

useStoreuseRouteruseRoute 都是只能在 setup中才能使用

<script>
import { useStore } from 'vuex'
import { useRouter, userRoute } from 'vue-router'
export default {
  setup() { 
    const store = useStore()
    const route = useRoute()
    const router = useRouter()
    // 和 vue2 使用方法类似

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

ref

获取到标签元素或组件,在Vue2中,我们获取元素都是通过给元素一个 ref 属性,然后通过 this.$refs.xx 来访问的,但这在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 = 'xxxxxx'
    })

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

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

如果引用的是一个组件元素,那么获得的将是该组件的实例对象

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3是Vue.js的最新版本,它具有更加简洁、高效的API和更好的性能。下面是Vue3常用方法及案例: 1. 响应式数据 在Vue3中,使用`ref`和`reactive`来创建响应式数据。 ```javascript import { ref, reactive } from 'vue' // ref const count = ref(0) // reactive const state = reactive({ name: 'Vue', version: '3.0', features: ['Composition API', 'Teleport', 'Suspense'], }) ``` 2. 组件 Vue3中,组件的定义方式有所变化,使用`defineComponent`来定义组件。 ```javascript import { defineComponent } from 'vue' export default defineComponent({ name: 'HelloWorld', props: { msg: String, }, setup(props) { return { greeting: `Hello, ${props.msg}!`, } }, template: '<h1>{{ greeting }}</h1>', }) ``` 3. 生命周期 Vue3中,生命周期的名称和使用方式都有所变化。 ```javascript import { onBeforeMount, onMounted } from 'vue' export default { // Vue2 beforeMount() { console.log('beforeMount') }, mounted() { console.log('mounted') }, // Vue3 setup() { onBeforeMount(() => { console.log('beforeMount') }) onMounted(() => { console.log('mounted') }) }, } ``` 4. 组合式API Vue3中,引入了组合式API,可以更好地组织和重用逻辑。 ```javascript import { ref, computed, watchEffect } from 'vue' export default { setup() { const count = ref(0) const doubled = computed(() => count.value * 2) watchEffect(() => { console.log(`count: ${count.value}, doubled: ${doubled.value}`) }) return { count, doubled, } }, } ``` 5. Teleport Vue3中,新增了Teleport组件,可以将子组件的内容渲染到父组件之外的DOM节点中。 ```javascript <template> <div> <h1>Welcome to my app!</h1> <teleport to="body"> <Modal :show="showModal" @close="showModal = false" /> </teleport> <button @click="showModal = true">Show Modal</button> </div> </template> ``` 6. Suspense Vue3中,新增了Suspense组件,可以优雅地处理异步组件和动态组件的加载状态。 ```javascript <template> <div> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <Loading /> </template> </Suspense> </div> </template> ``` 以上是Vue3常用方法及案例,希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值