Vue3组合式API

这篇具有很好参考价值的文章主要介绍了Vue3组合式API。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

composition API vs options API

体验 composition API

setup 函数

reactive 函数

ref 函数

script setup 语法

计算属性 computed 函数

监听器 watch 函数

生命周期

模板中 ref 的使用

组件通讯 - 父传子

组件通讯 - 子传父

依赖注入 - provide 和 inject

保持响应式 - toRefs 函数


​​​​​​​composition API vs options API

  1. vue2 采用的就是 options API

    (1) 优点: 易于学习和使用, 每个代码有着明确的位置 (例如: 数据放 data 中, 方法放 methods 中)

    (2) 缺点: 完成相同功能的代码不能放在一起, 在大项目中尤为明显。可维护性不好

  2. vue3 新增的就是 composition API

    (1) compositionAPI 是基于 逻辑功能 组织代码的, 一个功能相关的代码可以放到一起

    (2) 即使项目大了, 功能多了,也能快速定位相关功能的代码,大大的提升了代码的可维护性

  3. vue3 推荐使用 composition API, 也保留了options API

    即就算不用 composition API, 用 vue2 的写法也完全兼容!!

体验 composition API

需求:

  1. 显示隐藏图片

  2. 计数器功能

Vue3组合式API

 options API 版本

<template>
  <button @click="toggle">显示隐藏图片</button>
  <img v-show="show" alt="Vue logo" src="./assets/vue.svg" />
  <hr />
  计数器:{{ count }} <button @click="add">+1</button>
</template>
<script>
export default {
  data() {
    return {
      show: true,
      count: 0
    }
  },
  methods: {
    toggle() {
      this.show = !this.show
    },
    add() {
      this.count++
    }
  }
}
</script>

composition API 版本

<template>
  <button @click="toggle">显示隐藏图片</button>
  <img v-show="show" alt="Vue logo" src="./assets/vue.svg" />
  <hr />
  计数器:{{ count }} <button @click="add">+1</button>
</template>
<script>
// ref 就是一个组合式API,用于数据响应式 
import { ref } from 'vue';
export default {
  setup () {
    // 显示隐藏图片
    const show = ref(true)
    const toggle = () => {
      show.value = !show.value
    }
    
    // 计数器
    const count = ref(0)
    const add = () => {
      count.value++
    }
    return { show, toggle, count, add }
  }
}
</script>

小结:

optionsAPI

  • 优点: 易于学习和使用, 每个代码有着明确的位置

  • 缺点: 完成相同功能的代码不能放在一起, 在大项目中尤为明显。可维护性不好

compositionAPI

  • 基于 逻辑功能 组织代码

  • 可复用性和可维护性都更好!

setup 函数

composition api 的使用, 需要配置一个 setup 函数

  1. setup 函数是一个新的组件选项, 作为组件中 composition API 的起点

  2. setup 比 beforeCreate 执行时机还要早,此时 vue 的实例还没有创建,所以setup 中不能使用 this, this 指向 undefined

  3. 在模版中需要使用的数据和函数,需要在 setup 返回

<template>
  <h1 @click="sayHi">{{msg}}</h1>
</template>

<script>
export default {
  setup () {
    console.log('setup')
    console.log(this)
    
    // 定义数据和函数
    const msg = 'hi vue3'
    const sayHi = () => {
      console.log(msg)
    }

    return { msg, say }
  },
  beforeCreate() {
    console.log('beforeCreate')
    console.log(this)
  }
}
</script>

reactive 函数

setup 中定义的数据,默认情况不是响应式的,需要用 reactive 函数,将数据变成响应式的

作用:可以将一个复杂类型的数据,转换成响应式数据

<template>
  <div>{{ user.name }}</div>
  <div>{{ user.age }}</div>
  <button @click="changeAge">改年龄</button>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup () {
    const user = reactive({
      name: 'zs',
      age: 18
    })
    
    const changeAge = () => {
      user.age++
      console.log(user.age)
    }

    return {
      user,
      changeAge
    }
  }
}
</script>

ref 函数

reactive 处理的数据,必须是复杂类型,如果是简单类型无法处理成响应式,所以有 ref 函数!

作用:可以将一个简单类型或复杂类型的数据,转换成响应式数据。

<template>
  <div>{{ count }}</div>
  <button @click="add">+1</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    console.log(count)
		console.log(count.value)
    
    const add = () => {
      count.value++
    }
    return {
      count,
      add
    }
  }
}
</script>

