前端学习笔记 3:Vue 工程

前端学习笔记 3:Vue 工程

上一篇文章介绍了如何在单一 Html 页面中使用 Vue,本文介绍如何从头开始用 Vue 构建一个前端工程项目。

环境准备

Vue 框架代码的创建依赖于 Node.js,因此需要先安装 Node.js。

创建和启动

创建

通过以下命令可以创建 Vue 的框架代码:

npm create vue@latest
  • 该命令执行后会先检查是否安装 create-vue 工具,如果没有,就安装。然后再使用 create-vue 创建框架代码。
  • npm(Node Package Manager)是 NodeJS 的包管理工具,类似于 Linux 的 RPM 或 YUM。

在执行过程中会询问是否启用一些功能模块:

Vue.js - The Progressive JavaScript Framework√ 请输入项目名称: ... vue-project
√ 是否使用 TypeScript 语法? ... 否 / 是
√ 是否启用 JSX 支持? ... 否 / 是
√ 是否引入 Vue Router 进行单页面应用开发? ... 否 / 是
√ 是否引入 Pinia 用于状态管理? ... 否 / 是
√ 是否引入 Vitest 用于单元测试? ... 否 / 是
√ 是否要引入一款端到端(End to End)测试工具? » 不需要
√ 是否引入 ESLint 用于代码质量检测? ... 否 / 是

默认是

安装好框架代码后,还需要进入工程目录安装相关依赖:

cd .\vue-project\
npm install

启动

执行npm run dev命令可以启动 Vue 项目:

VITE v5.0.10  ready in 2711 ms➜  Local:   http://localhost:5173/
➜  Network: use --host to expose
➜  press h + enter to show help

就像控制台提示信息中显示的,运行 Vue 项目的 Nodejs 服务端地址默认是 http://localhost:5173/,前往该地址就能看到一个默认的欢迎页面。

除了命令行启动外,还可以用 VSCode 启动:

image-20231231190912113

如果界面上没有 NPM 脚本 这一栏,可以通过这里开启:

image-20231231191034895

快速开始

下面简单分析一下工程默认的欢迎页的显示逻辑。

实际上浏览器访问时加载的是index.html文件:

image-20231231192645949

该文件通过<script type="module" src="/src/main.js"></script>这行代码以模块化的方式加载了 JS 文件/src/main.js

image-20231231192815009

main.js中,通过import { createApp } from 'vue'导入了 Vue 的createApp函数,与之前不同的是,因为已经用 npm 工具安装了本地依赖(npm install),所以这里是通过本地导入,而非从在线的 JS 文件导入 Vue 函数。

npm 安装的本地依赖模块位于node_modules目录下。

这里最重要的是import App from './App.vue',从App.vue文件导入了一个 App 对象,之后的代码createApp(App).mount('#app')使用该对象作为参数创建了 Vue 实例。

App.vue文件包含三部分:

image-20231231193442841

事实上,在开发基于 Vue 的前端项目时,我们主要工作是创建和修改 Vue 文件。

作为示例,这里可以创建一个Hello.vue

<template><h1>Hello World!</h1>
</template>
<style>
h1 {color: aqua;
}
</style>

要在页面中显示,还需要在main.js中替换导入代码:

import App from './Hello.vue'

在 Vue 文件中同样可以像前文那样为 Vue 实例提供数据和方法:

<script>
export default {data() {return {msg: 'Hello World!'}}
}
</script>
<template><h1>{{ msg }}</h1>
</template>

这里通过export default {...}指定了Hello.vue文件默认导出的对象内容,该对象会在main.js中导入为App对象,也就是用于创建 Vue 实例的参数对象,因此我们可以在export default {...}定义的默认导出对象中定义datamethods等 Vue 需要的方法或属性。

除了上面的方式外,还可以借助ref函数定义数据或方法:

<script setup>
import {ref} from 'vue'
const msg = ref('Hello World!')
</script>

注意,这里的scriptsetup属性。

API 风格

Vue 的 API 有两种风格,这里分别用两种风格编写同样的功能页面进行说明。

选项式

定义一个 Count.vue 文件:

