当前位置: 首页 > news >正文

Vue 3 入门教程 2- Vue 组件基础与模板语法

一、Vue 组件基础

在 Vue 中,组件是构建用户界面的基本单位,它可以将页面拆分成多个独立、可复用的部分。一个 Vue 组件通常以 .vue 文件名结尾,包含三个核心部分:模板(Template)、脚本(Script)和样式(Style)。

1.1 单文件组件(.vue 文件)结构

单文件组件(SFC)是 Vue 推荐的组件组织方式,其结构清晰,便于维护。

<template><!-- 模板部分:定义组件的 HTML 结构 --><div class="hello"><h1>{{ msg }}</h1></div></template><script setup><!-- 脚本部分:处理组件的逻辑 -->// 导入需要的模块或组件import { ref } from 'vue'// 定义组件的数据const msg = ref('Hello Vue 3!')</script><style scoped>
<!-- 样式部分:定义组件的样式 -->.hello {color: blue;text-align: center;}</style>

  • 模板(Template):必须包含在 <template> 标签内,用于定义组件的渲染结构。一个组件的模板只能有一个根元素(Vue 3 支持多根元素,但通常建议使用一个根元素包裹)。
  • 脚本(Script):使用 <script setup> 语法(Vue 3 推荐),用于编写组件的逻辑,包括数据定义、方法声明、生命周期钩子等。setup 是 Vue 3 组合式 API 的入口点。
  • 样式(Style):包含在 <style> 标签内,用于定义组件的样式。添加 scoped 属性后,样式仅作用于当前组件,避免样式污染。

1.2 组件的注册与使用

组件分为全局注册和局部注册两种方式,全局注册的组件可在整个应用中使用,局部注册的组件仅能在注册它的父组件中使用。

1.2.1 全局注册

在 main.js 中通过 app.component() 方法全局注册组件:

// main.js
import { createApp } from 'vue'import App from './App.vue'import HelloWorld from './components/HelloWorld.vue'const app = createApp(App)// 全局注册 HelloWorld 组件,第一个参数是组件名,第二个参数是组件对象app.component('HelloWorld', HelloWorld)app.mount('#app')

注册后,可在任意组件的模板中直接使用:

<template><div><HelloWorld /></div>
</template>
1.2.2 局部注册

在需要使用组件的父组件中,通过 import 导入组件后,在 components 选项中注册:

<template><div><LocalComponent /></div></template><script setup>import LocalComponent from './components/LocalComponent.vue'// 在 setup 语法中,导入的组件会自动注册,无需额外配置</script>

1.3 组件通信基础(父传子)

父组件通过 props 向子组件传递数据,子组件通过定义 props 接收数据。

父组件示例
<template><div><ChildComponent :message="parentMsg" :count="10" /></div></template><script setup>import { ref } from 'vue'import ChildComponent from './components/ChildComponent.vue'const parentMsg = ref('来自父组件的消息')</script>
子组件示例
<template>
<div>
<p>{{ message }}</p>
<p>接收的数字:{{ count }}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
// 定义 props,指定接收的属性名和类型
const props = defineProps({
message: String,
count: Number
})
// 使用 props 中的数据(直接通过 props.属性名访问)console.log(props.message)

</script>

在子组件中,defineProps 用于声明接收的 props,可以指定属性的类型、默认值、验证规则等。父组件传递数据时,通过 v-bind(简写为 :)将数据绑定到子组件的属性上。

二、模板语法

Vue 的模板语法是一种基于 HTML 的模板系统,它允许在 HTML 中嵌入 Vue 特有的语法,实现数据绑定、条件渲染、列表渲染等功能。

2.1 文本插值

使用双大括号 {{ }} 可以将响应式数据插入到模板中,这称为文本插值。

<template><div><p>基本文本:{{ username }}</p><p>表达式计算:{{ 1 + 2 * 3 }}</p><p>函数调用:{{ formatMessage('Hello') }}</p></div></template><script setup>import { ref } from 'vue'const username = ref('Vue 用户')const formatMessage = (str) => {return str + ',欢迎使用 Vue 3'}</script>