ref 和 reactive 的最佳使用方式:

  • 明确的对象,明确的属性,用 reactive,其他用 ref

  • 从vue3.2之后,更推荐使用 ref(ref底层性能做了提升 => 260%)

// 1. 明确的对象和属性
const form = reactive({
  username: '',
  password: ''
})

// 2. 不明确的对象和属性
const list = ref([])
const res = await axios.get('/list')
list.value = res.data

script setup 语法

script setup 是在单文件组件 (SFC) 中,使用组合式 API 的编译时语法糖。相比于普通的 script 语法更加简洁

要使用这个语法,需要将 setup attribute 添加到 <script> 代码块上:

<script setup></script>

所有定义的变量,函数和 import 导入的内容都可以直接在模板中直接使用

<template>
  <div>{{ count }}</div>
  <button @click="add">+1</button>
</template>

<script setup>
import { ref } from 'vue'
  
const count = ref(0)
const add = () => {
  count.value++
}
</script>

计算属性 computed 函数

computed 函数调用时,要接收一个处理函数,处理函数中,需要返回计算属性的值。

<template>
  <div>今年的年龄 <input type="number" v-model="age" /></div>
  <div>明年的年龄 {{ nextAge }}</div>
</template>

<script setup>
import { computed, ref } from 'vue'

const age = ref(18)
const nextAge = computed(() => {
  return age.value + 1
})
</script>

监听器 watch 函数

watch 监听, 接收三个参数
1. 参数1: 监视的数据
2. 参数2: 回调函数
3. 参数3: 额外的配置

<template>
  <div>{{ count }} <button @click="count++">+1</button></div>
  <div>
    {{ user }} 
    <button @click="changeUser">修改用户信息</button>
    <button @click="changeName">修改用户的年龄</button>
    <button @click="changeAge">修改用户的姓名</button>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
  
// 1. 监听数据基础用法
const count = ref(0)
watch(count, (newValue, oldValue) => {
  console.log(newValue, oldValue)
})

// 2. 监听复杂类型数据
const user = ref({
  name: 'zs',
  age: 18
})
const changeUser = () => {
  user.value = {
    name: 'ls',
    age: 19
  }
}
const changeName = () => {
	user.value.name = 'ls'
}
watch(user, (newValue) => {
  console.log('user变化了', newValue)
}, {
  // 深度监听:当监听复杂数据类型的某个属性的变化,需要深度监听
  deep: true,
  // 让监听器立即执行一次
  immediate: true
})

// 3. 监听对象的某个属性的变化
const changeAge = () => {
  user.value.age = 19
}
watch(
  () => user.value.age,
  (newValue) => {
    console.log(newValue)
  }
)
</script>

生命周期

生命周期函数 vue3 中的生命周期函数, 需要在 setup 中调用。

vue2 和 vue3 的生命周期对比:

  1. beforeCreate 和 created 在 setup 中不需要,原来在这两个生命周期中做的事,直接写到setup函数中。

  2. 在原来的名字前加一个 on

  3. beforeDestroyed 变为 onBeforeUnmount,destroyed 变为 onUnmounted

选项式API下的生命周期函数使用 组合式API下的生命周期函数使用
beforeCreate 不需要(直接写到setup函数中)
created 不需要(直接写到setup函数中)
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroyed onBeforeUnmount
destroyed onUnmounted
activated onActivated
deactivated onDeactivated

 

<script setup>
import { onMounted } from "vue"

// 生命周期函数:组件渲染完毕
onMounted(()=>{
  console.log('onMounted触发了')
})

onMounted(()=>{
  console.log('onMounted也触发了')
})
</script>

<template>
  <div>生命周期函数</div>
</template>

模板中 ref 的使用

联想之前的 ref 和 $refs, 获取 DOM 元素 或 组件

获取 DOM

  1. 创建 ref => const h1Ref = ref(null)

  2. 模板中建立关联 => <h1 ref="h1Ref">钩子函数-----123</h1>

  3. 使用 => hRef.value 来获取 DOM

<script setup>
import { ref, onMounted } from 'vue'

const h1Ref = ref(null) 

onMounted(() => {
  console.log(h1Ref.value)
})
</script>

<template>
	<h1 ref="h1Ref">我是标题</h1>
</template>

获取组件实例

<script setup>
import { ref } from 'vue'
import MyForm from './components/MyForm.vue'

