vue3的composition API高级语法

生命周期

【options API】中,生命周期钩子是被暴露在vue实例上的选项,我们只需要调用使用即可。

【composition API】中,我们需要将生命周期钩子导入项目,然后才能使用。

注意格式的变化

<script>
import { onMounted } from 'vue';
export default {
    setup(){
        onMounted(()=>{
            console.log("hello")
        })
    }
}
</script>

在这里,beforecreate和created被setup方法本身所替代,我们在在setup中将会访问到9个生命周期:

onBeforeMount:在挂载之前被调用,渲染函数render首次被调用

onMounted:组件挂载时调用

onBeforeUpdate:数据更新时调用,发生在虚拟DOM打补丁之前。

onUpdated:因数据更改导致的虚拟DOM重新渲染和打补丁时调用

onBeforeUnmount:在卸载组件实例之前调用,此阶段的实例依旧是正常的。

onActivated:被keep-alive缓存的组件激活时调用

onDeactivated:被keep-alive缓存的组件停用时调用

onErrorCaptured:当捕获一个来自子孙组件的错误时被调用,有三个参数:错误对象、发生错误的组件实例、一个包含错误来源信息的字符串;此钩子会返回false来阻止改错误继续向上传播

举例

<script>
import { onMounted } from 'vue';
export default {
    setup(){
        //立即执行函数
        (function() {
          console.log("立即执行")
        })();
        function hello(){
            console.log("hello")
        }
        onMounted(()=>{
            console.log("生命周期")
        })
       hello()
      
        return{
            hello
        }
    }

}
</script>

输出顺序:

因此setup内部定义的方法是在onmonuted之前执行的

立即执行函数:

立即执行函数(Immediately Invoked Function Expression,IIFE立即执行函数(Immediately Invoked Function Expression,IIFE)是一种在定义时立即执行的JavaScript函数。它使用匿名函数表达式(Function Expression)来封装一些代码,并且这段代码会在定义后立即执行。

IIFE的基本语法如下:

  (function() {
    // 在这里编写需要执行的代码
  })();

或者可以使用箭头函数语法:

(() => {
  // 在这里编写需要执行的代码
})();

IIFE的主要作用是创建一个新的作用域,避免变量污染全局作用域。它可以访问外部作用域中的变量,但无法修改它们。这使得IIFE非常适合用于模块化和封装JavaScript代码。

provide

vue3中的provide/inject(提供注入)

有了provide/inject不用一级一级传递,只要是父组件提供了某个数据,隔代组件就能直接获取都数据,从而很方便。

provide为后代提供数据

注意

在 3.x , provide 需要导入并在 setup 里启用,并且现在是一个全新的方法。
每次要 provide 一个数据的时候,就要单独调用一次。
每次调用的时候,都需要传入 2 个参数:

参数

类型

说明

key

string

数据的名称

value

any

数据的值

// 记得导入provide
import { defineComponent, provide } from 'vue'

export default defineComponent({
  // ...
  setup () {
    // 定义好数据
    const msg: string = 'Hello World!';

    // provide出去
    provide('msg', msg);
  }
})

inject的注入

注意

在 3.x, inject 和 provide 一样,也是需要先导入然后在 setup 里启用,也是一个全新的方法。
每次要 inject 一个数据的时候,就要单独调用一次。
每次调用的时候,只需要传入 1 个参数:

参数

类型

说明

key

string

与provide对应的数据名称

参数是注入名,也就是key

// 记得导入inject
import { defineComponent, inject } from 'vue'

export default defineComponent({
  // ...
  setup () {
    const msg: string = inject('msg') || '';
  }
})

如果提供的值是一个 ref,注入进来的会是该 ref 对象,不会自动解包为其内部的值,具有响应式

例子

子组件home用inject接收

<template>
  <h3>
{{ homemessage }}
  </h3>
</template>

<script>
import { inject } from 'vue';
export default {
setup(){
    const homemessage=inject("message")
    console.log(homemessage)
    return{
        homemessage
    }
}
}
</script>
<style>
</style>

父组件app用provide传递

<template>
  <home></home>
</template>
<script>
import { ref,provide } from 'vue';
import home from "./home.vue"
export default {
    components:{
        home
    },
    setup(){
        const mess = ref("hellomessage")
        provide("message",mess)
        return{
        mess
        }
    }
}
</script>

<style>

</style>

注意

一般情况下,传递给后代的数据不应该被后代组件改变,后代组件只能获取数据,不能改变数据

setup语法糖

如何使用 setup script 语法糖

需要启用 <script setup> 语法糖,需要在 <script> 代码块加上 setup 属性

也就是说 : 只需在 script 标签上写上 setup 就可以了

<script setup>
	console.log('hello script setup')
</script>

里面的代码会被编译成组件 setup() 函数当中的内容

<script setup> 和 <script> 的执行时机是不同的:

普通的 <script> 只会在组件第一次被引入的时候执行一次

而 <script setup> 中的代码会在每次组件实例被创建的时候执行

好处:

1.不需要return返回了

当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的内容) 都能在模板中直接使用

