首页 > 其他分享 >组合式API

组合式API

时间:2023-08-02 18:59:16浏览次数:31  
标签:组合式 count vue const watch API 组件 ref

setup

setup选项的写法与执行时机



setup函数代码示例

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    // 返回值会暴露给模板和其他的选项式 API 钩子
    return {
      count
    }
  },

  mounted() {
    console.log(this.count) // 0
  }
}
</script>

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

在模板中访问从 setup 返回的 ref 时,它会自动浅层解包,因此你无须再在模板中为它写 .value。当通过 this 访问时也会同样如此解包。

setup语法糖

对于结合单文件组件使用的组合式 API,推荐通过 <script setup> 以获得更加简洁及符合人体工程学的语法。
通过setup语法糖可以简化我们写的代码,对上面的代码我们可以简化为

<script setup>
import { ref } from 'vue'
const count = ref(0);
mounted() {
    console.log(this.count) // 0
  }
</script>

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

总结

  1. setup选项的执行时机

beforeCreate钩子之前 自动执行

  1. setup写代码的特点是什么

定义数据+函数 然后以对象方式return

  1. <script setup>解决了什么问题

经过语法糖的封装更简单的使用组合式API

  1. setup中的this还指向组件实例吗

setup() 自身并不含对组件实例的访问权,即在 setup() 中访问 this 会是 undefined。你可以在选项式 API 中访问组合式 API 暴露的值,但反过来则不行

reactive和ref函数

reactive()

作用: 接受对象类型数据的参数传入并返回一个响应式的对象
核心步骤:

<script setup>
    // 导入
    import {reactive} from 'vue'

    // 执行函数 传入参数 变量接收
    const state = reactive(对象类型数据)
</script>
  1. 从vue包中导入reactive函数
  2. 在<script setup>中执行reactive函数并传入类型为对象的初始值,并使用变量接收返回值

ref()

作用: 接受简单类型或者对象类型的数据传入并返回一个响应式的对象
核心步骤:

<script setup>
    // 导入
    import {ref} from 'vue'

    // 执行函数 传入参数 变量接收
    const count = reactive(简单类型或者复杂类型数据)
</script>

ref实现简单计数器示例代码:

<script setup>
    // 导入ref函数
    import {ref} from 'vue'

    // 执行函数 传入参数[简单类型 + 对象类型] 变量接收
    const count = ref(0)

    const setCount = () =>{
        // 脚本区域修改ref产生的响应式对象数据 必须通过.value属性
        count.value++
    }
</script>

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

在模板中访问从 setup 返回的 ref 时,它会自动浅层解包,因此你无须再在模板中为它写 .value。当通过 this 访问时也会同样如此解包。

总结

  1. reactive和ref函数的共同作用是什么?

用函数调用的方式生成响应式数据

  1. reactive vs ref ?

[1]reactive不能处理简单类型的数据 [2]ref参数类型支持更好但是必须通过.value访问修改 [3]ref函数的内部实现依赖于reactive函数

  1. 在实际工作中推荐使用哪个 ?

推荐使用ref函数,更加灵活

computed

computed计算属性是Vue.js中一种特殊的实例属性,可以根据其他实例属性的值的变化而变化。 它可以被用来存储和计算一些复杂的值,而不必每次都去重新计算它们,这样可以提高应用的性能。

核心步骤

  1. 导入computed函数
  2. 执行函数在回调参数中return基于响应式数据做计算的值,用变量接收
<script setup>
    // 导入
    import {computed} from 'vue'

    // 执行函数 变量接收 在回调参数中return计算值
    const computedState = computed(()=>{
        return 基于响应式数据做计算之后的值
    })
</script>

过滤数组中小于等于2的元素得到新数组代码示例如下:

<script setup>
    // 导入computed
    import {ref, computed} from 'vue'
    // 原始响应式数组
    const list = ref([1, 2, 3, 4, 5, 6, 7, 8])
    // 执行函数 return计算之后的值 变量接收
    const computedList = computed(() => {
        return list.value.filter(item => item>2)
    })
</script>

<template>
  <div>
    原始响应式数组-{{list}}
  </div>
  <div>
  计算属性数组-{{computedList}}
  </div>
</template>

总结

  1. 计算属性不应该有“副作用”

计算属性API的主要作用是为了计算,除了计算外的其他逻辑不应该出现在计算属性函数中,如异步请求/修改dom等。

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

计算属性应该是只读的

watch

watch函数的作用是侦听一个或者多个数据的变化,数据变化时立即执行回调函数
两个额外参数: 1.immediate(立即执行) 2.deep(深度侦听)

基础使用 - 侦听单个数据

  1. 导入watch函数
  2. 执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