const myFormRef = ref(null)

const fn = () => {
  console.log(myFormRef.value.count)
  myFormRef.value.validate()
}
</script>

<template>
  <MyForm ref="myFormRef"></MyForm>
	<button @click="fn">获取子	组件属性和方法</button>
</template>

需要使用 defineExpose 暴露属性或方法

<script setup>
import { ref } from 'vue'

const count = ref(0)
const validate = () => {
  console.log('表单校验方法')
}
// 暴露属性或方法给外部组件使用
defineExpose({
  count,
  validate
})
</script>

<template>
  <h3>我是 Form 组件</h3>
</template>

组件通讯 - 父传子

目标:能够实现组件通讯中的父传子组件通讯

步骤:

  1. 父组件提供数据

  2. 父组件将数据传递给子组件

  3. 子组件通过 defineProps 进行接收

核心代码:

父组件

<script setup>
import { ref } from 'vue'
// 在 setup 语法中,组件导入之后就能够直接使用,不需要使用 components 进行局部注册
import Child from './components/Child.vue'

const car = ref('宝马')
</script>

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h1>我是父组件</h1>
    <Child :car="car"></Child>
  </div>
</template>

子组件

<script setup>
// defineProps: 接收父组件传递的数据
const props = defineProps({
  car: {
    type: String,
    required: true
    // default: '奔驰'
  }
})
// 如果使用 defineProps 接收数据,这个数据只能在模板中渲染,如果想要在 script 中使用 props 属性,应该接收返回值。
console.log(props.car)
</script>

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h3>我是子组件</h3>
    <div>{{ car }}</div>
  </div>
</template>

组件通讯 - 子传父

目标:能够实现组件通讯中的子传父

步骤:

  1. 父组件通过自定义事件的方式在子组件上注册事件

  2. 父组件提供自定义事件的处理函数,并接收子组件传递的数据

  3. 子组件通过 defineEmits 获取 emit 对象(因为没有 this)

  4. 子组件通过 emit 触发事件,并且传递数据

核心代码

父组件

<script setup>
import { ref } from 'vue'
import Child from './components/Child.vue'

const car = ref('宝马')

const changeCar = (newCar) => {
  car.value = newCar
}
</script>

<Child :car="car" @changeCar="changeCar"></Child>

子组件

<script setup>
defineProps({
  car: {
    type: String,
    required: true
    // default: '奔驰'
  }
})

const emit = defineEmits(['changeCar'])

const change = () => {
  emit('changeCar', '玛莎拉蒂')
}
</script>

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h3>我是子组件</h3>
    <div>{{ car }}</div>
    <button @click="change">换车</button>
  </div>
</template>

依赖注入 - provide 和 inject

依赖注入:可以非常方便的实现跨级的组件通信

父组件利用 provide 提供数据

<script setup>
import { provide, ref } from 'vue'
import Child from './components/Child.vue'

const car = ref('宝马')
provide('car', car)
</script>

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h1>我是父组件</h1>
    <Child></Child>
  </div>
</template>

子孙后代组件,都可以拿到这个数据)

<script setup>
import { inject } from 'vue'

const car = inject('car')
</script>	

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h3>我是子组件 -- {{ car }}</h3>
  </div>
</template>

如果希望子传父, 可以 provide 传递一个方法

父组件

<script setup>
import { provide, ref } from 'vue'
import Child from './components/Child.vue'

const car = ref('宝马')
const changeCar = (newCar) => {
  car.value = newCar
}
provide('car', car)
provide('changeCar', changeCar)
</script>

子组件

<script setup>
import { inject } from 'vue'

const car = inject('car')
const changeCar = inject('changeCar')
</script>

<template>
  <div style="border: 3px solid #ccc;margin: 10px;">
    <h3>我是子组件 -- {{ car }}</h3>
    <button @click="changeCar('兰博基尼')">换车</button>
  </div>
</template>

保持响应式 - toRefs 函数

如果对一个响应式数据, 进行解构, 会丢失它的响应式特性!

原因: vue3 底层是对 对象 进行监听劫持,reactive/ref 的响应式功能是赋值给对象的, 如果给对象解构, 会让数据丢失响应式的能力

toRefs 作用: 对一个 响应式对象 的所有内部属性, 都做响应式处理, 保证解构出的数据也是响应式的文章来源地址https://www.toymoban.com/news/detail-466077.html