双大括号内可以是变量、表达式或函数调用,Vue 会自动计算并将结果渲染到页面上。当数据发生变化时,插值内容会自动更新。

2.2 指令

指令是带有 v- 前缀的特殊属性,用于在模板中实现复杂的逻辑操作。

2.2.1 v-bind:绑定属性

v-bind 用于动态绑定 HTML 属性,可简写为 :。

<template>
<div>
<img v-bind:src="imageUrl" alt="图片">
<a :href="linkUrl" :class="{ active: isActive }">链接</a>
</div>
</template>
<script setup>
import { ref } from 'vue'
const imageUrl = ref('https://vuejs.org/images/logo.png')
const linkUrl = ref('https://vuejs.org')
const isActive = ref(true)
</script>
<style>
.active {
color: red;
text-decoration: underline;
}
</style>

上述示例中,src、href、class 属性的值通过 v-bind 绑定到响应式数据上,当数据变化时,属性值会自动更新。class 还支持对象语法,根据 isActive 的值动态添加或移除 active 类。

2.2.2 v-on:事件绑定

v-on 用于绑定事件监听器,可简写为 @。

<template>
<div>
<button v-on:click="handleClick">点击按钮</button>
<button @dblclick="handleDoubleClick">双击按钮</button>
<input @input="handleInput" placeholder="输入内容">
</div>
</template>
<script setup>
import { ref } from 'vue'
const handleClick = () => {
console.log('按钮被点击了')
}
const handleDoubleClick = () => {
console.log('按钮被双击了')
}
const handleInput = (e) => {
console.log('输入的内容:', e.target.value)
}
</script>

v-on 可以绑定各种 DOM 事件,事件处理函数可以接收事件对象 e,通过 e.target 等属性获取事件相关信息。

2.2.3 v-model:双向数据绑定

v-model 用于在表单元素(如输入框、复选框等)和响应式数据之间建立双向绑定,即数据变化时表单元素的值会更新,表单元素的值变化时数据也会同步更新。

