vue3基础+进阶(二、vue3常用组合式api基本使用)

news2024/11/25 15:18:58

目录

第二章、组合式API

2.1 入口:setup

2.1.1 setup选项的写法和执行时机

2.1.2 setup中写代码的特点

2.1.3 script setup语法糖

2.1.4 setup中this的指向

2.2 生成响应式数据:reactive和ref函数

2.2.1 reactive函数

2.2.2 ref函数

2.2.3 reactive 对比 ref

2.3 计算属性:computed

2.4 数据监听:watch

2.4.1 监听单个数据

2.4.2 侦听多个数据

2.4.3 immediate立即监听

2.4.4 deep深度监听

2.5 生命周期钩子

2.6 父子通信

2.6.1 父传子通信

2.6.2 子传父通信

2.7 模版引用

2.8 provide和inject


第二章、组合式API

2.1 入口:setup

2.1.1 setup选项的写法和执行时机

  • 写法
<script>
  export default {
    setup(){
      
    },
    beforeCreate(){
      
    }
  }
</script>
  • 时机:在beforeCreate钩子之前执行
<script>
  export default {
     beforeCreate(){
         console.log("beforeCreate生命钩子执行了-------------")
     },
     setup(){
          console.log("setup生命钩子执行了-------------")
     },
  }
</script>

  

2.1.2 setup中写代码的特点

在setup函数中写的数据和方法需要在末尾以对象的方式return,才能给模版使用

<script>
  export default {
    setup(){
      const message = 'this is message'
      const logMessage = ()=>{
        console.log(message)
      }
      // 必须return才可以
      return {
        message,
        logMessage
      }
    }
  }
</script>

2.1.3 script setup语法糖

script标签添加 setup标记,不需要再写导出语句,默认会添加导出语句

<script setup>
  const message = '关注我!!!'
  const logMessage = ()=>{
    console.log(message)
  }
</script>

<template>
  <h2>内容:{{message}}</h2>
  <br>
  <button @click="logMessage">输出消息</button>
</template>

2.1.4 setup中this的指向

this将不再指向组件实例,指向的是undefined

<script setup>
  const logThis = ()=>{
    console.log("Vue3中this的指向",this)
  }
</script>

<template>
  <button @click="logThis">this</button>
</template>

2.2 生成响应式数据:reactive和ref函数

2.2.1 reactive函数

接受对象类型数据的参数传入并返回一个响应式的对象

<script setup>
 // 导入
import {reactive} from 'vue'
    // 执行函数 传入参数 变量接收
  const message = reactive({
    name:'关注我!!!'
  })
  const logMessage = ()=>{
    // 修改数据更新视图
    message.name += '!'
  }
</script>

<template>
  <h2>内容:{{message.name}}</h2>
  <br>
  <button @click="logMessage">输出消息+!</button>
</template>

 确定reactive定义的对象是一个响应式对象

2.2.2 ref函数

接收简单类型或者对象类型的数据传入并返回一个响应式的对象,使用ref获取首层对象记得加 .value

<script setup>
 // 导入
 import { ref } from 'vue'
 // 执行函数 传入参数 变量接收
 const count = ref(0)
 const setCount = ()=>{
   // 修改数据更新视图必须加上.value
   count.value++
 }
</script>

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

 确定ref定义的也是一个响应式对象:

2.2.3 reactive 对比 ref

  • 1.相同点:都是用来生成响应式数据
  • 2. 不同点

        -- reactive不能处理简单类型的数据

        -- ref参数类型支持更好,但是必须通过.value做访问修改

        -- ref函数内部的实现依赖于reactive函数

  • 3. 在实际工作中的推荐

       -- 推荐使用ref函数,减少记忆负担

2.3 计算属性:computed

计算属性基本思想和Vue2保持一致,组合式API下的计算属性只是修改了API写法;不能有异步请求或者dom修改等等

核心步骤:

       1.导入computed函数
        2.执行函数在回调参数中return基于响应式数据做计算的值,用变量接收

<script setup>
// 导入
import {ref, computed } from 'vue'
// 原始数据
const count = ref(1)
// 计算属性
const doubleCount = computed(()=>count.value * 2)

// 原始数据
const list = ref([1,2,3,4,5,6,7,8])
// 计算属性list
const filterList = computed(()=>{
  return list.value.filter ( item=>item > 2)
})
</script>

<template>
  <div>初始数据ref基本类型:{{ count }} </div>
  <div>计算属性数据:{{ doubleCount }} </div>
  <div>原始数据ref引用类型:{{ list }}</div>
  <div>计算属性数据:{{ filterList }}</div>