<script setup>
    // 1. 导入watch
    import {ref, watch} from 'vue'
    const count = ref(0)

    // 2. 调用watch 侦听变化
    watch(count, (newValue, oldValue) => {
        console.log('count发生了变化,老值为${oldValue}, 新值为${newValue}')
    })
</script>

基础使用 - 侦听多个数据

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

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

    // 2. 侦听多个数据源
    watch(
        [count, name],
        ([newCount, newName], [oldCount, oldName]) =>{
            console.log('count或者name变化了',[newCount, newName], [oldCount, oldName])
        }
    )
</script>

immediate(立即执行)

说明: 在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调
代码示例如下:

<script setup>
    // 1. 导入watch
    import {ref, watch} from 'vue'
    const count = ref(0)

    // 2. TODO: watch立即执行
    watch(count, (newValue, oldValue) => {
        console.log('count发生了变化,老值为${oldValue}, 新值为${newValue}')
    },{
        immediate: true
    })
</script>

deep(深度侦听)

默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项

<script setup>
    // 1. 导入watch
    import {ref, watch} from 'vue'
    const state = ref({ count: 0 })
    // TODO: watch深度监听
    watch(state, () => {
        console.log('数据变化了')
    }, {
        deep: true
    })

    const changeStateByCount = () => {
        // 直接修改属性 -> 不会触发回调
        state.value.count++
    }
</script>

<template>
  <div>
    {{ state.count }}
    <button @click="changeStateByCount">通过count修改</button>
  </div>
</template>

精确侦听对象的某个属性

需求:下列对象中,在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调

const info = ref({
    name: 'cp',
    age: 18
    })

精确侦听的代码如下:

<script setup>
    //  导入watch
    import {ref, watch} from 'vue'
        const state = ref({
        name: 'cp',
        age: 18
    })

    const chageName = () => {
        // 修改name
        state.value.name = 'chaichai-teacher'
    }
    const chageAge = () => {
        // 修改age
        state.value.age = 20
    }
    // TODO: 精确侦听某个具体属性
    watch(
        () => info.value.age,
        () => console.log('age发生变化了')
    )

    // deep性能损耗 尽量不开启deep
</script>

<template>
  <div>
    <div>当前name -- {{state.name}}</div>
    <div>当前age -- {{state.age}}</div>
    <div>
      <button @click="chageName"> 修改name </button>
      <button @click="chageAge">  修改age </button>
    </div>
  </div>
</template>

总结

  1. 作为watch函数的第一个参数,ref对象需要添加.value吗?

不需要,watch会自动读取

  1. watch只能侦听单个数据吗?

单个或多个

  1. 不开启deep,直接修改嵌套属性能触发回调吗?

不能,默认是浅层侦听

  1. 不开启deep,想在某个层次比较深的属性变化时执行回调怎么做?

可以使用精确侦听,把第一个参数写成函数的写法,返回要监听的具体属性

生命周期函数

生命周期API(选项式 VS 组合式)


生命周期函数是可以执行多次的,多次执行时传入的回调会在时机成熟时按照注册的顺序依次执行。

<script setup>
    onMounted(() => {
        console.log('mount1')
    });
    onMounted(() => {
        console.log('mount2')
    });
</script>

父子通信

组合式API下的父传子

基本思想

  1. 父组件给子组件绑定属性
  2. 子组件内部通过props选项接收
<script setup>
    // 引入子组件
    import sonComVue from './son-com.vue'
    const count = ref(100)
    setTimeout(() =>{
      count.value = 200
    }, 300)
</script>

<template>
  <div class="father">
    <h2>父组件</h2>
    <!-- 1. 绑定属性 message -->
  <sonComVue message="this is app message" :count="count">
  </div>
</template>

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

<template>
  <div class="son">
    <h3>子组件</h3>
    <div>
      父组件传入的数据 - {{ message }} - {{ count }}
    </div>
  </div>
</template>

组合式API下的子传父

基本思想

  1. 父组件中给子组件标签通过@绑定事件
  2. 子组件内部通过$emit方法触发事件
<script setup>
  import SonCom from './son-com.vue'
  const getMessage = (msg) =>{
    console.log(msg)
  }
</script>

<template>
  <div class="father">
    <h3>父组件App</h3>
    <!-- 绑定事件 -->
    <SonCom @get-message="getMessage" />
  </div>
</template>
<script setup>
  // 2.通过defineEmits()-> emit(this.$emit)
  const emit defineEmits(['get-message'])
  const sendMsg = () => {
    // TODO 触发自定义事件 传数据给父组件
    emit('get-message', 'this is son message')
  }
</script>

<template>
  <div class="son">
    <h3>子组件Son</h3>
    <button @click="sendMsg">触发自定义事件</button>
  </div>
</template>

