自学内容网 自学内容网

Vue3学习笔记(下)


Vue3学习笔记(下)

组合式API下的父子通信

父传子

基本思想:

  1. 父组件中给子组件绑定属性
  2. 子组件内部通过props选项接收

在这里插入图片描述

注意:由于写了setup,所以无法直接配置props选项,所以,此处需要借助“编译器宏”函数接收子组件传递的数据。

defineProps原理:就是编译阶段的一个标识,实际编译器解析时,遇到后会进行编译转换

在这里插入图片描述

子传父

基本思想:

  1. 父组件中给子组件标签通过@绑定事件
  2. 子组件内部通过emit方法触发事件

在这里插入图片描述

模板引用

概念:通过ref标识获取真实的dom对象或者组件实例对象(可以获取dom,也可以获取组件)

  1. 调用ref函数,生成一个ref对象
  2. 通过ref标识,进行绑定
  3. 通过ref对象.value即可访问到绑定的元素(必须渲染完后才能拿到)

defineExpose()

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

<script setup>
import { ref } from 'vue'
const testMsg = ref('this is msg')
defineExpose({
    testMsg
})
</script>

provide和inject

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

跨层传递普通数据:

  1. 顶层组件通过provide函数提供数据 —— provide('words', 'abc')
  2. 底层组件通过inject函数获取数据 —— const word = inject('words')

跨层传递响应式数据:

  1. const count = ref(100) provide('count', count)
  2. const count = ('count')

跨层级传递函数:

底层组件如何修改顶层组件的数据:顶层组件给子孙后代传递可以修改数据的方法,底层组件调用。

  1. provide('changeCount', (newValue) => {
        count.value = newvalue
    })
    
  2. const changeCount = inject('changeCount')
    

vue3新特性 - defineOptions

背景:有<script setup>之前,如果要定义props,emits可以轻而易举地添加一个与setup平级的属性。但是用了<script setup>后,相当于script中所有的代码都写在setup函数里,无法添加与其平级的属性。

为了解决这一问题,引入了defineProps与defineEmits这两个宏,但这只解决了props与emits这两个属性。如果我们要定义组件的name或者其他自定义的属性,还得回到最原始的用法——再添加一个普通的<script>标签。

defineOptions主要是用来定义Options API的选项。可以用defineOptions定义任何选项,props,emits,expose,slots除外(因为这些可以使用defineXXX来做到。

<script setup>
defineOptions({
    name: 'LoginIndex',
    inheritAttrs: false,
    // ...更多自定义属性
})
</script>

vue3新特性 - defineModel

在vue3中,自定义组件上使用v-model,相当于传递一个modelValue属性,同时触发update:modelValue事件。

<script setup>
import sonCom from '@/components/son-com.vue'
import { ref } from 'vue'
const txt = ref('aaabbb')
</script>

<template>
  <sonCom v-model="txt"></sonCom>
  <div>{{ txt }}</div>
</template>

<style scoped>
</style>
<script setup>
defineProps({
  modelValue: String
})
const emit = defineEmits(['update:modelValue'])
</script>

<template>
<div>
  <input 
    type="text"
    :value="modelValue"
    @input="e => emit('update:modelValue', e.target.value)"
  >
</div>
</template>

<style>
</style>

Pinia

Pinia是Vue的最新状态管理工具,是Vuex的替代品。

  1. 提供更加简单的API(去掉了mutation)
  2. 提供符合组合式风格的API(和Vue3新语法统一)
  3. 去掉了modules的概念,每一个store都是一个独立的模块
  4. 配合TypeScript更加友好,提供可靠的类型推断
import { defineStore } from "pinia"
import { ref } from 'vue'
import axios from 'axios'
export const storeModel = defineStore('store', () => {
  const count = ref(10)
  const sub = () => { count.value-- }
  const add = () => { count.value++ } 
  return {
    count,
    sub,
    add
  }
})
<script setup>
import { storeModel } from '@/store/index'
const store = storeModel() // 此处不能直接解构const { count } = store,会丢失数据的响应式
</script>

<template>
  <div>
    <h3>Son1组件 - {{ store.count }}</h3>
    <button @click="store.add()">+</button>
  </div>
</template>

<style scoped>

</style>

Pinia异步写法

import { defineStore } from "pinia"
import { ref } from 'vue'
import axios from 'axios'
export const storeModel = defineStore('store', () => {
  const list = ref([])
  const getlist = async () => {
    const res =  await axios.get('http://geek.itheima.net/v1_0/channels')
    list.value = res
  }
  return {
    getlist,
    list
  }
})
<script setup>
import { storeModel } from '@/store/index'
const store = storeModel()
store.getlist()
</script>
<template>
<div>{{ store.list }}</div>
</template>
<style scoped>
</style>

注意:store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value。就像 setup 中的 props 一样,我们不能对它进行解构

为了从 store 中提取属性时保持其响应性,需要使用 storeToRefs()。它将为每一个响应式属性创建引用。

<script setup>
import { storeModel } from '@/store/index'
import { storeToRefs } from 'pinia';
const store = storeModel()
const { count } = storeToRefs(store)
</script>

<template>
  <div>
    <h3>Son1组件 - {{ count }}</h3>
    <button @click="store.add()">+</button>
  </div>
</template>

<style scoped>

</style>

注意,我们可以直接从 store 中解构 action,因为它们也被绑定到 store 上。


原文地址:https://blog.csdn.net/2301_79614379/article/details/143837918

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!