<script>
export default {data() { //定义响应式数据return {num: 0}},methods: { // 定义 Vue 方法count() {this.num++;}},mounted(){ // 定义钩子函数console.log("Vue 实例已加载...")}
}
</script>
<template><button @click="count">count:{{ num }}</button>
</template>

要让该文件生效,还要在Hello.vue中导入:

<script setup>
import {ref} from 'vue'
const msg = ref('Hello World!')
import Count from './Count.vue'
</script>
<template><h1>{{ msg }}</h1><br/><Count/>
</template>

注意 >Count/> 标签,该标签的位置代表 Count.vue 文件中的模版插入的位置。

选项式的优点在于结构简单,便于理解,缺点是代码结构过于死板,不够灵活。

组合式

<script setup>
import { ref, onMounted } from 'vue'
// 定义响应式数据
const num = ref(0)
// 定义 Vue 方法
function count() {num.value++;
}
// 定义钩子函数
onMounted(() => {console.log("Vue 实例已加载...")
})
</script>
<template><button @click="count">count:{{ num }}</button>
</template>

在组合式 API 中,需要用ref函数定义响应式数据,用特定的函数(比如 onMounted)定义 Vue 生命周期的钩子方法。特别需要注意的是,组合式 API 中,ref定义的响应式数据有一个value属性,表示响应式数据的值,因此这里在count函数中,自增使用的是num.value++而非num++

案例

下面是一个简单案例,用 Vue 工程的方式创建一个ArticleList.vue,用于展示文章列表和搜索框。

在编写这个 Vue 文件之前,需要先在本地安装 axios 的依赖:

npm install axios

下面是ArticleList.vue的完整内容:

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
// 创建表格对应的响应式数据
const articles = ref([])
// Vue 实例初始化后加载表格数据
onMounted(() => {axios.get("http://localhost:8080/article/getAll").then(result => {articles.value = result.data}).catch(error => {console.log(error)})
})
// 创建搜索条件对应的响应式数据
const conditions = ref({category: '',state: ''
})
// 定义搜索绑定事件
const search = () => {axios.get("http://localhost:8080/article/search", { params: {...conditions.value} }).then(result => {articles.value = result.data}).catch(error => {console.log(error)})
} 
</script>
<template><div>文章分类:<input type="text" v-model="conditions.category"/>发布状态:<input type="text" v-model="conditions.state"/><button @click="search">搜索</button><br /><br /><table border="1"><tr><td>文章标题</td><td>分类</td><td>发表时间</td><td>状态</td><td>操作</td></tr><tr v-for="article in articles"><td>{{ article.title }}</td><td>{{ article.category }}</td><td>{{ article.time }}</td><td>{{ article.state }}</td><td><button>编辑</button><button>删除</button></td></tr></table></div>
</template>

注意,这里search函数内调用axios.get方法传参时使用了 ES6 的解构赋值:

{ params: {...conditions.value} }

这样可以让代码更简洁。

当然你也可以使用传统匿名函数分别给属性赋值的方式。

封装函数

上面的案例有一个缺陷——通过 Axios 调用接口获取数据的部分没有单独封装成函数,这样不利于其它部分的代码进行复用。更好的做法是将这些会被复用的逻辑抽取成单独的函数保存在单独的 JS 文件中,在需要使用的地方导入所需的函数并进行调用。

首先在src目录下创建一个/api/article.js文件:

import axios from 'axios'export async function getAllArticlesService(){return await axios.get("http://localhost:8080/article/getAll").then(result => {return result.data}).catch(error => {console.log(error)})
}

ArticleList.vue 进行重构:

import { getAllArticlesService } from '@/api/article.js'
// ...
// Vue 实例初始化后加载表格数据
onMounted(async () => {articles.value = await getAllArticlesService()
})

需要注意的是,这里使用了awaitasync关键字,这是因为抽取后的函数getAllArticlesService中的axios.get本质上是异步调用,因此没办法同步地获取其返回值,所以需要在调用时添加await关键字将其变成同步调用,而此时进行调用的函数(getAllArticlesService)本身变成了异步,所以要添加async关键字。同理,在调用onMounted钩子方法时,同样需要给作为参数的匿名函数加上async,并且在其中的getAllArticlesService调用加上await

  • 如果不使用awaitasync,就不会有任何数据加载。因为异步调用的关系,响应式数据的赋值语句实际上还没有等到异步调用执行并返回就已经被主线程执行完毕,所以不会有任何实际数据被赋值。
  • 在导入时,如果导入的是本地src目录下的资源,可以使用@/代表src目录。

搜索文章相关调用同样可以进行封装,这里不再赘述。

axios 实例

上面的案例还存在一个瑕疵,单个 JS 文件中的多次 Axios 调用实际上使用的是相同的服务端域名(HOST),只是具体的接口路径不同。针对这个问题,可以使用 Axios 实例进行简化和统一设置:

import axios from 'axios'
const instance = axios.create({baseURL: 'http://localhost:8080'
});export async function getAllArticlesService() {return await instance.get("/article/getAll").then(result => {return result.data}).catch(error => {console.log(error)})
}

axios 拦截器

使用axios进行异步请求时,往往需要对响应结果进行相似的处理,比如:

instance.get("/article/getAll").then(result => {return result.data}).catch(error => {console.log(error)})

对此,可以创建一个单独的 axios 实例进行复用,并且在这个实例上定义请求/响应拦截器对请求或响应进行统一处理。

添加/util/request.js

import axios from 'axios'
const instance = axios.create({baseURL: 'http://localhost:8080'
});
instance.interceptors.response.use(result => {return result.data},error => {console.log(error)return Promise.reject(error);}
)
export default instance

interceptors.response.use用于设置响应拦截器,接收两个参数,分别为调用成功(HTTP 状态码 2XX)和调用失败(HTTP 状态码不是 2XX)时的回调函数。

article.js中导入:

import request from '@/util/request.js'export async function getAllArticlesService() {return await request.get("/article/getAll")
}export async function searchService(conditions) {return await request.get("/article/search", { params: conditions })
}

因为实例request设置了响应拦截器对结果进行统一处理,所以这里不需要再使用.then.catch进行处理。

实际上内层的awaitasync关键字是可以省略的,只要最外层调用有即可:

import request from '@/util/request.js'export function getAllArticlesService() {return request.get("/article/getAll")
}export function searchService(conditions) {return request.get("/article/search", { params: conditions })
}

谢谢阅读,本文的完整示例代码见这里。

参考资料

  • 1.1 ES6 教程 | 菜鸟教程 (runoob.com)
  • 拦截器 | Axios中文文档 | Axios中文网 (axios-http.cn)

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

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

相关文章

Spring通信传参的方法

Spring通信传参的方法 目录概述需求&#xff1a; 设计思路实现思路分析1.简单参数传递2.复合参数3.动态参数 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better resul…

C#中字母与ASCⅡ码的转换

目录 一、关于ASCⅡ及与字符互转 1.主要用到Encoding对象的GetBytes方法 2.Char显式转换为数值类型得到ASCⅡ 二、实例 三、生成效果 四、程序中的一些知识点 1.IsLetterOrDigit() 2.GetBytes() 3.TryParse(string, out int) 一、关于ASCⅡ及与字符互转 ASCⅡ(Americ…

计算机网络的接口

计算机网络接口是计算机与网络通信设备之间进行通信的重要部分&#xff0c;它提供了计算机连接到网络的物理和逻辑接口&#xff0c;是计算机进行网络通信的重要组成部分。本文将介绍计算机网络接口的基本概念&#xff0c;不同类型的网络接口及其特点&#xff0c;以及在实际应用…

KBDNO1.DLL文件缺失,软件或游戏无法启动运行,怎样快速修复

不少小伙伴&#xff0c;求助电脑报错“KBDNO1.DLL文件缺失&#xff0c;软件或游戏无法启动或运行”&#xff0c;应该怎么办&#xff1f; 首先&#xff0c;我们先来了解“KBDNO1.DLL文件”是什么&#xff1f; KBDNO1.DLL是Windows操作系统中的一个动态链接库文件&#xff0c;主…

连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver‘,亲测有效!!!

Jmeter连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver’ 1.到官方下载驱动注意&#xff1a;根据项目的JDK版本来下载对应的驱动Download | pgJDBC 2.将postgresql-42.2.27.jar复制到lib目录下面&#xff0c; 然后重新启动 连接driver信息如下&#…

【LeetCode:69. x 的平方根 | 二分】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

印尼小胖子表情包大全

印尼小胖子tatan表情包大全 想要更多表情包&#xff0c;访问cmay表情包大全

二叉树的前序遍历 、二叉树的最大深度、平衡二叉树、二叉树遍历(leetcode)

目录 一、二叉树的前序遍历 方法一&#xff1a;全局变量记录节点个数 方法二&#xff1a;传址调用记录节点个数 二、二叉树的最大深度 三、平衡二叉树 四、二叉树遍历 一、二叉树的前序遍历 方法一&#xff1a;全局变量记录节点个数 计算树的节点数: 函数TreeSize用于递…

机器视觉在医学影像与医疗领域的应用及前景

引言 随着人工智能技术的飞速发展&#xff0c;机器视觉在医学影像和医疗领域中扮演着越来越重要的角色。机器视觉技术如何在医院领域提高诊断准确性、加快治疗流程以及改善患者体验。本文将探讨机器视觉算法的重要性、使用场景&#xff0c;并对其在医院领域应用的前景提出个人见…

计算机毕业设计-----SSM场地预订管理系统

项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 用户角色包含以下功能&#xff1a; 按分类查看场地,用户登录,查看网站公告,按分类查看器材,查看商品详情,加入购物车,提交订单,查看订单,修改个人信息等功能。 管理员角…

分布式【Zookeeper】

1.1 ZooKeeper 是什么 ZooKeeper 是 Apache 的顶级项目。ZooKeeper 为分布式应用提供了高效且可靠的分布式协调服务&#xff0c;提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面&#xff0c;ZooKeeper 并没有直接采用 Paxos 算法&…

爬虫工作量由小到大的思维转变---<第三十四章 Scrapy 的部署scrapyd+Gerapy>

前言: scrapy-redis没被部署,感觉讲起来很无力;因为实在编不出一个能让scrapy-redis发挥用武之地的案子;所以,索性直接先把分布式爬虫的部署问题给讲清楚!! 然后,曲线救国式地再在部署的服务器上,讲scrapy redis我感觉这样才好! 正文: 现在还有不少人在用scrapy web进行爬虫管…

2024,启动(回顾我的2023)

零.前言 打开博客想写个年度总结&#xff0c;发现已经半年没有更新文章了&#xff0c;排名从几千掉到了几万&#xff0c;不过数据量还是不错的。 时间过得可真快&#xff0c;2023年是充满动荡的一年&#xff0c;上半年gpt横空出世&#xff0c;下半年各种翻车暴雷吃瓜吃到嘴软…

系统编程--VIM

这里写目录标题 vim三种工作模式进入文本模式的快捷键在命令模式下进行文本编辑 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 vim 三种工作模式 具体可见第二章对vim的详细介绍 …

第二节 linux操作系统安装与配置

一&#xff1a;Vmware虚拟机安装与使用   ①VMware是一个虚拟PC的软件&#xff0c;可以在现有的操作系统上虚拟出一个新的硬件环境&#xff0c;相当于模拟出一台新的PC &#xff0c;以此来实现在一台机器上真正同时运行多个独立的操作系统。   ②VMware主要特点&#xff1a…

ES6 Module详解

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

SELinux 基本原理

本文讲述 SELinux 保护安全的基本原理 首发公号&#xff1a;Rand_cs 安全检查顺序 不废话&#xff0c;直接先来看张图 当我们执行系统调用的时候&#xff0c;会首先对某些错误情况进行检查&#xff0c;如果失败通常会得到一些 error 信息&#xff0c;通过查看全局变量 errno …

基于Flutter构建小型新闻App

目录 1. 概述 1.1 功能概述 1.2 技术准备 1.3 源码地址 2. App首页 2.1 pubspec依赖 2.2 热门首页组件 2.2.1 DefaultTabController 2.2.2 Swiper 2.3 新闻API数据访问 2.4 热门首页效果图 3. 新闻分类 3.1 GestureDetector 3.2 新闻分类效果图 4. 收藏功能 4…

知识付费小程序系统源码:轻松实现 一站啊运营模式+完整的代码包 附安装部署的矫教程

在当今社会&#xff0c;知识的价值愈发凸显。人们对于优质内容的渴求&#xff0c;使得知识付费市场不断扩大。然而&#xff0c;对于许多内容创作者而言&#xff0c;搭建和维护一个知识付费平台的成本较高&#xff0c;技术门槛也相对较高。下面小编来和大家分享一款知识付费小程…

【Reading Notes】(2)

文章目录 FreestyleHip-hop dance and MusicProgrammerMaster Freestyle 都说人的成长有三个阶段&#xff0c;第一个阶段认为自己独一无二&#xff0c;天之骄子&#xff1b;第二个阶段发现自己原来如此渺小&#xff0c;如此普通&#xff0c;沮丧失望&#xff1b;第三阶段&#…