</template>

2.4 数据监听:watch

侦听一个或者多个数据的变化,数据变化时执行回调函数,watch的第三个参数(俩个额外参数 immediate控制立刻执行,deep开启深度侦听)

2.4.1 监听单个数据

核心步骤:

        1.导入watch函数
        2.执行watch函数传入要侦听的响应式数据(ref对象)和回调函数

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount =  ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  })
</script>

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

2.4.2 侦听多个数据

侦听多个数据,第一个参数可以改写成数组的写法,得到的新旧值也是数组的形式

说明:同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const name = ref('cp')
  const setCount = ()=>{
    count.value++
  }
  const setName = ()=>{
    name.value += 'p'
  }
  // 2. 调用watch 侦听变化
  watch([count, name], ([newCount, newName],[oldCount,oldName])=>{
    console.log(`count或者name变化了`,[newCount, newName],[oldCount,oldName])
  })
</script>

<template>
  <button @click="setCount">{{ count }}</button>
  <button @click="setName">{{ name }}</button>
</template>

2.4.3 immediate立即监听

第三个参数,在侦听器创建时立即出发回调,响应式数据变化之后继续执行回调

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount = ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  },{
    immediate: true
  })
</script>

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

2.4.4 deep深度监听

第三个参数,通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ count: 0 })
  // 2. 监听对象state
  watch(state, ()=>{
    console.log('数据变化了')
  },{
    immediate:true,
    deep:true
  })
  const changeStateByCount = ()=>{
    // 直接修改不会引发回调执行
    state.value.count++
  }
</script>

<template>
  <button @click="changeStateByCount">{{ state.count }}</button>
</template>

 1、对象更深层的值变化了,但是没有监听到

2、对象更深层的值变化了,也监听到了

2.5 生命周期钩子

基本使用:

        1.导入生命周期函数
        2.执行生命周期函数传入回调

<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了')
})
</script>

  

多次执行:

多次执行时传入的回调会在时机成熟时依次执行

<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了2')
})
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了1')
})
</script>

  

2.6 父子通信

2.6.1 父传子通信

基本思想:

        1. 父组件中给子组件绑定属性

        2. 子组件内部通过props选项接收数据

父组件:

<script setup> //引入子组件
    import sonComVue from './son.vue'
</script>
<template>
    <!-- 1.绑定属性message -->
    <div>父组件</div><br>
    <sonComVue message="this is app message "/>
</template>

子组件:

<script setup>
//2.通过defineProps"编译器宏"接收子组件传递的数据
const props = defineProps({
    message: String
})
</script>

<template>
    <div>
        子组件:{{ message }}
    </div>
</template>

 

2.6.2 子传父通信

基本思想:

        1.父组件中给子组件标签通过@绑定自定义事件

        2.子组件内部通过$emit方法触发事件

父组件:

<script setup>
    //引入子组件
    import sonComVue from './son-com.vue '
    //自定一函数方法
    const getMessage = (msg)=→> {
        console.log(msg)
    }
</script>
<template>
    <!--1.绑定自定义事件-->
    <sonComVue @get-message="getMessage">
</template>

子组件:

<script setup>
// 2.通过 defineEmits编译器宏生成emit方法
    const emit = defineEmits(L'get-message ']
    const sendMsg =() {
        // 3.触发自定义事件并传递参数
        emit(' get-message ', 'this is son msg ')
    }
</script>
<template>
    <button @click="sendMsg">sendMsg</button>
</template>

未发送前:

发送后:

2.7 模版引用

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

核心步骤:

        1. 调用ref函数生成一个ref对象

        2. 通过ref标识绑定ref对象到标签

<script setup>
    import { onMounted, ref } from 'vue'// 1.调用ref函数得到ref对象
    const h1Ref = ref(null)

    onMounted(()=>{
      console.log("hiRef",h1Ref)
    })
</script>
<template>
    <!--2.通过ref标识绑定ref对象-->
    <h1 ref="h1Ref">我是dom标签h1</h1>
</template>

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

<script setup>
    import { ref } from 'vue'
    const testMessage = ref('this is test msg ')
    defineExpose({ //向外暴露该组件的方法
        testMessage
    })
</script>

 未使用definExpose编译宏时输出ref没有子组件内的方法:

 使用后能看到对应的方法:

2.8 provide和inject

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

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

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