模板引用

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

如何使用(以获取dom为例 组件同理)

  1. 调用ref函数生成一个ref对象
  2. 通过ref标识绑定ref对象到标签
<script setup>
  import {onMounted, ref } from 'vue'

  // 1. 调用ref函数 -> ref对象
  const h1Ref = ref(null)

  // 组件挂载完毕之后才能获取
  onMounted(() => {
    console.log(h1Ref.value)
  })
</script>

<template>
  <div class="son">
    <h3>子组件Son</h3>
    <button @click="sendMsg">触发自定义事件</button>
  </div>
</template>

标签:组合式,count,vue,const,watch,API,组件,ref
From: https://www.cnblogs.com/bfyzzk/p/17596131.html

相关文章

  • YApi怎么测试接口: 最佳实践
    接口测试为什么要接口测试?你想想,你们后端团队写了几百个接口,兴高采烈地,直接部署上线,你们开开心心下班去。等到晚上的时候,你发现你们的接口好几个都崩了,这导致了你们产品损失了一大批用户,那个时候你会后悔,后悔啥呢?后悔接口写完后,没有进行 接口测试 。要怎么测试?其实现在市面上已经......
  • 怎样在Apipost中设计出实用又好看的API文档
    Apipost一直推荐文档先行的API设计理念,在Apipost中可以添加Markdown格式的文本,用以储备文档和API文档设计。作为一种轻量级标记语言,Markdown在撰写文档、博客文章、README文件以及网站内容上被广泛使用。如何在Apipost中设计出漂亮的文档?Apipost近期发布的7.1.9版本更新中,Apipos......
  • WebApi接口的调用和传参
    publicCommon.mdlResultModel<mdlGetHistoryData>GetHistoryDataByCondition(intpDeviceId,intpPageIndex,intpPageSize,stringpStartTime,stringpEndTime)       {           Common.mdlResultModel<mdlGetHistoryData>objResult=newCommon.m......
  • 多语言演示API接口对接电商平台,优惠券查询源代码演示示例
     优惠券查询API接口的重要性可以从以下几个方面来说明:优惠券信息获取:优惠券查询API接口可以提供用户和开发者获取优惠券的详细信息,包括优惠券名称、类型、面值、使用规则、有效期等。这些信息对于用户来说非常重要,可以帮助他们选择适合自己的优惠券,并充分利用优惠券的优惠力度。优......
  • Asp.net Web Api .net6如何解决跨域的问题
    在Program.cs中添加如下代码//配置跨域builder.Services.AddCors(cor=>{varcors=builder.Configuration.GetSection("CorsUrls").GetChildren().Select(p=>p.Value);cor.AddPolicy("Cors",policy=>{policy.WithOrigins(c......
  • 处理API请求并行问题
    背景:我们有一个导出全部数据的功能,因为各种原因,可能需要同时发送10几条请求来获取数据遇到的问题:因为浏览器http/1.1最多同时进行6个请求,所以会阻塞用户的其他操作打个比喻:之前我们是一个赛道,可以上6个任意国家的运动员,第七个人想上去就得排队现在改为了两个赛......
  • .Net Web API 004 Controller获取对象列表,传入数据以及对象
    1、返回UserEntityList这个服务接口的目的是分为用户列表,代码如下所示。///<summary>///得到用户列表///</summary>///<returns></returns>[HttpGet][Route("GetUserList")]publicActionResult<List<UserEntity>>GetUserList(){varmyUse......
  • rest-apiV2.0.0升级为simplest-api开源框架生态之simplest-jpa发布
    什么是simplestsimplest追求存粹简单和极致。旨在为项目快速开发提供一系列的基础能力,方便用户根据项目需求快速进行功能拓展不在去关心一些繁琐。重复工作,而是把重点聚焦到业务。前言程序10年。作为一个多年程序。深知每个项目和程序,都有很多重复性工作要做。入行近10......
  • 台积电迎新劲敌,Rapidus横空杀出欲抢2纳米客户 | 百能云芯
    8月2日消息,据台媒报道,台积电2纳米制程劲敌不只大家熟知的三星、英特尔,后面还有追兵,日本芯片国家队Rapidus也计划于2027年量产2纳米芯片,抢台积电客户。值得关注的是,英特尔上周财报会议上也放话,2025年用2纳米、1.8纳米从台积电手中拿回制程技术龙头地位,分析师透露,台积电内部相当紧张......
  • 干掉 CRUD!这个API开发神器效率爆炸,无需定义MVC类!!
    简介magic-api能够只通过UI界面就能完成简单常用的接口开发,能够支持市面上多数的关系性数据库,甚至还支持非关系性数据库MongoDB。通过 magic-api 提供的UI界面完成接口的开发,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象和相关文......