【Vue】3-2、组合式 API

一、setup 选项

<script>
export default {
  /**
   * 1、setup 执行时机早于 beforeCreate
   * 2、setup 中无法获取 this
   * 3、数据和函数需要在 setup 最后 return,才能在模板中使用
   * 4、可以通过 setup 语法糖简化代码
   */
  setup(){
    // console.log('setup function', this)

    // 数据
    const msg = 'Hello Vue3'
    const logMsg = () => {
      console.log(msg)
    }

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

若未 return 在浏览器也会有警告  

每次都需要 return,若数据与函数的量很大,就会很麻烦,所以可以通过语法糖来简化代码  

<script setup>
const msg = 'Hello Vue3'
const logMsg = () => {
  console.log(msg)
}
</script>

<template>
  <div>{{ msg }}</div>
  <button @click="logMsg"></button>
</template>

二、reactive 和 ref 函数  

reactive():接收对象类型数据的参数传入并返回一个响应式的对象 

步骤:

  • 从 vue 中导入 reactive 函数

  • <script setup> 中执行 reactive 函数并传入类型为对象的初始值,并使用变量接收返回值

<script setup>
 import { reactive } from 'vue'
 const state = reactive({
   count: 100
 })
 const setCount = () => {
   state.count++;
 }
</script>

<template>
  <div>
    <!-- 
      <div>{{ state.count }}</div>
      <button @click="setCount">+1</button> 
    -->
  </div>
</template>

ref():接收简单类型或对象类型的数据传入并返回一个响应式的对象

底层是将简单类型数据包装成对象类型的数据,然后借助 reactive 实现响应式  

步骤:

  • 从 vue 中导入 ref函数

  • <script setup> 中执行 ref函数并传入类型为对象的初始值,并使用变量接收返回值

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

const count = ref(0)
const setCount = () => {
  // 访问数据需要通过 .value【template中不需要】
  count.value++;
}
</script>

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

三、computed 

步骤:

  • 导入 computed 函数

  • 执行函数在回调函数中 return 基于响应式数据做计算的值,用变量接收

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

const list = ref([1, 2, 3, 4, 5, 6, 7, 8])

const computedList = computed(() => {
  // 只读
  return list.value.filter(item => item > 2)
})

const addFn = () => {
  list.value.push(9)
}
</script>

<template>
  <div>
    <div>原始数据:{{ list }}</div>
    <div>计算后数据:{{ computedList }}</div>
    <button @click="addFn">修改</button>
  </div>
</template>

以上创建的是一个 只读 的计算属性 ref,若要创建一个 可写 的计算属性 ref,可以这样做:  

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

在计算属性中不要进行异步请求或这修改 DOM 的操作

避免直接修改计算属性的值

四、watch 

侦听一个或者多个数据的变化,数据变化时执行回调函数  

<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('cp')

const setCount = () => {
  count.value++;
}

const setName = () => {
  name.value = '张三 - 李四'
}

// 侦听单个数据
watch(count, (newValue, oldValue) => {
  console.log(`count 值发生了变化,新值为 ${newValue},旧值为 ${oldValue}`)
})
// 侦听多个数据
watch(
  [count, name],
  ([newCount, newNode], [oldCount, oldName]) => {
    console.log('count 或 name 发生了变化', [newCount, newNode], [oldCount, oldName])
})
</script>

<template>
  <div>{{ count }}</div>
  <button @click="setCount">改数字</button>
  <div>{{ name }}</div>
  <button @click="setName">改名字</button>
</template>

两个参数:

  • immediate(立即执行)

  • deep(深度侦听)  

watch(count, ()=>{
  console.log('count变了')
},{
  immediate: true
})

watch 可以直接监视简单类型数据

const ref = ref(简单类型)

 watch 无法监视复杂类型内部数据的变化

const ref = ref(复杂类型)
watch(复杂类型对象, (newValue) => {
	console.log(newValue);
}, {
	deep: true
})

若没有添加 deep 参数,默认的是监听对象的地址是否变化,除非修改了对象的地址,否则不会被监听到。

若要监听复杂类型对象内部属性的变化,则需要添加 deep 参数,即可对其进行监听

精确监听对象的某个属性

在不开启 deep 的前提下,侦听对象属性的变化,只有属性变化时才执行回调

// 精确侦听某个属性
const info = ref({
  name: 'cp',
  age: 18
})
watch(
  () => info.value.age,
  () => console.log('age变了')
)

五、生命周期函数 

选项式 API组合式 API
beforeCreate/createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBreforeUpdate
updateonUpdate
beforeUnmountonBeforeUnmount
unmountedonUnmounted
<script setup>
import { onMounted } from "vue"

// 一进入页面就调用
const getList = () => {
  setTimeout(() => {
    console.log('发送请求,获取列表数据')
  }, 2000)
}
getList()

// 在 mounted 时执行
onMounted(() => {
  console.log('mounted 生命周期函数 - 逻辑1')
})
// 写成函数的调用方式,可以调用多次,并不会冲突,而是按照顺序依次执行
onMounted(() => {
  console.log('mounted 生命周期函数 - 逻辑2')
})
</script>

六、父子通信 

1、父传子 

基本思想:

  • 父组件给子组件绑定属性

  • 子组件内部通过 props 选项接收  

defineProps 原理:编译阶段的一个标识,实际编译器解析时,遇到后会进行编译转换  

2、子传父 

基本思想:

  • 父组件中给子组件标签通过 @绑定事件

  • 子组件内部通过 emit 方法触发事件  

七、模板引用

通过 ref 标识获取真实的 DOM 对象或者组件实例对象  

步骤:

  • 调用 ref 函数生成一个 ref 对象

  • 通过 ref 标识绑定 ref 对象到

<script setup>
import { ref } from 'vue'
// 通过 ref 函数获得一个 ref 对象
const h1Ref = ref(null)
</script>

<template>
      <!-- 通过 ref 标识绑定 ref 对象 -->
      <h1 ref="h1Ref">我是 DOM 标签 h1</h1>
</template>

获取模板引用的时机:组件挂载完毕  

默认情况下在 <script setup> 语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过 defineExpose 编译宏指定哪些属性和方法允许访问  

<script setup>
import { ref } from 'vue'
const testMsg = ref('this is test msg')
defineExpose({
      testMsg
})
</script>

八、provide 和 inject  

作用:顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信  

跨层传递普通数据

  • 顶层组件通过 provide 函数提供数据

  • 底层组件通过 inject 函数获取数据

// 顶层组件
provide('key', 顶层组件中的数据)

// 底层组件
const msg = inject('key')

顶层组件可以向子层组件传递方法,底层组件调用方法修改顶层组件中的数据【实际在修改数据的依然是顶层组件】

一  叶  知  秋,奥  妙  玄  心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370691.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink容错机制

目录 一&#xff0c;检查点&#xff1a; 二&#xff0c;保存点&#xff1a; ①版本管理和归档存储&#xff1a; ②更新Flink版本&#xff1a; ③更新应用程序&#xff1a; ④调整并行度&#xff1a; ⑤暂停应用程序&#xff1a; Flink容错机制 一&#xff0c;检查点&#xff…

RedHat8.4安装邮件服务器

一、配置发件服务器 1.1 根据现场IP&#xff0c;配置主机名 vim /etc/hosts 192.168.8.120 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1.2 关闭防火墙&#xff0c;禁止开机启动 systemctl stop firewalld systemctl disable firewalld 1.3 关闭selinux v…

java之ReentrantLock

在讲RentrantLock之前需要先讲一下AQS和LockSupport&#xff0c;因为rentrantLock底层是用AQS实现的&#xff0c;而AQS中获取阻塞和唤醒底使用LockSupport实现的。 1、LockSupport实现 下面代码中&#xff0c;LockSupport.park方法是当前线程等待&#xff0c;直到获得许可&am…

React Native学习记录

一、创建RN项目的时候是空文件夹的问题 1.使用npx react-native init RNDemos初始化项目的时候&#xff0c;会报错&#xff0c;模版错误&#xff0c;然后创建出来一个空的文件夹 2.如果出现这种情况&#xff0c;需要设置npm install -g react-native-cli 3.安装完成以后再次初…

Postgres与DynamoDB:选择哪个数据库

启动新项目时需要做出的决定之一是使用哪个数据库。如果您使用的是Django这样的包含电池的框架&#xff0c;那么没有理由再三考虑。选择一个受支持的数据库引擎&#xff0c;就可以了。另一方面&#xff0c;如果你使用像FastAPI或Flask这样的微框架&#xff0c;你需要自己做出这…

聚簇索引、回表与覆盖索引

聚簇索引一般指的是主键索引&#xff08;如果存在主键索引的话&#xff09;。 作为一个正常开发&#xff0c;建表时主键肯定是必须的。 而即使如果表中没有定义主键&#xff0c;InnoDB 会隐式选择一个唯一的非空索引代替。 所以我们就直接含糊点说&#xff1a; 聚簇索引就是…

crmebAI名片小程序全开源全端uniapp

应用介绍 AI名片小程序是一种基于人工智能技术的数字化智能名片&#xff0c;具有多种功能和特点。以下是AI名片小程序的简介&#xff1a; 智能化管理&#xff1a;AI名片小程序具备智能化的管理系统&#xff0c;用户可以方便地管理名片信息&#xff0c;包括个人信息、职位、公司…

jmeter-02切换中文,改为白色背景

文章目录 一、切换中文问题&#xff1a;jmeter设置中文后无法保存&#xff0c;下次启动还是英文 二、改为白色背景 一、切换中文 问题&#xff1a;jmeter设置中文后无法保存&#xff0c;下次启动还是英文 解决办法&#xff1a; 在jmeter路径下找到文件jmeter.bat开启编辑模式&…

如何在Shopee平台上进行手机类目选品?

在Shopee平台上进行手机类目的选品是一个关键而复杂的任务。卖家需要经过一系列的策略和步骤&#xff0c;以确保选品的成功和销售业绩的提升。下面将介绍一些有效的策略&#xff0c;帮助卖家在Shopee平台上进行手机类目选品。 先给大家推荐一款shopee知虾数据运营工具知虾免费…

指针的学习2

目录 数组名的理解 使用指针访问数组 一维数组传参的本质 冒泡排序 二级指针 指针数组 指针数组模拟二维数组 数组名的理解 数组名是数组首元素的地址 例外&#xff1a; sizeof(数组名),sizeof中单独放数组名&#xff0c;这里的数组名表示整个数组&#xff0c;计算的…

从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器

上一章我们完成了netty服务启动的相关抽象&#xff08;https://blog.csdn.net/money9sun/article/details/136025471&#xff09;&#xff0c;这一章我们再新增一个全局的服务启动类&#xff0c;方便后续扩展。 服务启动 新增的两个类如下&#xff1a; 定义一个接口IServer …

6款超好用的IDEA插件,开发必备!

今天给大家介绍几款开发必备的IDEA插件&#xff1a; JRebel 热部署插件&#xff0c;让你在修改完代码后&#xff0c;不用再重新启动&#xff0c;很实用&#xff01;但是&#xff0c;不是免费的&#xff0c;需要大家继续发挥下自己的聪明才智才能happy的使用 Json Parser 厌倦…

Linux 多线程 | 线程的概念

线程的概念 线程是一个执行分支&#xff0c;执行粒度比进程更细&#xff0c;调度成本更低&#xff1b; 线程是进程内部的一个执行流&#xff1b; 线程是CPU调度的基本单位&#xff0c;进程是承担分配系统资源的基本实体。 之前我们学习过虚拟地址空间的知识&#xff0c;知道…

SpringFramework实战指南(五)

SpringFramework实战指南(五) 4.3 基于 注解 方式管理 Bean4.3.1 实验一: Bean注解标记和扫描 (IoC)4.3.2 实验二: 组件(Bean)作用域和周期方法注解4.3.3 实验三: Bean属性赋值:引用类型自动装配 (DI)4.3.4 实验四: Bean属性赋值:基本类型属性赋值 (DI)4.3.5 实验五:…

区块链游戏解说:Axie Infinity 是什么

数据源&#xff1a;Axie Infinity Dashboard 作者&#xff1a;lesleyfootprint.network 什么是 Axie Infinity Axie Infinity 是一个引人入胜的区块链游戏&#xff0c;让玩家可以探索一个充满独特且可收藏的 NFT 生物&#xff08;称为 Axies&#xff09;的世界。 Axie Infin…

[AIGC] 21世纪Java与Go的相爱相杀

在21世纪的软件开发领域中&#xff0c;Java和Go这两门编程语言可谓是相爱相杀的存在。它们各自拥有着强大的特点和独特的优势&#xff0c;同时也存在着一些明显的竞争和冲突。让我们来看看这两门语言的故事&#xff0c;以及它们之间的深远意义。 文章目录 Java的魅力Go的魅力相…

【Simulink系列】——动态系统仿真 之 简单系统

引入 不同的系统具有不同的输入与输出。一般来说&#xff0c;输入输出数目越多&#xff0c;系统越复杂。最简单的系统只要一个输入一个输出&#xff08;SISO&#xff09;&#xff0c;且其任意时刻的输出只与当前时刻的输入有关。 一、简单系统定义 对于满足下列条件的系统&a…

Qt拖拽事件,实现控件内项的相互拖拽

文章目录 1拖拽演示2 步骤3 实现 这里主要以QTableview控件为例&#xff0c;实现表格内数据的相互拖拽。 1拖拽演示 2 步骤 自定以QTableView类&#xff0c;在自定义类中重写拖拽事件&#xff1a; void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *…

【c++】友元

友元提供了一种突破封装的方式&#xff0c;有时提供了便利。但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以友元不宜多用 友元分为&#xff1a;友元函数和友元类 1.友元函数 问题&#xff1a;现在尝试去重载operator<<&#xff0c;然后发现没办法将ope…