备注:顶层组件给底层组件提供的是数据时,底层组件只是渲染值;如果底层组件想要改传递的该值,需要顶层组件重新提供更改改数据的方法,底层组件获取到该方法后调用就能更改顶层组件传的值了

父组件:

<script setup>
    import { provide, ref } from 'vue'// 1.调用ref函数得到ref对象
    import son from './son.vue'
    //1、顶层组件提供数据
    provide("data-key","this is data 关注关注!!")
    //传递响应式数据
    const count = ref(0)
    provide('count-key',count)

    setTimeout(()=>{
        count.value++
    },3000)

    //传递方法
    const setCount = () =>{
        count.value ++ 
    }
    provide('setCount-key',setCount)

    const name = ref('*VE*')
    provide('name-key',name)

    setTimeout(()=>{
        name.value += '关注我!!'
    },3000)
</script>
<template>
    <!--2.通过ref标识绑定ref对象-->
    <div style="background-color: red; padding: 20px;">
        <h1>顶层父组件</h1><br>
        <son ref="sonRef"></son>
    </div>
</template>

中间组件:

<script setup>
    import grandson from './grandson.vue'
</script>

<template>
    <div style="background-color: gold; padding: 20px;">
        <div>中间子组件</div><br>
        <grandson/>
    </div>
</template>

底层组件:

<script setup>
import { inject } from "vue";

//2、接收数据
const data = inject('data-key')
//接收响应式数据
const count = inject('count-key')
const name = inject('name-key')
//接收方法
const setCount = inject('setCount-key')
</script>

<template>
  <div style="background-color: skyblue;">
    <div>底层孙组件——</div>
    <div>
      来自顶层父组件的数据为:{{ data }}<br />
      来自顶层父组件的响应式数据为:{{ count }}<br />
      来自顶层父组件的响应式数据为:{{ name }}<br />
      <button @click="setCount">修改顶层组件的数据</button>
    </div>
  </div>
</template>

首次渲染:

 传递响应式数据渲染:

 传递方法:点击按钮,数字修改表示顶层组件的值已经修改

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cesium态势标绘专题-入口

本专题没有废话,只有代码,撸! 标绘主类MilitaryPlotting.ts /** 态势标绘主类* @Author: Wang jianLei* @Date: 2023-01-13 14:47:20* @Last Modified by: jianlei wang* @Last Modified time: 2023-05-31 09:55:34*/ import * as Creator from ./create/index; import Cre…

S32K324双核的核间通信使用示例

文章目录 前言修改ld文件核0的ld文件核1的ld文件 定义共享数据使用共享数据编译共享数据文件总结 前言 最近项目用S32K324开发&#xff0c;暂时只用了MCAL&#xff0c;没有Autosar上层的模块&#xff0c;最开始用官方给的demo工程双核可以正常跑起来&#xff0c;但实际开发时都…

使用nginx和ffmpeg搭建HTTP FLV流媒体服务器(摄像头RTSP视频流->RTMP->http-flv)

名词解释 RTSP &#xff08;Real-Time Streaming Protocol&#xff09; 是一种网络协议&#xff0c;用于控制实时流媒体的传输。它是一种应用层协议&#xff0c;通常用于在客户端和流媒体服务器之间建立和控制媒体流的传输。RTSP允许客户端向服务器发送请求&#xff0c;如…

数据分析工具与技术

数据分析工具与技术 数据分析技术 数据分析工具 备选方案分析 一种对已识别的可选方案进行评估的技术&#xff0c;用来决定选择哪种方案 或使用何种方法来执行项目工作。 其他风险参数评估 为了方便未来分析和行动&#xff0c;在对单个项目风险进行优先级排序时&#xff0…

GO内存模型(同步机制)

文章目录 概念1. 先行发生 编译器重排同步机制init函数协程的创建channelsync 包1. sync.mutex2. sync.rwmutex3. sync.once atomic 参考文献 概念 1. 先行发生 The happens before relation is defined as the transitive closure of the union of the sequenced before and …

超详细-Vivado配置Sublime+Sublime实现Verilog语法实时检查

目录 一、前言 二、准备工作 三、Vivado配置Sublime 3.1 Vivado配置Sublime 3.2 环境变量添加 3.3 环境变量验证 3.4 Vivado设置 3.5 配置验证 3.6 解决Vivado配置失败问题 四、Sublime配置 4.1 Sublime安装Package Control 4.2 Sublime安装Verilog插件 4.3 安装语…

centos7中MySQL备份还原策略

