前端刺客系列----Vue 3 入门介绍

目录

一.什么是 Vue 3?

二.Vue 3 的主要特性

三,Vue3项目实战

四.总结



在前端开发的世界里,Vue.js 作为一款渐进式的 JavaScript 框架,已成为许多开发者的首选工具。自从 Vue 3 发布以来,它带来了许多重要的改进和新特性,不仅提升了性能,还使得开发体验更加流畅。在这篇文章中,我们将详细介绍 Vue 3 的核心概念,并通过一些简单的代码示例,帮助大家快速上手 Vue 3。

一.什么是 Vue 3?

Vue.js 是一款渐进式的 JavaScript 框架,用于构建用户界面。它的设计理念非常灵活,可以逐步引入到项目中,适应不同规模的需求。Vue 3 是 Vue.js 框架的最新版本,它在 Vue 2 的基础上进行了全面的优化,带来了以下几大亮点:

性能提升:Vue 3 引入了更高效的虚拟 DOM 和组件渲染机制,使得整体性能得到了显著提升。
组合式 API (Composition API):这是一种全新的编写组件的方式,使得逻辑复用和代码组织变得更加灵活和清晰。
TypeScript 支持:Vue 3 在设计时就考虑到了 TypeScript,增强了对类型系统的支持。
更小的包体积:Vue 3 的核心库相比 Vue 2 更加精简,加载速度更快。
多个其他新特性:如 Teleport、Suspense、Fragment 等。
在这篇文章中,我们会深入探索 Vue 3 的主要新特性,并通过示例帮助大家更好地理解它。

二.Vue 3 的主要特性

1. 组合式 API (Composition API)
组合式 API 是 Vue 3 中最为重要的新增特性之一。它允许开发者通过函数的方式组织和复用逻辑,相比于 Vue 2 中的选项式 API (Options API),组合式 API 提供了更强的灵活性和可维护性。

为什么使用组合式 API?
更好的逻辑复用:组合式 API 允许将相关的逻辑封装到函数中,使得代码复用变得更加简洁。
更清晰的代码结构:你可以按照功能进行代码分离,而不再依赖于 Vue 2 中的 data、methods、computed 等选项,避免了大量冗长的逻辑。
TypeScript 更好的支持:组合式 API 更适合与 TypeScript 配合使用,因为它能更好地推导类型。
代码示例:使用组合式 API 创建一个计数器

// App.vue
<template><div><h1>{{ count }}</h1><button @click="increment">Increment</button></div>
</template><script setup>
// 引入 Composition API 中的 `ref` 函数
import { ref } from 'vue'// 定义一个响应式变量 `count`
const count = ref(0)// 定义一个方法来更新 `count`
const increment = () => {count.value++
}
</script>

在这个例子中,我们使用了 ref 函数来创建一个响应式变量 count,并用 increment 方法来更新它。ref 会将基本类型(如数字、字符串等)包装成响应式对象,通过 .value 来访问和修改其值。

2. 更高效的虚拟 DOM 和性能提升
Vue 3 在性能方面做了大量的优化。最显著的改进之一是虚拟 DOM 的实现变得更加高效。虚拟 DOM 是 Vue 用来追踪 DOM 变更的技术,它允许 Vue 对 DOM 进行精确的更新,而不是每次都完全重渲染整个页面。Vue 3 在此基础上进行了优化,使得渲染速度更快,尤其是在大规模应用中。

3. TypeScript 支持
Vue 3 从一开始就为 TypeScript 提供了更全面的支持。在 Vue 2 中,TypeScript 的集成不是特别好,而 Vue 3 则原生支持 TypeScript,提供了更好的类型推导和类型检查。

代码示例:使用 TypeScript 和 Vue 3

// App.vue
<template><div><h1>{{ count }}</h1><button @click="increment">Increment</button></div>
</template><script lang="ts" setup>
import { ref } from 'vue'const count = ref<number>(0)const increment = () => {count.value++
}
</script>

在这个示例中,我们通过 lang="ts" 声明了 Vue 文件使用 TypeScript,并为 count 使用了明确的类型定义 ref<number>(0),这保证了变量 count 始终是数字类型。

4. Teleport
Vue 3 引入了一个新的内置组件 Teleport,它允许将一个组件的内容渲染到页面的任何位置,而不是默认的父组件中。这对于某些特殊场景,比如模态框、通知等非常有用。

代码示例:使用 Teleport 实现一个模态框

<template><div><button @click="showModal = true">Open Modal</button><Teleport to="body"><div v-if="showModal" class="modal"><div class="modal-content"><p>This is a modal!</p><button @click="showModal = false">Close</button></div></div></Teleport></div>
</template><script setup>
import { ref } from 'vue'const showModal = ref(false)
</script><style>
.modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background-color: white;padding: 20px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
</style>

