Vue.js前端开发零基础教学(四)

学习目标:

 熟悉选项式API和组合式API,能够说出选项式API和组合式API的区别

  掌握注册组件的方法,能够运用全局注册或者局部注册的方式完成组件的注册

  掌握父组件向子组件传递数据的方法,能够使用props实现数据传递等等

前言

在学习完第2章的基础知识后,可以编写一些简单的组件了,但是这样的组件功能比较简单,无法满足实际项目开发中各种复杂的需求。为了能够更灵活地使用组件,还需要更深入地学习组件的相关知识。第3章和第4章共两章的篇幅详细讲解组件基础,本章为上半部分内容。

3.1 选项式API和组合式API

Vue 3支持选项式API和组合式API。其中,选项式API是从Vue 2开始使用的一种写法,而Vue 3新增了组合式API的写法。

选项式API

选项式API是一种通过包含多个选项的对象来描述组件逻辑的API,其常用的选项包括data、methods、computed、watch等。 

组合式API

相比于选项式API,组合式API是将组件中的数据、方法、计算属性、侦听器等代码全部组合在一起,写在setup()函数中。

选项式API的语法格式如下。

<script>
export default {
  data() {
    return { // 定义数据 }
  },
  methods: { // 定义方法 },
  computed: { // 定义计算属性 },
  watch: { // 定义侦听器 }
}
</script>

组合式API的语法格式如下。

<script>
import { computed, watch } from 'vue'
export default {
  setup() {
    const 数据名 = 数据值
    const 方法名 = () => {}
    const 计算属性名 = computed(() => {})
    watch(侦听器的来源, 回调函数, 可选参数)
    return { 数据名, 方法名, 计算属性名 }
  }
}
</script>

Vue还提供了setup语法糖,用于简化组合式API的代码。使用setup语法糖时,组合式API的语法格式如下。

<script setup>
import { computed, watch } from 'vue'
// 定义数据
const 数据名 = 数据值
// 定义方法
const 方法名 = () => {}
// 定义计算属性
const 计算属性名 = computed(() => {})
// 定义侦听器
watch(侦听器的来源, 回调函数, 可选参数)
</script>

选项式API和组合式API的关系

Vue提供的选项式API和组合式API这两种写法可以覆盖大部分的应用场景,它们是同一底层系统所提供的两套不同的接口。选项式API是在组合式API的基础上实现的。

企业在开发大型项目时,随着业务复杂度的增加,代码量会不断增加。 如果使用选项式API,整个项目逻辑不易阅读和理解,而且查找对应功能的代码会存在一定难度。 如果使用组合式API,可以将项目的每个功能的数据、方法放到一起,这样不管项目的大小,都可以快速定位到功能区域的相关代码,便于阅读和维护。

同时,组合式API可以通过函数来实现高效的逻辑复用,这种形式更加自由,需要开发者有较强的代码组织能力和拆分逻辑能力。

演示选项式API和组合式API的使用方法

创建src\components\CustomSub.vue文件,用于演示组合式API的写法,在该文件中实现单击“+1”按钮使数字加1的效果。

<template>
	<p>子组件count值为:{{count}}</p>
	<!-- 出发自定义事件 -->
	<button @click="add">count+n</button>
</template>

<script setup>
import { ref } from 'vue';
// 声明自定义事件
	const emit=defineEmits(['updateCount']);
	const count=ref(1);
	const add = () =>{
		count.value++
		// add()方法
		emit('updateCount',2)
	}
</script>

<style>
</style>

 创建src\components\CustomFarther.vue文件

<template>
	<!-- 引用子组件,监听自定义事件 -->
	<p>父组件number的值:{{number}}</p>
	<CustomSub @updateCount="updateEmitCount"/>
</template>

<script setup>
	import CustomSub from'./CustomSub.vue'
	import { ref } from 'vue';
	// 局部注册子组件
	const number =ref(10);
	const updateEmitCount = (value) =>{
		number.value +=value
		emit('updateCount',2)
	}
</script>

<style>
</style>

修改src\main.js文件,切换页面中显示的组件。

import { createApp } from 'vue'
import App from './components/CustomFarther.vue'
const app=createApp(App)
import GlobalComponent from './components/GlobalComponent.vue'
app.component("GlobalComponent", GlobalComponent)
app.mount('#app')

运行结果:

持续点击count父组件会随着子组件的增加而增加:

3.2 生命周期函数 

概念:在Vue中,组件的生命周期是指每个组件从被创建到被销毁的整个过程,每个组件都有生命周期。如果想要在某个特定的时机进行特定的处理,可以通过生命周期函数来完成。 随着组件生命周期的变化,生命周期函数会自动执行。

组合式API下的生命周期函数如下表所示。

以onMounted()函数为例演示生命周期函数的使用。

<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  // 执行操作
})
</script>

 演示生命周期函数的使用方法

创建src\components\LifecycleHooks.vue文件,用于通过生命周期函数查看在特定时间点下的DOM元素。

<template>  <div class="container">container</div> </template>
<script setup>
import { onBeforeMount, onMounted } from 'vue'
onBeforeMount(() => {
  console.log('DOM元素渲染前', document.querySelector('.container'))
})
onMounted(() => {
  console.log('DOM元素渲染后', document.querySelector('.container'))
})
</script>

修改mian.js文件

import { createApp } from 'vue'
import App from './components/LifecycleHooks..vue'
createApp(App).mount('#app')

运行效果:

选项式API下的生命周期函数如下表所示。 

演示选项式API下beforeCreate()函数和created()函数的使用。

<script>
export default {
  data() { return { value: 'Hello Vue.js' } },
  beforeCreate() {
    console.log('实例对象创建前: ' + this.value)
  },
  created() {
    console.log('实例对象创建后: ' + this.value)
  }
}
</script>

3.3 组件的注册和引用

当在Vue项目中定义了一个新的组件后,要想在其他组件中引用这个新的组件,需要对新的组件进行注册。在注册组件的时候,需要给组件取一个名字,从而区分每个组件,可以采用帕斯卡命名法(PascalCase)为组件命名。 Vue提供了两种注册组件的方式,分别是全局注册和局部注册

帕斯卡命名法(PascalCase): 帕斯卡命名法(Pascal Case)是一种在编程中使用的命名约定,它要求将变量名和函数名称等标识符的每个单词首字母大写,并且单词之间直接相连,没有空格。这种命名法通常用于类名、函数名、属性名等标识符的命名。

例如,类名可以使用帕斯卡命名法表示为`MyClass`、`PersonInfo`、`GameManager`;方法名可以是`CalculateTotalScore()`、`PrintUserInfo()`、`InitializeGameWorld()`;属性名可以是`PlayerName`、`HighScore`、`IsGameOver`。

1. 全局注册

在实际开发中,如果某个组件的使用频率很高,许多组件中都会引用该组件,则推荐将该组件全局注册。被全局注册的组件可以在当前Vue项目的任何一个组件内引用。

在Vue项目的src\main.js文件中,通过Vue应用实例的component()方法可以全局注册组件,该方法的语法格式如下。

component('组件名称', 需要被注册的组件)

上述语法格式中,component()方法接收两个参数,第1个参数为组件名称,注册完成后即可全局使用该组件名称,第2个参数为需要被注册的组件。

在src\main.js文件中注册一个全局组件MyComponent,示例代码如下。

import { createApp } from 'vue';
import './style.css'
import App from './App.vue'
import MyComponent from './components/MyComponent.vue'
const app = createApp(App)
app.component('MyComponent', MyComponent)
app.mount('#app')

component()方法支持链式调用,可以连续注册多个组件,示例代码如下。

app.component('ComponentA', ComponentA)
    .component('ComponentB', ComponentB)
    .component('ComponentC', ComponentC)

2. 局部注册

 在实际开发中,如果某些组件只在特定的情况下被用到,推荐进行局部注册。局部注册即在某个组件中注册,被局部注册的组件只能在当前注册范围内使用。 局部注册组件的示例代码如下。

<script>
import ComponentA from './ComponentA.vue'
export default {
  components: { ComponentA: ComponentA }
}
</script>

在使用setup语法糖时,导入的组件会被自动注册,无须手动注册,导入后可以直接在模板中使用,示例代码如下。

<script setup>
import ComponentA from './ComponentA.vue'
</script>

 将组件注册完成后,若要将组件在页面中渲染出来,需要引用组件。 在组件的<template>标签中可以引用其他组件,被引用的组件需要写成标签的形式,标签名应与组件名对应。

组件的标签名可以使用短横线分隔或帕斯卡命名法命名。例如,<my-component>标签和<MyComponent>标签都表示引用MyComponent组件。一个组件可以被引用多次,但不可出现自我引用和互相引用的情况,否则会出现死循环。

演示组件的使用方法

创建src\components\GlobalComponent.vue文件,表示全局组件。

<template>
  <div class="global-container"><h5>全局组件</h5></div>
</template>
<style>
.global-container {
  border: 1px solid black;
  height: 50px;
  flex: 1;
}
</style>

 创建src\components\LocalComponent.vue文件,表示局部组件。

<template>
  <div class="local-container">
    <h5>局部组件</h5>
  </div>
</template>
<style>
.local-container {
  border: 1px dashed black;
  height: 50px;
  flex: 1;
}
</style>

修改src\main.js文件,导入GlobalComponent组件并调用component()方法全局注册GlobalComponent组件。

import { createApp } from 'vue'
import './style.css'
import App from './components/ComponentUse.vue'
import GlobalComponent from './components/GlobalComponent.vue'
const app = createApp(App)
app.component('GlobalComponent', GlobalComponent)
app.mount('#app')

修改src\components\ComponentUse.vue文件,添加代码导入LocalComponent组件。

<script setup>
import LocalComponent from './LocalComponent.vue'
</script>

 运行结果如下:

 

3.4 解决组件之间的样式冲突

在默认情况下,写在Vue组件中的样式会全局生效,很容易造成多个组件之间的样式冲突问题。例如,为ComponentUse组件中的h5元素添加边框样式,具体代码如下。

h5 {
  border: 1px dotted black;
}

运行效果如下:

原因:

导致组件之间样式冲突的根本原因是:在单页Web应用中,所有组件的DOM结构都是基于唯一的index.html页面进行呈现的。每个组件中的样式都可以影响整个页面中的DOM元素。 在Vue中可以使用scoped属性和深度选择器来解决组件之间的样式冲突。

1. scoped属性

Vue为<style>标签提供了scoped属性,用于解决组件之间的样式冲突。

为<style>标签添加scoped属性后,Vue会自动为当前组件的DOM元素添加一个唯一的自定义属性(如data-v-7ba5bd90),并在样式中为选择器添加自定义属性(如.list[data-v-7ba5bd90]),从而限制样式的作用范围,防止组件之间的样式冲突问题。

下面演示scoped属性的使用。

修改ComponentUse组件,为<style>标签添加scoped属性,具体代码如下。

<style scoped>

运行结果:

 

 打开开发者工具,切换到Elements面板,查看父组件的h5元素的代码,如下图所示。

从上图可以看出,当<style>标签添加scoped属性后,h5元素和相应的选择器被Vue自动添加了data-v-e4f30916属性,从而解决了样式冲突的问题。

2. 深度选择器

 如果给当前组件的<style>标签添加了scoped属性,则当前组件的样式对其子组件是不生效的。 如果在添加了scoped属性后还需要让某些样式对子组件生效,则可以使用深度选择器来实现。

深度选择器通过:deep()伪类来实现,在其小括号中可以定义用于子组件的选择器,例如,“:deep(.title)”被编译之后生成选择器的格式为“[data-v-7ba5bd90] .title”。

演示如何通过ComponentUse组件更改LocalComponent组件的样式

为LocalComponent组件的h5元素添加class属性。

<h5 class="title">局部组件</h5>

演示如何通过ComponentUse组件更改LocalComponent组件的样式

在ComponentUse组件中定义.title的样式。

:deep(.title){
  border: 3px dotted black;
}

运行结果为:

打开开发者工具,切换到Elements面板,查看LocalComponent组件的h5元素的代码,页面效果如下图所示。

 3.5 父组件向子组件传递数据

在不使用setup语法糖的情况下,可以使用props选项声明props。props选项的形式可以是对象或字符串数组。声明对象形式的props的语法格式如下。

<script>
export default {
  props: {
    自定义属性A: 类型,
    自定义属性B: 类型,
    ……
  }
}
</script>

如果不需要限制props的类型,可以声明字符串数组形式的props,示例代码如下。

props: ['自定义属性A', '自定义属性B'],

 当使用setup语法糖时,可使用defineProps()函数声明props,语法格式如下。

<script setup>
const props = defineProps({'自定义属性A': 类型}, {'自定义属性B': 类型})
</script>

使用defineProps()函数声明字符串数组形式的props,语法格式如下。

const props = defineProps(['自定义属性A', '自定义属性B'])

 在组件中声明了props后,可以直接在模板中输出每个prop的值,语法格式如下。

<template> 
  {{ 自定义属性A }}
  {{ 自定义属性B }}
</template>

当在父组件中引用了子组件后,如果子组件中声明了props,则可以在父组件中向子组件传递数据。如果传递的数据是固定不变的,则可以通过静态绑定props的方式为子组件传递数据。

通过静态绑定props的方式为子组件传递数据,其语法格式如下。

<子组件标签名 自定义属性A="数据" 自定义属性B="数据" />

在上述语法格式中,父组件向子组件的props传递了静态的数据,属性值默认为字符串类型。

注意:如果子组件中未声明props,则父组件向子组件中传递的数据会被忽略,无法被子组件使用。

演示父组件向子组件传递数据的方法

创建src\components\Count.vue文件,用于展示子组件的相关内容。

<template>
  初始值为:{{ num }}
</template>
<script setup>
const props = defineProps({
  num: String
})
</script>

创建src\components\Props.vue文件,用于展示父组件的相关内容。

<template>
  <Count num="1" />
</template>
<script setup>
import Count from './Count.vue'
</script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/Props.vue'

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode每日一题】 递归 - 求根节点到叶节点数字之和(难度⭐⭐)(47)

1. 题目解析 题目链接&#xff1a;129. 求根节点到叶节点数字之和 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 递归函数设计&#xff1a; 我们设计了一个递归函数 int dfs(TreeNode* root, int num)&#xff0c;其…

【42 可视化大屏 | 某瓣电影Top250数据分析可视化大屏】

文章目录 &#x1f3f3;️‍&#x1f308; 1 普版大屏&#x1f3f3;️‍&#x1f308;2 Flask版大屏&#x1f3f3;️‍&#x1f308;3 FlaskMysql版大屏&#x1f3f3;️‍&#x1f308; 4. 可视化项目源码数据 大家好&#xff0c;我是 &#x1f449;【Python当打之年(点击跳转)…

PonyAi Planning-横纵向轨迹规划

PonyAi Planning-横纵向轨迹规划 轨迹规划的探索和挑战 轨迹规划的概念安全舒适两不误&#xff1a;探讨优化算法在规划控制中的应用 轨迹规划的概念 决策 横向规划 纵向规划 优化算法在规划&#xff08;Planning&#xff09;中的应用 附赠自动驾驶学习资料和量产经验…

七、函数的使用方法

函数的调用 nameinput&#xff08;&#xff09;#输入参数并赋值name print&#xff08;name&#xff09;#d打印name 格式&#xff1a;返回值函数名&#xff08;参数&#xff09; def get_sum(n):#形式参数计算累加和:param n::return: sumsum0for i in range(1,n1):sumiprint…

Linux编译器-gcc/g++/gdb使用

Linux编译器-gcc/g/gdb使用 一、背景知识二、 gcc如何完成2.1 预处理(进行宏替换)2.2 编译&#xff08;生成汇编&#xff09;2.3 汇编&#xff08;生成机器可识别代码&#xff09;2.4 连接&#xff08;生成可执行文件或库文件&#xff09; 三、函数库四、gcc选项五、gdb5.1 背景…

Node.js的Event Loop:六个阶段详解

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Vue2(十二):Vuex环境搭建、Vuex工作原理、几个配置项

一、Vuex 1.概念 专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff08;use引入&#xff09;&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读&#xff0f;写&#xff09;&#xff0c;也是一种组件间通信的方式&…

JavaSE:继承和多态(下篇)

目录 一、前言 二、多态 &#xff08;一&#xff09;多态的概念 &#xff08;二&#xff09;多态实现条件 &#xff08;三&#xff09;多态的优缺点 三、重写 &#xff08;一&#xff09;重写的概念 &#xff08;二&#xff09;重写的规则 &#xff08;三&#xff09;重…

Vue-vue3

一、Vue3简介二、Vue3有那些优化性能的提升源码升级拥抱TypeScript新的特性 三、创建Vue3.0工程四、Vue3工程结构&#xff08;使用cli创建的vue3&#xff09;五、常用的Composition API&#xff08;组合式API&#xff09;setupsetup的两个注意点 ref函数reactive函数Vue3.0中的…

Java实验报告2

一、实验目的 本实验为Java课程的第二次实验&#xff0c;其主要目的如下&#xff1a; 理解继承和多态的概念&#xff1b; 掌握域和方法在继承中的特点&#xff1b; 掌握构造函数的继承和重载&#xff1b; 掌握this和super的用法&#xff1b; 二、实验原理 ​ 继承性是面…

日志集中审计系列(3)--- LogAuditor接收UMA设备syslog日志

日志集中审计系列(3)--- LogAuditor接收UMA设备日志 前言拓扑图设备选型组网需求配置思路操作步骤结果验证前言 近期有读者留言:“因华为数通模拟器仅能支持USG6000V的防火墙,无法支持别的安全产品,导致很多网络安全的方案和产品功能无法模拟练习,是否有真机操作的实验或…

深度学习(四)笔记1

0.前提 往后我会以我的笔记形式来发布我的文章&#xff08;每3次笔记为一篇文章&#xff09;&#xff0c;有爱的人可以自取学习&#xff0c;当然如果可以的话我会把我的文章翻出来变成文章。 1.数据操作 本期4.1数据操作的链接在这。 链接&#xff1a;https://pan.baidu.com/s…

测试图片可否直接粘贴进csdn,后期删除

java图书管理系统mysqlswing版本 V1.0.1版 P1&#xff0c;简介项目功能&#xff1a; 运行主函数运行程序&#xff0c;进入管 理系统的登录界面

9.Python类与对象

1 面向对象 类和对象都是面向对象中的重要概念。面向对象是一种编程思想&#xff0c; 即按照真实世界的思维方式构建软件系统。 例如&#xff0c;在真实世界的校园里有学生和老师&#xff0c;学生有学号、姓名、所 在班级等属性&#xff08;数据&#xff09;&#xff0c;还有…

顺序表详解

目录 线性表顺序表概念及结构接口实现初始化函数void SLInit(SL *psl);销毁函数 void SLDestroy(SL *psl);尾插函数void SLPushBack(SL* psl ,SLDataType x);封装函数void SLCheckCapacity(SL* psl)头插函数void SLPushFront(SL* psl, SLDataType x);尾删函数void SLPopBack(SL…

洛谷_P2437 蜜蜂路线_python写法_高精度加法

目录 1. 40分代码 2.高精度加法 3.全AC代码 4.惊掉下巴的解法 P2437 蜜蜂路线 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 1. 40分代码 m, n map(int,input().split())ans 0 d [1,2] flag [0 for _ in range(n1)] def fun(step):global ansif step n:ans 1return…

了解微信小程序开发流程

前言&#xff1a;本文只适合初学者了解大致开发流程&#xff0c;好让后续学习胸有成竹&#xff0c;有条不紊 1、开发准备 ① 在微信公众平台 (qq.com)完成微信小程序账号注册 ②下载安装微信小程序开发者工具 2、创建项目 新建 新建时需要的appid&#xff0c;在微信公众平…

GeoLite2 geoip数据库下载和使用

GeoLite2 数据库是免费的 IP 地理定位数据库&#xff0c;与MaxMind 的 GeoIP2 数据库相当&#xff0c;但准确度较低 。GeoLite2 国家、城市和 ASN 数据库 每周更新两次&#xff0c;即每周二和周五。GeoLite2 数据还可作为 GeoLite2 Country 和 GeoLite2 City Web 服务中的 Web …

微服务监控:确保分布式系统的可观察性与稳定性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 一、前言二、微服务监控的重要性三、关键监控指标四、常用监控工具五、最佳实践六、结论 一、前言 在当前的软件开发领域&a…

Lua环境下载与配置

这里介绍如何下载已经编译好的Lua环境&#xff0c;如何配置Lua环境。 如希望自己从源码编译Lua环境&#xff0c;请自行搜索资料。 第一步&#xff1a;下载编译好的lua环境 打开下面链接&#xff0c;然后根据指引下载。 The Programming Language Luahttps://www.lua.org/hom…