Cycle de vie de la composition-api et de la configuration de Vue3

1. Une brève introduction à la configuration

La configuration est la fonction d'entrée dans l'API Composition et est également la première fonction à être utilisée. L'installation n'est exécutée qu'une seule fois lors de l'initialisation et toutes les fonctions de l'API Composition sont utilisées ici. L'organisation du code de l'API Composition est très flexible et tout le code peut être écrit directement dans la configuration (pour faire simple, cela signifie que les données, les méthodes et les calculs dans vue2 sont tous omis et que toutes les méthodes de données sont écrites dans le configuration )
Insérer la description de l'image ici

On peut en déduire que lorsque l'installation est exécutée, l'objet composant n'a pas encore été créé et l'objet instance de composant n'est pas encore disponible. Pour le moment, cela n'est pas défini et les données/calculés/méthodes/props ne sont pas accessibles via ce.

1. setup函数执行于beforeCreate和created之前,也就是说setup函数里面无法使用data和methods方法中的数据
2. setup 有2个参数
    props 的父组件传递过来的参数
    ctx 上下文对象
        ctx.attrs
        ctx.slots
        ctx.parent
        ctx.root
        ctx.emit
        ctx.refs
3.在 setup() 函数中无法访问到 this
4. 在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用

2.Configurer le composant de fichier unique de balise

Est un sucre syntaxique au moment de la compilation pour utiliser l'API de composition dans un composant de fichier unique (SFC). par rapport à l'ordinaire

  • Moins de passe-partout, un code plus propre.
  • Possibilité de déclarer des accessoires et de lancer des événements en utilisant du TypeScript pur.
  • Meilleures performances d'exécution (son modèle sera compilé dans une fonction de rendu dans le même périmètre que lui, sans aucun proxy intermédiaire).
  • Meilleures performances d'inférence de type IDE (moins de travail pour le serveur de langage pour extraire les types du code)

grammaire de base