<template>
<div>
<input v-model="username" placeholder="输入用户名">
<p>您输入的用户名:{{ username }}</p>
<textarea v-model="content" placeholder="输入内容"></textarea>
<p>文本域内容:{{ content }}</p>
<label>
<input type="checkbox" v-model="isAgree"> 同意协议
</label>
<p>是否同意:{{ isAgree }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const username = ref('')
const content = ref('')
const isAgree = ref(false)
</script>

v-model 会根据表单元素的类型自动选择合适的绑定方式,例如文本输入框绑定 value 属性和 input 事件,复选框绑定 checked 属性和 change 事件。

2.2.4 条件渲染(v-if /v-else/v-else-if)

v-if、v-else、v-else-if 用于根据条件动态渲染元素。

<template><div><p v-if="score >= 90">优秀</p><p v-else-if="score >= 60">及格</p><p v-else>不及格</p><button @click="score += 10">加分</button><button @click="score -= 10" :disabled="score < 10">减分</button><p>当前分数:{{ score }}</p></div></template><script setup>import { ref } from 'vue'const score = ref(70)</script>

v-if 会根据条件决定是否渲染元素,如果条件为 false,元素会被从 DOM 中移除;而 v-show 则是通过 display: none 控制元素的显示与隐藏,元素始终存在于 DOM 中。通常,频繁切换显示状态时使用 v-show 性能更好,条件很少改变时使用 v-if 更合适。

2.2.5 列表渲染(v-for)

v-for 用于基于数组或对象渲染列表,语法为 v-for="(item, index) in items",其中 item 是数组元素,index 是元素的索引(可选)。

<template><div><h3>数组渲染</h3><ul><li v-for="(fruit, index) in fruits" :key="index">{{ index + 1 }}. {{ fruit }}</li></ul><h3>对象渲染</h3><ul><li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li></ul></div></template><script setup>import { ref, reactive } from 'vue'const fruits = ref(['苹果', '香蕉', '橙子'])const user = reactive({name: '张三',age: 25,gender: '男'})</script>

使用 v-for 时,必须为每个列表项指定 key 属性,key 的值应该是唯一的(通常使用数据的唯一标识,如 ID),以便 Vue 能够高效地跟踪列表项的变化,优化渲染性能。

2.3 事件修饰符

事件修饰符用于处理事件的默认行为或事件冒泡等问题,通过 .修饰符 的形式添加到 v-on 指令后。

常用的事件修饰符:

  • .stop:阻止事件冒泡
  • .prevent:阻止事件的默认行为
  • .once:事件只触发一次
  • .self:只有事件目标是当前元素时才触发事件
<template><div @click="parentClick"><button @click.stop="childClick">点击(阻止冒泡)</button><a href="https://vuejs.org" @click.prevent="handleLinkClick">Vue 官网(阻止跳转)</a><button @click.once="onceClick">只点击一次</button></div></template><script setup>const parentClick = () => {console.log('父元素点击事件')}const childClick = () => {console.log('子元素点击事件')}const handleLinkClick = () => {console.log('链接被点击')}const onceClick = () => {console.log('只触发一次')}</script>
  • 在上述示例中:

  • .stop 阻止了子元素的点击事件冒泡到父元素,因此点击按钮时只会触发 childClick,不会触发 parentClick。
  • .prevent 阻止了链接的默认跳转行为,点击链接时只会执行 handleLinkClick。
  • .once 使按钮的点击事件只触发一次。
http://www.lryc.cn/news/605056.html

相关文章:

  • 推客系统开发全流程解析:从概念到落地的完整指南
  • 论文Review LSLAM BALM | 经典激光SLAM方案!港大MARS出品!RAL2021 | 激光BA优化
  • RocketMQ 核心特性解析及与 Kafka区别
  • Spring AI 海运管理应用第2部分
  • Centos 7.9安装部署cobbler-自动化部署服务器完整教程
  • 数据结构第3问:什么是线性表?
  • 从0开始学linux韦东山教程Linux驱动入门实验班(7)
  • 不止 “听懂”,更能 “感知”!移远通信全新AI 音频模组 重新定义智能家居“听觉”逻辑
  • 【Datawhale AI夏令营】科大讯飞AI大赛(大模型技术)/夏令营:让AI理解列车排期表(Task3)
  • 如何将DICOM文件制作成在线云胶片
  • 一句话指令实现“2D转3D”、“图片提取线稿”
  • Kong API Gateway深度解析:插件系统与微服务架构的技术基石
  • Python爬虫05_Requests肯德基餐厅位置爬取
  • 企业微信API接口发消息实战:从0到1的技术突破之旅
  • 新注册企业信息查询“数据大集网”:驱动企业增长的源头活水
  • 笔试——Day23
  • C++ 项目 QML QtQuick.Controls“ is not installed
  • 【C语言】深度剖析指针(二):指针与数组,字符,函数的深度关联
  • 基于 Amazon Bedrock 与 Anthropic Claude 3 智能文档处理方案:从扫描件提取到数据入库全流程实践
  • C++入门基础 1
  • 【MySQL 数据库】MySQL索引特性(二)页目录(B和B+树)(非)聚簇索引 索引操作
  • 293F细胞是什么?
  • Service Mesh
  • 使用HaiSnap做了一款取件码App(一键生成)
  • 修改Windows鼠标滚轮方向
  • Haproxy 七层代理深度解析
  • 《校园生活平台从 0 到 1 的搭建》第五篇:商品后端
  • Qt 嵌入式 Linux 系统定制全指南
  • Nuxt3 全栈作品【通用信息管理系统】用户管理(含重置密码)
  • 第十二天:C++ 标准库函数分类总结