在这个例子中,我们使用了 Teleport 将模态框内容渲染到 body 元素下,而不是当前组件的 DOM 中。

5. Suspense 和异步组件
Vue 3 引入了 Suspense 组件,它使得异步加载的组件能够在数据加载完毕之前提供一个“加载中”的状态。这对于需要异步加载的应用非常有用,提升了用户体验。

代码示例:使用 Suspense 加载异步组件

<template><Suspense><template #default><AsyncComponent /></template><template #fallback><p>Loading...</p></template></Suspense>
</template><script setup>
import { defineAsyncComponent } from 'vue'const AsyncComponent = defineAsyncComponent(() =>import('./AsyncComponent.vue')
)
</script>

三,Vue3项目实战

项目结构

my-vue3-app/
├── public/
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── TaskList.vue
│   │   ├── TaskItem.vue
│   │   └── AddTask.vue
│   ├── store/
│   │   └── taskStore.js
│   ├── views/
│   │   ├── Home.vue
│   │   └── NotFound.vue
│   ├── router/
│   │   └── index.js
│   ├── App.vue
│   ├── main.js
├── package.json
└── vite.config.js

1. src/main.js - 项目入口文件

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createStore } from 'vuex'const app = createApp(App)app.use(router)
app.use(createStore({state: {tasks: []},mutations: {addTask(state, task) {state.tasks.push(task)},deleteTask(state, taskId) {state.tasks = state.tasks.filter(task => task.id !== taskId)},toggleTaskCompletion(state, taskId) {const task = state.tasks.find(t => t.id === taskId)if (task) {task.completed = !task.completed}},editTask(state, { taskId, updatedTask }) {const task = state.tasks.find(t => t.id === taskId)if (task) {Object.assign(task, updatedTask)}}},getters: {completedTasks: (state) => {return state.tasks.filter(task => task.completed)},pendingTasks: (state) => {return state.tasks.filter(task => !task.completed)}}
}))app.mount('#app')

2. src/router/index.js - 路由配置 

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import NotFound from '../views/NotFound.vue'const routes = [{path: '/',name: 'Home',component: Home},{path: '/:catchAll(.*)',name: 'NotFound',component: NotFound}
]const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes
})export default router

3. src/views/Home.vue - 主页视图

<template><div class="home"><h1>Task Manager</h1><AddTask /><h2>Pending Tasks</h2><TaskList :tasks="pendingTasks" /><h2>Completed Tasks</h2><TaskList :tasks="completedTasks" /></div>
</template><script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import TaskList from '../components/TaskList.vue'
import AddTask from '../components/AddTask.vue'const store = useStore()const pendingTasks = computed(() => store.getters.pendingTasks)
const completedTasks = computed(() => store.getters.completedTasks)
</script><style scoped>
.home {padding: 20px;
}
h1 {color: #42b983;
}
</style>

4. src/components/AddTask.vue - 添加任务组件

<template><div class="add-task"><input v-model="newTask" placeholder="Add a new task" @keyup.enter="addTask" /><button @click="addTask">Add Task</button></div>
</template><script setup>
import { ref } from 'vue'
import { useStore } from 'vuex'const newTask = ref('')
const store = useStore()const addTask = () => {if (newTask.value.trim()) {store.commit('addTask', {id: Date.now(),title: newTask.value,completed: false})newTask.value = ''}
}
</script><style scoped>
.add-task {margin-bottom: 20px;
}
input {padding: 8px;margin-right: 10px;width: 200px;
}
button {padding: 8px 12px;
}
</style>

5. src/components/TaskList.vue - 任务列表组件

<template><div><ul><TaskItemv-for="task in tasks":key="task.id":task="task"/></ul></div>
</template><script setup>
import TaskItem from './TaskItem.vue'
import { defineProps } from 'vue'const props = defineProps({tasks: Array
})
</script><style scoped>
ul {list-style: none;padding-left: 0;
}
</style>

6. src/components/TaskItem.vue - 任务项组件

<template><li :class="{ completed: task.completed }"><span @click="toggleCompletion">{{ task.title }}</span><button @click="deleteTask">Delete</button><button @click="editTask">Edit</button></li>
</template><script setup>
import { defineProps } from 'vue'
import { useStore } from 'vuex'const props = defineProps({task: Object
})const store = useStore()const toggleCompletion = () => {store.commit('toggleTaskCompletion', props.task.id)
}const deleteTask = () => {store.commit('deleteTask', props.task.id)
}const editTask = () => {const newTitle = prompt('Edit Task Title', props.task.title)if (newTitle && newTitle !== props.task.title) {store.commit('editTask', {taskId: props.task.id,updatedTask: { title: newTitle }})}
}
</script><style scoped>
.completed {text-decoration: line-through;
}
button {margin-left: 10px;padding: 5px 10px;cursor: pointer;
}
</style>

