vue3(二)

news2024/12/23 8:52:39

前一篇讲了 vue3的生命周期钩子的使用。
本节接着讲 vue3的数据通信。

provide/inject 依赖注入

App.vue

<script setup lang="ts">
import { ref, provide } from 'vue'
import List from './components/List.vue'
import User from './components/User.vue'
import Demo from './components/Demo.vue'

const count = ref<number>(1)
const msg = ref<string>('hello world')

interface DataObj {
  name: string
  readonly id?: number // 只读属性
  age: number
  gender: string
  address?: string // 可选属性
  [propName: string]: any // 任意的属性
  sum?(a: number, b: number): number // 声明 可选方法 sum()返回值为 number
  updateData(): any // 声明 updateData() 返回值类型为 any
}

const updateData = (): void => {
  console.log('我是来自爷爷组件的方法')
}
const dataObj = ref<DataObj>({
  name: 'zhangsan',
  age: 20,
  gender: 'male',
  updateData,
})

const clickHandle = (): any => {
  console.log(count.value)
  count.value++
  /**在js中需要通过 .value来访问变量,因为 count是 proxy代理的名称 */
}

// 通过 provide 向外暴露一个变量,然后在所有后代组件中都可以获取,实现跨组件通信
provide('msg', msg)
provide('dataObj', dataObj)

const getDataFromSon = (params: string): any => {
  console.log('来自子组件的数据', params)
}
</script>

<template>
  <!--在模板中直接使用变量-->
  <h1>{{ count }}</h1>

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

  <button @click="clickHandle">增加</button>

  <List @getDataFromSon="getDataFromSon" :dataToSon="msg" />

  <User />

  <Demo />
</template>

<style scoped></style>

Info.vue 作为后代组件来消费根组件传递的数据

<script setup lang="ts">
import { ref, inject } from 'vue'
import Home from './Home.vue'
const txt = ref<string>('hello vue3')
const list = ref<string[]>()

// 通过 inject来消费顶层组件传递的数据
const message = inject<string>('msg')
const dataObj = inject<any>('dataObj')
</script>
<template>
  <h1>{{ txt }} {{ message }}</h1>

  <h2>{{ dataObj.name }}</h2>

  <button @click="dataObj.updateData">调用爷爷组件的方法</button>

  <Home :txt="txt" />
</template>

<style scoped></style>

父子组件通信

创建一个List.vue

<script setup lang="ts">
import { ref, onMounted, watch, computed, reactive } from 'vue'
import Info from './Info.vue'

// 申明一个接口
interface Book {
  title: string
  year?: number // 可选属性,有可能不存在
}

const book: Book = reactive({ title: 'Vue 3 指引' })

const txt = ref<string>('')
const list = ref<string[]>([])
const infoRef = ref<any>()
// 通过 defineEmits()方法来声明传递给父组件的方法,该方法接收一个数组,可以传递多个emit方法
// defineEmits()和 defineProps()都是在子组件中使用,声明的都是定义在子组件上的事件和属性

const emit = defineEmits(['getDataFromSon'])
const props = defineProps<{ dataToSon: string }>()

const saveText = (): any => {
  if (txt) list.value.push(txt.value)
  emit('getDataFromSon', txt.value)
  console.log('来自父组件的数据:', props.dataToSon)
  txt.value = ''
}

computed(() => {})

watch(
  () => txt.value,
  (txt, preText) => {
    console.log(txt, preText)
  }
)

onMounted(() => {
  // 使用子组件暴露出来的属性和方法
  console.log(infoRef.value.message)
  console.log(infoRef.value.dataObj)
  console.log('Dom 已经挂在完毕')
})

const callSonMethod = (): any => {
  infoRef.value.callMe()
}
/**
 * 在script标签中添加 setup 属性是 vue 官方推荐的默认写法,
 * 这样在 script标签中定义的函数,变量,甚至是 imort 导入的,都可以在模板中直接使用
 * 而setup()函数这种写法,需要将所有声明的变量,函数通过 renturn函数暴露处供模板使用
 */