2、响应式

ref响应式数据和从 setup() 函数中返回值一样,值在模板中使用的时候会自动解包,不需要用xxx.value取值。

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

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

</style>
3、自动注册

我们引入组件之后,就不需要在components选项中注册它了,直接就能在模板中使用了。被引入时的变量名直接作为自定义组件的标签名使用。当然了,引入方法,变量也是一样的,直接就能在template里用了。

<template>
  <subassembly @getChili="getChili" :title="msg" />
</template>
 
<script setup>
import {ref} from 'vue'
 
//这里我们引入了子组件 subassembly
import subassembly from './subassembly.vue'
</script>

组件通信

注意:defineProps,defineEmits,defineExpose这三个api都是可以直接在 <script setup>里使用的,不需要引入。

defineProps :代替props,接收父组件传递的数据(父组件向子组件传参)
父组件
<template>
    <div>我是父组件----1</div>
    <chil @getChili="getChili" :title="msg" />
  </template>
   
  <script setup>
  import {ref} from 'vue'
  import chil from "./chil.vue"
   
  //把值传递给子组件 ---> :title="msg"  <Home @getChili="getChili" :title="msg" />
  
  const msg = ref('父的值')
   
  </script>
  
子组件
<template>
    <div>我是子组件----2</div>
    <div style="color: red">{{props.title}}</div>
  </template>
   
  <script setup>
  import {defineProps} from 'vue'
   
  //接收父组件 传过来的值!
  const  props = defineProps({
    title: {
      type: String
    }
  });
   
  //打印一下 接收父组件的值
  console.log(props.title) //父的值
  </script>

defineEmit 代替emit,子组件向父组件传递数据(子组件向外暴露数据)
父组件
<template>
    <div>我是父组件----1</div>
    <div>{{data}}</div>
    <chil @getChili="getChili" :title="msg" />
  </template>
   
  <script setup>
  import {ref} from 'vue'
	import chil from "./chil.vue"
   
  //空值接收 子组件的传值
  let data = ref(null)
  const getChili = (e) => {
    data.value = e
    console.log(e)  //子组件的值
  }
   
  </script>
子组件
<template>
    <hr>
    <div>我是子组件----2</div>
    <button @click="toEmits">点击传到父组件</button>
  </template>
   
  <script setup>
  import {defineEmits,ref} from 'vue'
   
   
  //先定义一下子 在发送值
  const  emits = defineEmits(['getChili']);
   
  const  toEmits = () => {
    emits('getChili','子的值')
  }
   
  </script>
defineExpose :子组件暴露自身数据,(父组件获取子组件属性)

在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在script-setup模式下,所有数据只是默认return给template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载ref 变量获取子组件的数据。

如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由defineExpose来完成。

defineExpose是vue3新增的一个api,放在<scipt setup>下使用的,目的是把属性和方法暴露出去,可以用于父子组件通信,子组件把属性暴露出去, 父组件用ref获取子组件DOM,子组件暴露的方法或属性可以用dom获取。

父组件

父组件用ref获取子组件dom拿到暴露的属性

shield.value.xiaoZhi拿到子组件暴露的属性

<template>
    <button @click="shiEmots">获取暴露</button>
    <chil ref="shield"/>
  </template>
  <script setup>
  import chil from "./chil.vue"
  import {defineEmits,defineProps,ref} from 'vue'
   
  const shield = ref()
   
  const  shiEmots = () =>{
    //子组件接收暴露出来得值
    console.log('接收reactive暴漏出来的值',shield.value.xiaoZhi)
    console.log('接收ref暴漏出来的值',shield.value.xiaoXiaoZhi)
  }
  </script>
子组件

子组件使用defineExpose把那个变量暴露出去

<template>
    <div>我是子组件....{{ xiaoZhi.stator }}</div>
  </template>
   
  <script setup>
  import {ref, defineExpose, reactive} from 'vue'
   
  let xiaoZhi = reactive({
    stator: '小志',
    age: 27
  })
   
  let xiaoXiaoZhi = ref('小小志');
  console.log(xiaoXiaoZhi)
   
  defineExpose({
    xiaoZhi,
    xiaoXiaoZhi
  })
  </script>

这里的ref是Vue.js中的一个函数,用于创建一个响应式的引用。在这个例子中,shield是一个响应式的引用,它指向了子组件chil的实例。当子组件的属性发生变化时,shield的值也会相应地更新。

在模板中,通过ref="shield"将shield与子组件关联起来。这样,在shiEmots方法中,可以通过shield.value访问到子组件的属性和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值