7. src/views/NotFound.vue - 404 页面视图

<template><div class="not-found"><h1>404 - Page Not Found</h1></div>
</template><script setup>
</script><style scoped>
.not-found {text-align: center;padding: 50px;
}
</style>

8. public/index.html - 项目 HTML 模板

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue 3 Task Manager</title>
</head>
<body><div id="app"></div>
</body>
</html>

9. package.json - 项目依赖

{"name": "vue3-task-manager","version": "1.0.0","main": "src/main.js","scripts": {"dev": "vite","build": "vite build","serve": "vite preview"},"dependencies": {"vue": "^3.2.0","vue-router": "^4.0.0","vuex": "^4.0.0"},"devDependencies": {"vite": "^4.0.0"}
}

10. vite.config.js - Vite 配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue()]
})

四.总结

    Vue 3 是 Vue.js 框架的最新版本,它带来了多个令人期待的改进和特性,旨在提升开发者体验和性能。最显著的变化是引入了 组合式 API,通过 setup() 函数和 ref、reactive 等新的响应式机制,开发者可以更灵活地组织组件逻辑,避免了 Vue 2 中的复杂选项式 API,提升了代码的可维护性和逻辑复用性。此外,Vue 3 进一步优化了性能,框架的体积比 Vue 2 小了约 30%,并且虚拟 DOM 的更新算法也得到了改进,使得更新速度更快,启动时间也大大缩短。同时,Vue 3 完美支持 TypeScript,增强了类型推导和类型检查,使得大型项目的开发更加安全和高效。Vue 3 还支持 Fragment,允许组件返回多个根节点,从而避免了不必要的 DOM 包裹元素。新加入的 Teleport 组件使得将内容渲染到页面的任意位置变得简单,例如模态框、弹窗等 UI 组件的处理更加灵活。而 Suspense 则提供了对异步组件的优雅处理,允许开发者在组件加载时显示占位符内容,改善用户体验。此外,Vue 3 与 Vite 集成紧密,Vite 作为构建工具提供了极快的热更新和构建速度,极大提升了开发效率。对于 Vue 2 的开发者,Vue 3 提供了良好的向后兼容性,使得迁移过程更加平滑,且框架支持通过 @vue/compat 模式逐步过渡。总体而言,Vue 3 是一个强大、灵活且高效的框架,既适合小型项目,也能够满足大型应用的开发需求,帮助开发者构建更现代化、响应式和可扩展的 Web 应用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文复现】MSA+抑郁症模型总结(三)

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀MSA抑郁症模型 热门研究领域&#xff1a;情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…

Linux 实验:日志的备份与恢复 xfs文件系统

添加一个新的硬盘&#xff0c;创建硬盘分区sdc1 设置文件系统格式xfs&#xff0c;提示安装xfsprogs&#xff0c;如果安装失败&#xff0c;在后缀加上--fix-missing直到安装完成为止 mkdir创建空目录data&#xff0c;将sdc1挂载到data&#xff0c;data是根目录下新建的目录&…

应对AI与机器学习的安全与授权管理新挑战,CodeMeter不断创新引领保护方案

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术正在快速发展&#xff0c;逐渐应用到全球各类主流系统、设备及关键应用场景中&#xff0c;尤其是在政府、商业和工业组织不断加深互联的情况下&#xff0c;AI和ML技术的影响日益广泛。虽然AI技术的…

证书学习(六)TSA 时间戳服务器原理 + 7 个免费时间戳服务器地址

目录 一、简介1.1 什么是时间戳服务器1.2 名词扩展1.3 用时间戳标记顺序1.4 7 个免费TSA时间戳服务器地址(亲测可用)1.5 RFC 3161 标准二、时间戳原理2.1 时间戳服务工作流程2.2 验证工作流程2.3 举个例子2.4 时间戳原理总结三、代码实现3.1 curl 命令请求时间戳3.2 java 代码…

一文快速预览经典深度学习模型(一)——CNN、RNN、LSTM、Transformer、ViT

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要简要并通俗地介绍了几种经典的深度学习模型&#xff0c;如CNN、RNN、LSTM、Transformer、ViT&#xff08;Vision Transformer&#xff09;等&#xff0c;便于大家初探深度学习的相关知识&#xff0c;并更好地理解深度学…

如何运营Github Org

目录 前言 正文 关于分支保护 特别说明 如何在Windows环境下配置GitHub Desktop GPG签名&#xff1f; 推荐分支保护选择 关于good first issue 如何设置good first issue&#xff1f; 关于Project 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learni…