<script setup name="Dict">
	1. name 表示组件的名称
	2. setup 放在script 上时,声明 变量,函数声明,以及 import 引入的内容,都能在模板中直接使用,不用rerun 
	3. 访问props 使用defineProps
 	const props = defineProps({
    
    
	    //子组件接收父组件传递过来的值
	    info:{
    
    
	        type: Object
	    }
	})
	4. ctx.emit 触发事件=》defineEmits(['selected']) // defineEmits子组件向父组件事件传递值
	5. ctx.expose 暴露公共 函数 =》defineExpose({
    
    函数名称});
	6. useSlots 和 useAttrs:与 setupContext.slots 和 setupContext.attrs 等价的值
	import {
    
     useSlots, useAttrs } from 'vue'
	const slots = useSlots()
	const attrs = useAttrs()
	7. 状态驱动的动态 CSS【(<style> 中的 v-bind)】
	const theme = {
    
    
  		color: 'red'
	}
	<style scoped>
		p {
    
    
		  color: v-bind('theme.color');
		}
	</style>
	8. 更新dom后操作nextTick(()=>{
    
     //执行代码})
	9. a
</script>

composants dynamiques

 动态组件:由于组件被引用为变量而不是作为字符串键来注册的,在 <script setup> 中要使用动态组件的时候,就应该使用动态的 :is 来绑定:
	<template>
 		 <component :is="Foo" />
  		<component :is="someCondition ? Foo : Bar" />
	</template>
	<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>

composants récursifs

Un composant monofichier peut être référencé par lui-même via son nom de fichier. Par exemple : un composant nommé FooBar.vue peut se référencer dans son modèle.
Veuillez noter que les composants importés de cette manière ont une priorité inférieure à l'importation. Si une importation nommée entre en conflit avec le nom déduit du composant, vous pouvez utiliser l'alias d'importation :
import { FooBar as FooBarChild } from './components'

Composants d'espace de noms

Vous pouvez utiliser des balises de composant en pointillés, telles que <Foo.Bar>, pour référencer des composants imbriqués dans les propriétés de l'objet. Ceci est utile lorsque vous devez importer plusieurs composants à partir d'un seul fichier :

<script setup>
import * as Form from './form-components'
</script>

<template>
  <Form.Input>
    <Form.Label>label</Form.Label>
  </Form.Input>
</template>

Utiliser des directives personnalisées

Les directives personnalisées enregistrées globalement fonctionneront comme prévu, et les directives enregistrées localement peuvent être utilisées directement dans les modèles, tout comme les composants mentionnés ci-dessus.

Mais il y a une limitation à noter : les directives personnalisées locales doivent être nommées sous la forme vNameOfDirective afin de pouvoir être utilisées directement dans le modèle.

<script setup>
const vMyDirective = {
    
    
  beforeMount: (el) => {
    
    
    // 在元素上做些操作
  }
}
</script>
<template>
  <h1 v-my-directive>This is a Heading</h1>
</template>
或是
<script setup>
  // 导入的指令同样能够工作,并且能够通过重命名来使其符合命名规范
  import {
    
     myDirective as vMyDirective } from './MyDirective.js'
</script>

attente de haut niveau

<script setup> 中可以使用顶层 await。结果代码会被编译成 async setup()<script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>
注意:
async setup() 必须与 Suspense 组合使用,Suspense 目前还是处于实验阶段的特性。我们打算在将来的某个发布版本中开发完成并提供文档 - 如果你现在感兴趣,可以参照 tests 看它是如何工作的

Veuillez faire attention à la version vue3 lors de son utilisation. Elle est prise en charge à partir de la 3.2 et est plus concise. Les variables et méthodes définies n'ont pas besoin d'être renvoyées et peuvent être utilisées dans des modèles.

API .Composition

Un ensemble d'API fonctionnelles peu intrusives qui nous permettent de « combiner » la logique des composants de manière plus flexible .
L'API de composition est inspirée de React Hooks et est plus puissante que les mixins. Elle peut améliorer la réutilisabilité de la logique du code, obtenant ainsi une indépendance par rapport aux modèles ; en même temps, la programmation fonctionnelle rend le code plus compressible.

Qu'est-ce qu'une API composable ?

Insérer la description de l'image ici
Problèmes avec l'API basée sur les objets (vue2)

  1. Peu propice à la réutilisation
  2. conflit de nom potentiel
  3. contexte perdu
  4. Prise en charge des types limités
  5. Organiser les fonctionnalités fournies par les API combinées par type d'API
  6. Extrêmement simple à réutiliser (fonction js native)
  7. Combinaison flexible (les crochets de cycle de vie peuvent être utilisés plusieurs fois)
  8. Fournir une meilleure prise en charge du contexte
  9. Meilleure prise en charge du type typeScipt
    5. Organisé par fonction/logique

Données réactives

Dans la version Vue2.x, il suffit de définir une donnée dans data() pour la transformer en données réactives. Dans Vue3.0, nous devons utiliser la fonction réactive ou ref pour créer des données réactives.

1. 简单数据类型(String、Number, bool 等)推荐使⽤ref
引入 import {
    
    ref} from 'vue'
使用: let num = ref(1)
获取/修改值:num.value
2. 复杂数据类型(Array、Object)推荐使⽤reactive
 import {
    
    reactive} from 'vue'
 let arr = reactive({
    
    age:1}) 传⼊⼀个对象,vue会封装成Proxy对象,使⽤⾥⾯的⽅法实现响应式数据
 直接修改数据: arr.age = 12

Remarque : Si vous n'avez pas besoin de créer des données réactives, déclarez simplement les variables directement. Par exemple, les données obtenues depuis l'interface,

réf introduction

Introduction à ref et réactif, il est recommandé d'utiliser ref

Insérer la description de l'image ici

Lorsque ref est automatiquement décompressé, il n'est pas nécessaire d'utiliser .value

Insérer la description de l'image ici

unref - l'opération inverse de Ref

Si une référence est transmise, sa valeur est renvoyée, sinon elle est renvoyée
Insérer la description de l'image ici
inchangée. Les deux peuvent être bien utilisés ensemble.
MaybeRef peut bien fonctionner avec ref et unref.

Accepter la référence comme paramètre de fonction

Insérer la description de l'image ici

Jugement des données réactives

isRef : Vérifie si une valeur est un objet de référence
isReactive : Vérifie si un objet est un proxy réactif créé par réactif
isReadonly : Vérifie si un objet est un proxy en lecture seule créé par readonly
isProxy : Vérifie si un objet est créé par réactif ou en lecture seule méthode Proxy créé

propriétés calculées calculées

Computed() est utilisé pour créer des propriétés calculées et la valeur de retour est une instance ref()

calculé crée une propriété calculée en lecture seule

En passant une fonction à Computed(), vous pouvez obtenir une propriété calculée en lecture seule :

const count = ref(1)

// 创建一个计算属性,使其值比 count 大 1
const bigCount = computed(() => count.value + 1)

console.log(bigCount.value) // 输出 2
bigCount.value++ // error 不可写

calculé crée des propriétés calculées lisibles et inscriptibles

onst count = ref(1)

// 创建一个 computed 计算属性,传入一个对象
const bigCount = computed({
    
    
    // 取值函数
    get: () => (count.value + 1),
    // 赋值函数
    set: val => {
    
    
      count.value = val - 1
    }
})

// 给计算属性赋值的操作,会触发 set 函数
bigCount.value = 9
// 触发 set 函数后,count 的值会被更新
console.log(count.value) // 8

lecture seulement()

Transmettez un objet réactif, un objet ordinaire ou une référence, et renvoyez un proxy d'objet en lecture seule. Ce proxy est profond et les données contenues dans l'objet sont également en lecture seule.

const state = reactive({
    
     count: 0 })

const copy = readonly(state)

watchEffect(() => {
    
    
  // 依赖追踪
  console.log(copy.count)
})

// state 上的修改会触发 copy 上的侦听
state.count++

// 这里只读属性不能被修改
copy.count++ // warning!

watchEffet()

watchEffect() exécute immédiatement la fonction passée, écoute de manière réactive ses dépendances et réexécute la fonction lorsque ses dépendances changent.

Utilisation de base

const count = ref(0)

// 初次直接执行,打印出 0
watchEffect(() => console.log(count.value))

setTimeout(() => {
    
    
  // 被侦听的数据发生变化,触发函数打印出 1
  count.value++
}, 1000)

Arrêtez d'écouter

watchEffect() renvoie une fonction lorsqu'elle est utilisée. Lorsque la fonction renvoyée est exécutée, l'écoute s'arrêtera.

const stop = watchEffect(() => {
    
    
  /* ... */
})

// 停止侦听
stop()

montre()

Watch dans composition-api est le même que dans Vue2.x. Watch doit écouter les données et exécuter son rappel d'écoute. Par défaut, le premier rendu n'est pas effectué.

La différence entre montre et watchEffect

  • regarder le rendu initial n'est pas exécuté
  • la montre écoute plus spécifiquement
  • la montre peut accéder aux valeurs avant et après avoir écouté les changements de données

la montre écoute une seule source de données

Les données écoutées peuvent être des données réactives créées par réactif (fonction getter avec valeur de retour), ou il peut s'agir d'une référence

Une seule montre reçoit trois attributs
  • Paramètre 1 : un objet réactif, tel qu'un objet réactif
  • Paramètre 2 : La fonction de rappel concernant les modifications des propriétés internes de l'objet, avec deux paramètres formels : ancien et nouveau.
  • Paramètre 3 : Contrôle des attributs de surveillance, profond signifie une surveillance approfondie, immédiat signifie démarrer la surveillance dès le lancement de la page.
<script setup >
let message = reactive({
    
    
    name: 'helloworld'
})
watch(message, (newVal, oldVal) => {
    
    
    console.log(newVal);
    console.log(oldVal);
}, {
    
    
    deep: true,
    immediate: true
})
</script>

la montre écoute plusieurs sources de données

Lors de l'écoute de plusieurs sources de données, donnez les paramètres à surveiller sous la forme d'un tableau. Lorsqu'il y a plusieurs propriétés dans l'objet d'écoute, le paramètre un peut être écrit sous la forme d'une fonction fléchée pour spécifier le nom de la propriété souhaitée. à surveiller ; sinon, si vous le faites, alors tout sera surveillé.

 const loginForm = reactive({
    
    
    username: '',
    password: '',
  });
  const num = ref(0);
  // loginForm的每个值变化或num变化都会触发watch
  watch([loginForm, num], (val) => {
    
    
    console.log(val); // val[0]的数据是loginForm的数据,val[1]是num的数据
  });
  // loginForm.username值变化或num变化都会触发watch
    watch([() => loginForm.username, num], (val) => {
    
    
    console.log(val); // val[0]的是loginForm.username数据,val[1]是num的数据
  });

4. Outils dépendants de Composition-Api

 1. toRef():当我们在模板中渲染数据时,不希望由前缀的时候可以使用组合-toRef()
 toRef()是函数,转换响应式对象中某个属性为单独响应式数据,并且值是关联的
 	//  数据响应式:
    const obj = reactive({
    
    
      msg: 'hello',
      info: 'hi'
    })
    const msg = toRef(obj, 'msg')
    const info = toRef(obj, 'info')
    const hClick = () => {
    
    
      msg.value = 'nihao'
      info.value= 'hihi'
    }
  可以直接访问: msg, info
2. toRefs():toRefs函数可以定义转换响应式中所有属性为 响应式数据,通常用于结构reactive定义的对象,转换响应式对象中所有属性(也可以是一部分)为单独响应式数据,对象成为普通对象,并且值是关联的
const {
    
     msg, info } = toRefs(obj);

5. Cycle de vie

Les fonctions de cycle de vie sont : onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmount, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated.
Différent de vue2, vue3 ajoute un on basé sur le nom du cycle de vie de vue2 .

script>
import {
    
    
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onRenderTracked,
  onRenderTriggered,
} from "vue";
export default {
    
    
  components: {
    
    },
  data() {
    
    
    return {
    
    };
  },
  setup() {
    
    
    // setup里面存着两个生命周期创建前创建
    // beforeCreate
    // created
    onBeforeMount(() => {
    
    
      console.log("onBefore   ====>  vue2.0 x beforemount");
    });
    onMounted(() => {
    
    
      console.log("onMounted  ====>  vue2.0 x mount");
    });
    onBeforeUpdate(() => {
    
    
      console.log("onBeforeUpdate  ====>  vue2.0 x beforeUpdate");
    });
    onUpdated(() => {
    
    
      console.log("onUpdated  ====>  vue2.0 x update");
    });
    onBeforeUnmount(() => {
    
    
      //在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。
      console.log("onBeforeUnmount ====>  vue2.0 x beforeDestroy");
    });
    onUnmounted(() => {
    
    
      //卸载组件实例后调用,调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。
      console.log("onUnmounted ====>  vue2.0 x destroyed");
    });
    // 新增两个生命周期函数
    //每次渲染后重新收集响应式依赖
    onRenderTracked(({
    
     key, target, type }) => {
    
    
      // 跟踪虚拟DOM重新渲染时调用,钩子接收debugger event作为参数,此事件告诉你哪个操作跟踪了组件以及该操作的目标对象和键。
      // type:set/get操作
      // key:追踪的键
      // target:重新渲染后的键
      console.log("onRenderTracked");
    });
    //每次触发页面重新渲染时自动执行
    onRenderTriggered(({
    
     key, target, type }) => {
    
    
      //当虚拟DOM重新渲染被触发时调用,和renderTracked类似,接收debugger event作为参数,
      // 此事件告诉你是什么操作触发了重新渲染,以及该操作的目标对象和键
      console.log("onRenderTriggered");
    });
    return {
    
    };
  },
};
</script>

Par rapport à l'exécution du cycle de vie dans setup et à la fonction de cycle de vie externe, il pointera d'abord vers la fonction de cycle de vie dans setUp, puis exécutera la fonction de cycle de vie externe.

Cycle de vie des composants parent-enfant

Composant parent :

<template>
<div class="container">
 父组件-->{
    
    {
    
    msg}}
 //子组件
<ChildItem :msg="msg" :msg1="msg1"></ChildItem>
</div>
</template>


<script lang="ts">
import {
    
     defineComponent,ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated } from 'vue'
import ChildItem from './components/base/Child.vue'
export default defineComponent({
    
    
  name: 'App',
  components: {
    
    
    ChildItem

  },
  beforeCreate () {
    
    
    console.log('父beforeCreate')
  },
  created () {
    
    
    console.log('父created')
  },
  setup () {
    
    
    console.log('父setup')
    onBeforeMount(() => {
    
    
      console.log('父onBeforeMount')
    })
    onMounted(() => {
    
    
    //更新数据
    setTimeout(() => {
    
    
        msg.value = 'hello,1s后修改msg'
        console.log('msg 被修改')
      }, 1000)
      console.log('父onMounted')
    })
    onBeforeUpdate(() => {
    
    
      console.log('父onBeforeUpdate')
    })
    onUpdated(() => {
    
    
      console.log('父onUpdated')
    })
  }
})
</script>

Enfant.vue

<template>
  <div>子组件-->{
    
    {
    
    msg}}</div>

</template>

<script lang="ts">
import {
    
     defineComponent, onBeforeMount, onMounted, onBeforeUpdate, onUpdated } from 'vue'

export default defineComponent({
    
    
  name: 'ChildItem',
  props: {
    
    
    msg: {
    
    
      type: String,
      required: true
    }
  },
  beforeCreate () {
    
    
    console.log('子beforeCreate')
  },
  created () {
    
    
    console.log('子created')
  },
  setup (props, {
    
     attrs, slots, emit }) {
    
    
    console.log('子setup')
    onBeforeMount(() => {
    
    
      console.log('子onBeforeMount')
    })
    onMounted(() => {
    
    
      console.log('子onMounted')
    })
    onBeforeUpdate(() => {
    
    
      console.log('子onBeforeUpdate')
    })
    onUpdated(() => {
    
    
      console.log('子onUpdated')
    })
  }

})
</script>

Insérer la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/gao_xu_520/article/details/125559272
conseillé
Classement