目录 一、直接拷贝数据库文件 1.1在shangke主机上停止服务并且打包压缩数据库文件 1.2 在shangke主机上把数据库文件传输到localhost主机上(ip为192.168.33.157) 1.3在localhost主机上停止服务&#xff0c;解压数据库文件 1.4 在localhost主机上开启服务 1.5 测试 二、m…

利用@Excel实现复杂表头导入

EasyPoi导入 <a-upload name"file" :showUploadList"false" :multiple"false" :headers"tokenHeader" :action"importExcelUrl"change"handleImportExcel"><a-button type"primary" icon&quo…

【软件测试】如何选择回归用例

目录 如何在原始用例集中挑选测试用例 具体实践 总结 本文讨论一下在回归测试活动中&#xff0c;如何选择测试用例集。 回归测试用例集包括基本测试用例集&#xff08;原始用例&#xff09;迭代新增测试用例集&#xff08;修复故障引入的用例和新增功能引入的用例集&#xf…

洛必达法则和分部积分的应用之计算数学期望EX--概率论浙大版填坑记

如下图所示&#xff0c;概率论与数理统计浙大第四版有如下例题&#xff1a; 简单说就是&#xff1a;已知两个相互独立工作电子装置寿命的概率密度函数&#xff0c;将二者串联成整机&#xff0c;求整机寿命的数学期望。 这个题目解答中的微积分部分可谓是相当的坑爹&#xff0c;…

【1++的C++初阶】之适配器

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的C初阶】 文章目录 一&#xff0c;什么是适配器二&#xff0c;栈与队列模拟实现三&#xff0c;优先级队列四&#xff0c;reverse_iterator 一&#xff0c;什么是适配器 适配器作为STL的六大组…

【高阶数据结构】跳表

文章目录 一、什么是跳表二、跳表的效率如何保证&#xff1f;三、skiplist的实现四、skiplist跟平衡搜索树和哈希表的对比 一、什么是跳表 skiplist本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是 一样的&#xff0c;可…

Windows环境Docker安装

目录 安装Docker Desktop的步骤 Docker Desktop 更新WSL WSL 的手动安装步骤 Windows PowerShell 拉取&#xff08;Pull&#xff09;镜像 查看已下载的镜像 输出"Hello Docker!" Docker Desktop是Docker官方提供的用于Windows的图形化桌面应用程序&#xff0c…

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测 目录 区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归多输入单输出区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 区间预测 | MATLAB实现QRBiLSTM…

odoo16 用好计量单位中的激活功能

odoo16 用好计量单位中的激活功能 根据国内常用&#xff0c;把不常用的单位去除&#xff0c;删除不了&#xff0c;提示已用&#xff0c;其实不用删除&#xff0c;每个单位后有个激活功能&#xff0c;选一下就可以了&#xff0c;显示成整洁的界面了 第一次用时&#xff0c;小伙伴…

解决spring cloud 中使用spring security全局异常处理器失效

写auth认证模块实现忘记密码与注册功能时&#xff0c;用异常抛出&#xff0c;全局异常处理器无法捕获。 无法进行异常捕捉 解决方案&#xff1a;使用WebSecurityConfigurerAdapter.configure中http实现自定义异常&#xff1a; EnableWebSecurity EnableGlobalMethodSecurity(…

87、springcloud核心组件及其作用

spring Eureka: 服务注册与发现 注册:&#xff1a;每个服务都向Eureka登记自己提供服务的元数据&#xff0c;包括服务的ip地址、端口号、版本号、通信协议等 eureka将各个服务维护在了一个服务清单中 (双层Map&#xff0c;第一层key是服务名&#xff0c;第二层key是实例名&…

macOS 源码编译 qpress

╰─➤ git clone https://github.com/PierreLvx/qpress.git ╰─➤ cd qpress ╰─➤ make g -O3 -o qpress -x c quicklz.c -x c qpress.cpp aio.cpp utilities.cpp -lpthread -Wall -Wextra -Werror ╰─➤ sudo make install …

Vue--》打造个性化医疗服务的医院预约系统(三)

今天开始使用 vue3 + ts 搭建一个医院预约系统的前台页面,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关…

Java基础小知识(待续)

类型转换、ASCII码、除法取余、三元表达式 long x 100;//int->long自动类型转换&#xff08;隐式) 1&#xff0e;特点:代码不需要进行特殊处理&#xff0c;自动完成。2&#xff0e;规则:数据范围从小到大。double y 2.5F;//2.5 float->double自动类型转换&#xff08…