</script>

<template>
  <input
    type="text"
    v-model="txt"
    @keyup.enter="saveText"
    placeholder="请输入内容"
  />
  <div class="list">
    <ul>
      <li v-for="item in list" :key="item">
        {{ item }}
      </li>
    </ul>
  </div>

  <Info ref="infoRef"/>
</template>
<style scoped></style>

创建Info.vue, 父组件传递 tex 变量给子组件, 子组件通过触发getDataFromSon()向父组件传递数据

<script setup lang="ts">
import { ref, inject } from 'vue'
import Home from './Home.vue'

const txt = ref<string>('hello vue3.0')
const list = ref<[]>()
const message = inject<string>('msg')
const dataObj = inject<any>('dataObj')

const callMe = (): any => {
  console.log('this method is use defineExpose to parent')
}
// 通过 defineExpose({}) 方法暴露子组件的一些属性和方法,供父组件使用
defineExpose({
  message,
  dataObj,
  callMe,
})

</script>
<template>
  <h1>{{ txt }} {{ message }}</h1>

  <h2>{{ dataObj.name }}</h2>

  <button @click="dataObj.updateData">调用爷爷组件的方法</button>

  <Home :txt="txt" />
</template>

<style scoped></style>

setup() 这种写法

<script lang="ts">
import { ref, reactive, onMounted } from 'vue'
export default {
  /**
   * 组合式 API 我们可以讲所有的属性方法都写在 setup()方法中,然后 return 出去
   * 不再像 选项式API 哪种,需要写 data, methods, created等等
   */
  setup() {
    // ref用来定义基础数据类型,在 js中访问的时候要通过.value来访问
    const count = ref<number>(1)
    const list = reactive<any>({
      // reactive用来定义复杂数据类型,访问的不用.value
      num: 1,
      list: [],
    })
    const increment = () => {
      count.value++
      list.num += 1
    }
    /**
     * 在 vue3中没有 beforeCreated 和 created钩子函数,
     * setup 方法就相当于这 2 个钩子
     */

    onMounted(() => {
      console.log('Dom 已经过载完毕')
    })

    /**
     * 通过 return 将属性和方法暴露出去,供模板访问
     */
    return {
      count,
      list,
      increment,
    }
  },
}
/**
 * 注意:使用reactive()声明复杂数据类型,给对象赋值时,通过下面这种方式来声明(如果嫌.value麻烦的话)
 * const obj = reactive({
 *  data: {
 *    name: '',id: '',}
 *  })
 * 就是在对象外面给它包一个key值,赋值时:
 * obj.data = {name: 'zhangsan', id: 100}
 *
 * 第二种:就是直接用 ref 来声明对象或者数据,赋值时:obj.value = {name: 'Alex', id: 001}
 */
</script>

<template>
  <h2>这是 User 组件 {{ count }}</h2>

  <h1>{{ list.num }}</h1>

  <button @click="increment">click</button>
</template>

<style></style>

setup() <script setup></script> 区别

  • setup()函数中定义的变量或者函数,需要 return 暴露出去,模板才能调用
  • 而当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用
  • <script setup> 中的代码会在每次组件实例被创建的时候执行。
    <script setup></script> 优势:
    setup_attribute
    toRef()toRefs() 区别
    toRef
const state = reactive({
  foo: 1,
  bar: 2
})
// 通过toRef()后 fooRef变量也是响应式的,改变foo的值,fooRef也改变
// 作用:将一个非响应式的变量转换为一个响应式变量
const fooRef = toRef(state, 'foo')

// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo) // 2

// 更改源属性也会更新该 ref
state.foo++
console.log(fooRef.value) // 3

toRefs
ref()shallowRef() 区别

ref()我们知道可以创建一个响应式变量
shallowRef(): ref() 的浅层作用形式。

那么,shallowRef()就是可以创建一个浅层次的响应式变量,
应用场景:如果你的数据不赋值,不变更或者修改,只是做展示用,那么可以用 shallowRef(),可以节省性能消耗