接收nVisual中rabbitmq数据不成功问题排查

rabbitmq服务部署成功的情况下&#xff0c;消息对接不成功一般原因为消息发送失败&#xff0c;发送失败大多数可能为global_settings表配置错误。下面从两个方面解决消息对接不成功问题。 1.数据是否成功发送 检查global_settings表中rabbitmq发送消息配置信息是否正确 #MQS…

二叉树的实现

一.树 1.1树的概念与结构 树是一种非线性数据结构&#xff0c;由有限个结点组成的具有层次关系的集合。树的根部位置就叫根结点&#xff0c;除根结点以外&#xff0c;其余的树被分为各个互不相交的集合。树的根系只能向下延伸不能向左右延伸。除根结点以外每个结点有且仅有一…

Python基础学习-03逻辑分支语句、循环

目录 1、记住逻辑关系 2、逻辑分支语句 3、for-loop循环 4、while-loop 5、break 和 continue 6、本节总结 1、记住逻辑关系 • 逻辑关系 1&#xff09; True&#xff08;真&#xff09; 和 False&#xff08;假&#xff09; 2&#xff09;逻辑关系有 and&#xff08;与…

Spark中给读取到的数据 的列 重命名的几种方式!

目录 一、第一种 (withColumnRenamed) 二、第二种&#xff08;toDF&#xff09; 三、第三种&#xff08; toDF(*tuple1) &#xff09; 四、 第四种(schema) 五、假如文件里自带有列名的情况&#xff08;option&#xff09; 一、第一种 (withColumnRenamed) 假设要把如下…

鸿蒙UI开发——实现环形文字

1、背 景 有朋友提问&#xff1a;您好关于鸿蒙UI想咨询一个问题 如果我想实现展示环形文字是需要通过在Text组件中设置transition来实现么&#xff0c;还是需要通过其他方式来实现。 针对这位粉丝朋友的提问&#xff0c;我们做一下解答。 2、实现环形文字效果 ❓ 什么是环形…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

Rust-AOP编程实战

文章本天成,妙手偶得之。粹然无疵瑕,岂复须人为?君看古彝器,巧拙两无施。汉最近先秦,固已殊淳漓。胡部何为者,豪竹杂哀丝。后夔不复作,千载谁与期? ——《文章》宋陆游 【哲理】文章本是不加人工,天然而成的,是技艺高超的人在偶然间所得到的。其实作者所说的“天成”…

Spark的Standalone集群环境安装

一.简介 与MR对比&#xff1a; 概念MRYARNSpark Standalone主节点ResourceManagerMaster从节点NodeManagerWorker计算进程MapTask&#xff0c;ReduceTaskExecutor 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接…

SpringBoot整合Sharding-JDBC实现读写分离

SpringBoot整合Sharding-JDBC实现读写分离 Sharding-JDBC实现读写分离&#xff0c;记得先要实现数据库的主从结构先。 1、Sharding-JDBC 简介 Sharding-JDBC 是的分布式数据库中间件解决方案。Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar(计划 中)是 3 款相互独立的…

几个docker可用的镜像源

几个docker可用的镜像源 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; sudo rm -rf /etc/docker/daemon.json sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://d…

数字时代企业的基本数据丢失预防策略

在当今的数字时代&#xff0c;数据丢失预防对企业的重要性怎么强调也不为过。了解与数据丢失相关的风险至关重要&#xff0c;因为人为错误和网络攻击等常见原因可能会产生严重后果。 实施有效的数据丢失预防策略&#xff08;例如安全协议、定期数据备份和员工培训&#xff09;…

Android CCodec Codec2 (十九)C2LinearBlock

在上一篇文章的结尾&#xff0c;我们看到fetchLinearBlock方法最终创建了一个C2LinearBlock对象。这一节&#xff0c;我们将深入了解C2LinearBlock是什么&#xff0c;它的作用是什么&#xff0c;以及它是如何被创建的。 1、_C2BlockFactory 先对上一篇文章的结尾内容做简单回顾…

【EasyExcel】EasyExcel导出表格包含合计行、自定义样式、自适应列宽

目录 0 EasyExcel简介1 Excel导出工具类设置自定义表头样式设置自适应列宽添加合计行 2 调用导出工具类导出Excel表3 测试结果 0 EasyExcel简介 在数据处理和报表生成的过程中&#xff0c;Excel是一个非常常用的工具。特别是在Java开发中&#xff0c;EasyExcel库因其简单高效而…

SparkSql读取数据的方式

一、读取普通文件 方式一&#xff1a;给定读取数据源的类型和地址 spark.read.format("json").load(path) spark.read.format("csv").load(path) spark.read.format("parquet").load(path) 方式二&#xff1a;直接调用对应数据源类型的方法 …