组合式API

组合式API入口-setup

setup选项的写法和执行时间


写法

<script>
  export default {
    setup(){
      
    },
    beforeCreate(){
      
    }
  }
</script>

执行时间

image.png
由生命周期图得知,在组件进行渲染的时候会优先执行setup,它的执行时机是在beforeCreate之前并且是自动执行的。


示例

<script>
export default {
  setup() {
    console.log('setup')
  },
  beforeCreate() {
    console.log('beforeCreate')
  }
}
</script>

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

运行结果
image.png


setup选项中写代码的特点

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

<script>
  export default {
    setup() {
      // 数据
      const message = 'this is a message'
      // 函数
      const logMessage = () => {
        console.log(message)
      }
      // 以对象的形式返回数据和方法,模板中才能使用数据和函数
      return {
        message,
        logMessage
      }
    },
    beforeCreate() {
    }
  }
</script>

<template>
  <div>
    {{ message }}
    <button @click="logMessage">Log Message</button>
  </div>
</template>

image.png

setup语法糖

上面的原始写法过于复杂,每定义一次数据或函数都需要return一下,繁琐。而在script标签添加 setup标记,就不需要再写导出语句,默认会添加导出语句,简洁。

<script setup>
  const message = 'this is a message'
  const logMessage = ()=>{
    console.log(message)
  }
</script>


组合式API-reactive和ref函数

reactiveref函数共同作用是用函数调用的方式生成响应式数据。

reactive()

作用

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

核心步骤

  • vue包中导入reactive函数
  • <script setup>中执行reactive函数并传入类型为对象的初始值,并使用变量接收返回值
<script setup>
  // 导入
  import { reactive } from 'vue'
  // 执行函数 传入参数 变量接收
  const state = reactive({
    msg:'this is msg'
  })
  const setSate = ()=>{
    // 修改数据更新视图
    state.msg = 'this is new msg'
  }
</script>

<template>
  {{ state.msg }}
  <button @click="setState">change msg</button>
</template>


ref()

作用

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

核心步骤

  • 从vue包中导入ref函数
  • <script setup>中执行ref函数并传入初始值,使用变量接收ref函数的返回值
<script setup>
 // 导入
 import { ref } from 'vue'
 // 执行函数 传入参数 变量接收
 const count = ref(0)
 const setCount = ()=>{
   // 修改数据更新视图必须加上.value
   count.value++
 }
</script>

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

reactive 对比 ref

  • reactive不能处理简单类型的数据
  • ref参数类型支持更好,但是必须通过.value做访问修改
  • ref函数内部的实现依赖于reactive函数
  • 推荐使用ref函数,更加灵活


组合式API-computed计算属性函数

计算属性基本思想和Vue2保持一致,组合式API下的计算属性只是修改了API写法

核心步骤

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

// 原始数据
const list = ref([1,2,3,4,5,6,7,8])
  
// 2.执行函数return计算之后的值,用变量接收
const filterList = computed(() => {
  return list.value.filter(item=>item > 2)
})
</script>

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

注意

  • 计算属性中不应该有“副作用”,比如异步请求/修改dom
  • 避免直接修改计算属性的值,计算属性应该是只读的


组合式API-watch函数

作用

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

侦听单个数据

核心步骤

  • 导入watch函数
  • 执行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 侦听变化
  // 侦听多个数据,第一个参数可以改写成数组的写法
  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. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,旧值为${oldValue},新值为${newValue}`)
  },{
    immediate: true
  })
</script>

deep

说明

通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项,但是一旦开启deep便会进行递归遍历,造成性能损耗,尽量不开启deep

// 默认机制
<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ count: 0 })
  // 2. 监听对象state
  watch(state, ()=>{
    console.log('数据变化了')
  })
  const changeStateByCount = ()=>{
    // 直接修改不会引发回调执行
    state.value.count++
  }
</script>
// 开启deep选项
<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ count: 0 })
  // 2. 监听对象state 并开启deep
  watch(state, ()=>{
    console.log('数据变化了')
  },{deep:true})
  const changeStateByCount = ()=>{
    // 此时修改可以触发回调
    state.value.count++
  }
</script>

精确侦听对象的某个属性

需求

在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调函数

// 默认机制
<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ 
    name: 'zhangsan',
    age: 18
  })

  const changeName = () => {
    //修改name
    state.value.name = 'lisi'
  }
  
  const changeAge = () => {
    //修改age
    state.value.age = 20
  }
  
  // 2. 精确侦听某个具体属性
  watch(
    () => state.value.age, 
    ()=>{
    console.log('age变化了')
  })
  
</script>


组合式API-生命周期函数

选项式API和组合式API的对比

image.png


生命周期函数的基本使用

核心步骤

  • 导入生命周期函数
  • 执行生命周期函数,传入回调函数
<scirpt setup>
// 导入生命周期函数
import { onMounted } from 'vue'
// 执行生命周期函数,传入回调函数
onMounted(()=>{
  // 自定义逻辑
})
</script>

生命周期函数执行多次的时候,会按照顺序依次执行,故可以做到不动原有生命周期函数的逻辑,再补充新的逻辑。

<scirpt setup>
import { onMounted } from 'vue'
onMounted(()=>{
  // 自定义逻辑
})

onMounted(()=>{
  // 自定义逻辑
})
</script>


组合式API-父子通信

父传子

基本思想

  • 父组件中给子组件绑定属性
  • 子组件内部通过props选项接收
// 父组件
<script setup>
// 引入子组件,setup语法糖下局部组件无需注册导入后直接可以使用
import sonComVue from './son-com.vue'
// 响应式数据
const count = ref(100)
</script>

<template>
  <!-- 1.绑定属性 message -->
  <sonComVue :count="count" message="this is app message" />
</template>
// 子组件
<script setup>
// 2.通过definProps“编译器宏”接收子组件传递的数据
const props = definProps({
  message: String,
  count: Number
})
</script>

<template>
  {{ message }}
  {{ count }}
</template>

image.png



子传父

基本思想

  • 父组件中给子组件标签通过@绑定事件
  • 子组件内部通过$emit方法触发事件
// 父组件
<script setup>
// 引入子组件,setup语法糖下局部组件无需注册导入后直接可以使用
import sonComVue from './son-com.vue'
const getMessage = (msg) => {
  console.log(msg)
}
</script>

<template>
  <!-- 1.绑定自定义事件 -->
  <sonComVue @get-message="getMessage" />
</template>
// 子组件
<script setup>
// 2.通过definEmits“编译器宏”生成emit方法
const emit = defineEmits(['get-message'])

const sendMsg = () => {
  //3.触发自定义事件 并传递参数
  emit('get-message', 'this is son message')
}
</script>

<template>
  <button @click="sendMsg">发送信息</button>
</template>

image.png


组合式API模板引用

概念

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

实现步骤

  • 调用ref函数生成一个ref对象
  • 通过ref标识绑定ref对象到标签
<script setup>
  import { ref } from'vue'
  //1.调用ref函数得到ref对象
  const h1Ref = ref(null)
</script>

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


defineExpose

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

<script setup>
  import { ref } from'vue'
  const name = ref('test name')
  const setName = () => {
    name.value = 'test new name'
  }

  defineExpose({
    name,
    setName
  )}
</script>

<template>
  <div>我是test组件</div>
</template>


组合式API - provide和inject

作用和场景

顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信信image.png

跨层传递普通数据

实现步骤

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

image.png


跨层传递响应式数据

在调用provide函数时,第二个参数设置为ref对象
image.png


跨层传递方法

顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件的数据
image.png

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值