reactive()shallowReactive()

reactive(): 返回一个对象的响应式代理,
响应式转换是“深层”的:它会影响到所有嵌套的属性。一个响应式对象也将深层地解包任何 ref 属性,同时保持响应性

shallowReactive():reactive() 的浅层作用形式。

和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了
若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用 shallowReactive() 作替代。

const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 更改状态自身的属性是响应式的
state.foo++

// ...但下层嵌套对象不会被转为响应式
isReactive(state.nested) // false

// 不是响应式的
state.nested.bar++

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

知识点8--Docker镜像的秘密

前面的知识点我们介绍了docker的日常使用&#xff0c;但其实docker存在的核心意义是交付环境&#xff0c;也就是镜像&#xff0c;本片知识点带大家了解一下镜像的秘密。 镜像本身是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;包…

【Tensorflow学习二】神经网络优化方法学习率、激活函数、损失函数、正则化

文章目录预备知识tf.wheretf.random.RandomState.rand() 返回一个[0,1)之间的随机数np.vstack() 将数组按照垂直方向叠加np.mgrid[ ] np.ravel( ) np.c_[ ] 一起使用可以生成网格坐标点复杂度、学习率复杂度指数衰减学习率激活函数Sigmoid激活函数Tanh激活函数ReLu激活函数Leak…

今天面了个00后测试员,让我见识到了内卷届的天花板

深耕IT行业多年&#xff0c;我们发现&#xff0c;对于一个程序员而言&#xff0c;能去到一线互联网公司&#xff0c;会给我们以后的发展带来多大的影响。 很多人想说&#xff0c;这个我也知道&#xff0c;但是进大厂实在是太难了&#xff0c;简历投出去基本石沉大海&#xff0…

Linux安装KVM

一、虚拟化技术 1、全虚拟化和半虚拟化技术 如果给KVM、XEN简单归类的话&#xff0c;KVM是完全虚拟化技术又叫硬件辅助虚拟化技术&#xff08;Full Virtualization)。相反&#xff0c;XEN是半虚拟化技术&#xff08;paravirtualization&#xff09;&#xff0c;也叫做准虚拟化…

线上环境内存溢出-OutOfMemoryError

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 线上环境内存溢出-OutofMemoryError前言一、OutOfMemoryError是什么&#xff1f;二、实际情况&#xff08;参考&#xff09;解决方案1.实战总结前言 公司线上环境&#xff0…

getBoundingClientRect属性研究

getBoundingClientRect属性研究 概念 getBoundingClientRect 返回 width、height和下图中的6个属性 实测总结&#xff1a; 抓住一个核心点&#xff0c;就是height、width的值&#xff1a; box-sizing 是 content-box时&#xff0c;width和height 内容borderpaddingbox-siz…

国家级专新特精“小巨人”「皖仪科技」携手企企通,打造采购数字化平台成功上线

近日&#xff0c;安徽皖仪科技股份有限公司&#xff08;以下简称“皖仪科技”&#xff09;携手企企通共同打造的数字化采购管理系统成功上线。基于皖仪科技的采购业务流程和规则&#xff0c;形成全新的数字化采购体系&#xff0c;在推动企业降本增效的同时&#xff0c;实现企业…

单商户商城系统功能拆解42—应用中心—商城公告

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

冠状病毒疾病优化算法 (COVIDOA)附matlab代码

​✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法…

npp各个平台npp数据比较

文章目录1GEE中的npp数据2 与其他数据的比较1GEE中的npp数据 在GEE上查阅npp&#xff0c;可以看到有连个数据集&#xff0c;一个是Terra的&#xff0c;另一个是Aqua的。 我比较了两个的不同&#xff0c;发现Terra是2000-目前的&#xff0c;而Aqua是2002-目前的&#xff0c;都是…

2022吴恩达机器学习课程——第一课