<script setup>
import { ref, toRefs } from 'vue'
const user = ref({
  name: 'zs',
  age: 18
})
// 直接解构,会丢失响应式
const { name, age } = user.value
// 解构之前使用 toRefs 处理要解构的数据
const { name, age } = toRefs(user.value)
</script>

<template>
  <div>{{ name }}</div>
  <div>{{ age }}</div>
  <button @click="name = 'ls'">改名</button>
	<button @click="age++">改年龄</button>
</template>

到了这里,关于Vue3组合式API的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3组合式api单文件组件写法

    一,模板部分  二,js逻辑部分 

    2024年02月13日
    浏览(51)
  • vue3 组合式 api 单文件组件写法

    Vue3 中的 Composition API 是一种新的编写组件逻辑的方式,它提供了更好的代码组织、类型推导、测试支持和复用性。相比于 Vue2 的 Options API,Composition API 更加灵活和可扩展。 在 Composition API 中,我们使用 setup 函数来定义组件的逻辑部分。setup 函数是一个特殊的函数,在创建组

    2024年02月12日
    浏览(39)
  • 带你了解vue3组合式api基本写法

    本文的目的,是为了让已经有 Vue2 开发经验的 人 ,快速掌握 Vue3 的写法。 因此, 本篇假定你已经掌握 Vue 的核心内容 ,只为你介绍编写 Vue3 代码,需要了解的内容。 一、Vue3 里 script 的三种写法 首先,Vue3 新增了一个叫做组合式 api 的东西,英文名叫 Composition API。因此 Vu

    2024年02月01日
    浏览(80)
  • vue3:7、组合式API-watch

     

    2024年02月09日
    浏览(43)
  • Vue3: 选项式API和组合式API的优缺点

    Vue框架提供了两种不同的API风格来编写组件,分别是 选项式API 和 组合式API 。 一.选项式API: 选项式API是vue2.x版本中默认使用的API风格,它是基 于对象的方式 来描述组件的行为和状态的。选项式API需要在Vue组件的选项对象中声明组件的属性和方法,如data、methods、computed、

    2024年02月09日
    浏览(46)
  • Vue3的组合式API中如何使用provide/inject?

    听说 Vue 3 加入了超多酷炫的新功能,比如组合式 API 等等。今天我们就来聊聊 Vue 3 中的组合式 API,并且如何使用 provide/inject 来搞定它! 首先,我们来了解一下组合式 API 是什么。其实,组合式 API 就是一个用来构建和组合函数的工具,它能让我们的代码更加简洁、可读性更

    2024年02月11日
    浏览(44)
  • vue3 组合式api中 ref 和$parent 的使用

    ref 的使用 vue3中, 在 组件中添加一个 component ref=“xxx” ,就可以在父组件中得到 子组件的 dom 对象, 以及 虚拟的 dom 对象, 有了虚拟 dom, 我们就可以在父组件中控制子组件的显示了 ref 的使用方法 vue3中ref 的特点 以上如果在vue2中,就可以使用 子组件的对象来改变子组件的

    2024年02月10日
    浏览(44)
  • 【vue3.0 组合式API与选项式API是什么,有什么区别】

    Vue3.0中引入了组合式API(Composition API),同时保留了选项式API(Options API)。两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。实际上,选项式 API 是在组合式 API 的基础上实现的!关于 Vue 的基础概念和知识在它们之间都是通用的

    2024年02月10日
    浏览(43)
  • 最新 Vue3、TypeScript、组合式API、setup语法糖 学习笔记

    备注:目前 vue-cli 已处于维护模式,官方推荐基于 Vite 创建项目。 vite 是新一代前端构建工具,官网地址:https://vitejs.cn vite 的优势如下: 轻量快速的热重载(HMR),能实现极速的服务启动。 对 TypeScript 、 JSX 、 CSS 等支持开箱即用。 真正的按需编译,不再等待整个应用编译

    2024年02月20日
    浏览(46)
  • Vue3:Typescript与组合式API、defineProps、defineEmits等使用

    使用 defineProps() 使用 script setup 在使用 script setup 时, defineProps() 宏函数支持从它的参数中推导类型: 运行时声明 基于类型的声明 注意:接口或对象字面类型可以包含从其他文件导入的类型引用,但是,传递给 defineProps 的泛型参数本身不能是一个导入的类型, 这是因为Vue

    2023年04月20日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包