注&#xff1a;参考B站视频教程 视频链接&#xff1a;【(强推|双字)2022吴恩达机器学习Deeplearning.ai课程】 文章目录第一周一、监督学习与无监督学习二、线性回归三、梯度下降第二周一、向量化二、特征缩放第三周一、逻辑回归二、训练逻辑回归模型三、逻辑回归中的梯度下降四…

[运维]如何快速压缩一个数据库的硬盘占用大小(简单粗暴但有效)

文章目录前言一、数据库文件为什么会那么大&#xff1f;1.数据空间2.日志空间3.索引空间4.其他二、我的解决方案总结前言 在维护网站时我们经常会遇到数据库占用服务器磁盘空间的问题。高端的食材往往只需要采用最朴素的烹饪方式。本文我讲一个简单粗暴但有效的方法。本文以Sq…

RabbitMQ快速上手以及RabbitMQ交换机的四种模式

Win10安装&#xff1a; ​win10下安装 RabbitMQ​_柚几哥哥的博客-CSDN博客 Linux安装&#xff1a; Linux下载安装 RabbitMQ​_柚几哥哥的博客-CSDN博客 一、基础使用 1、导入依赖 <!--RabbitMQ--><dependency><groupId>org.springframework.boot</g…

JAVA12_06学习总结(JDBC,工具类优化)

今日内容 1. PreparedStatement PreparedStatement--预编译步骤1)注册驱动2)获取数据库连接对象3)准备sql语句--不需要拼接--需要的参数全部使用 ? 占位符4)通过数据库连接对象,获取预编译对象,同时将sql语句房费数据库,将参数和参数类型都存储在预编译中Connection中的方法…

均匀传输线的串扰和饱和长度

下图为串扰的电路模型&#xff0c;动态线与静态线之间通过互容与互感联系&#xff0c;这样也说明了动态线的信号耦合到静态线上的条件是存在di/dt或者dv/dt时&#xff0c;也就是说只在信号边沿上产生串扰&#xff0c;当电压或者电流为常数的时候静态线上就不会有串扰的信号。 信…

扩散模型:Diffusion models as plug-and-play priors作为即插即用先验的扩散模型

扩散模型&#xff1a;Diffusion models as plug-and-play priors作为即插即用先验的扩散模型0.摘要1.概述2.方法2.1.问题设置2.2.将去噪扩散概率模型作为先验3.实验&#xff1a;图像生成3.1.MNIST的简单说明3.2.使用现成组件条件生成脸部图像4.实验&#xff1a;语义分割附录B&a…

Ubuntu 20.04 系统最快安装WRF软件手册

前言 天气研究和预报&#xff08;WRF&#xff09;模型是一种中尺度数值天气预报系统&#xff0c;在全球范围内用于业务预报和研究目的。 这是在基于Intel的i7&#xff08;12核&#xff09;Linux Ubuntu 20.04 LTS系统上安装WRF 4.2.1的版本。这将有助于初学者在普通台式机上实现…

树莓派4b+mcp2515实现CAN总线通讯和系统编程(一.配置树莓派CAN总线接口)

文章目录前言硬件连线树莓派环境准备启用树莓派ssh启用mcp2515驱动下载can-utils工具测试CAN通讯开启CAN网卡测试发送和接收前言 树莓派本身是没有CAN通讯能力的&#xff0c;但他有mcp2515模块的驱动&#xff0c;可以通过SPI来控制mcp2515进行CAN的通讯。 本章主要讲,如何使能…

基于卡尔曼滤波的二维目标跟踪(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

双十二选哪个品牌led灯好一点?国产led灯这些品牌护眼好

现在绝大部分人造灯光都是使用led灯珠作为发光源了&#xff0c;所以led灯普遍的质量都比较好&#xff0c;也能护眼&#xff0c;特别是习惯晚上熬夜工作、学习、看书的人群&#xff0c;也都会选择led台灯来辅助照明&#xff0c;因为相比传统的家用室内顶灯&#xff0c;led护眼灯…