苍穹外卖(前端)

苍穹外卖(前端)

创建前端工程:

环境要求:

基于脚手架创建前端工程,需要具备如下环境要求:

node.js:前端项目的运行环境

npm:JavaScript 的包管理工具

Vue CLI:基于 Vue 进行快速开发的完整系统,实现交互式的项目脚手架

操作过程:

使用 Vue CLI 创建前端工程

方式一:vue create 项目名称

方式二:vue ui

工程结构:

文件/目录介绍
node_modules当前项目依赖的 js 包
assets静态资源存放目录
components公共组件存放目录
App.vue项目的主组件,页面的入口文件
main.js整个项目的入口文件
package.json项目的配置信息、依赖包管理
vue.config.jsvue-cli 配置文件

启动服务:

使用 VS Code 打开创建的前端工程,启动前端工程:

访问前端工程:

在 vue.config.js 中配置前端服务端口号防止冲突:

Vue 使用方式:

Vue 组件:

Vue 的组件文件以 .vue 结尾,每个组件由三部分组成:

结构 <template>,样式 <style>,逻辑 <script>

文本插值:

作用:用来绑定 data 方法返回的对象属性

用法:{{插值表达式}}

<template> <div> <h1>{{ name }}</h1> <h1>{{ age > 60 ? '老年' : '青年' }}</h1> </div> </template> <script> export default { data() { return { name: '张三', age: 30 } } } </script>

属性绑定:

作用:为标签的属性绑定 data 方法中返回的属性

用法:v-bind:xxx,简写为 :xxx

<template> <div> <div><input type="text" v-bind:value="name"></div> <div><input type="text" :value="age"></div> <div><img :src="src"/></div> </div> </template> <script> export default { data() { return { name: '李四', age: 30, src: 'https://img2.baidu.com/it/u=3423222222,2822222222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500' } } } </script>

事件绑定:

作用:为元素绑定对应的事件

用法:v-on:xxx,简写为 @xxx

<template> <div> <div> <input type="button" value="保存" v-on:click="handleSave"/> <input type="button" value="保存" @click="handleSave"/> </div> </div> </template> <script> export default { data() { return { name: '王五' } }, methods: { handleSave(){ alert(this.name) } } } </script>

双向绑定:

作用:表单输入项和 data 方法中的属性进行绑定,任意一方改变都会同步给另一方

用法:v-mode

<template> <div> <div> 双向绑定: {{ name }} <input type="text" v-model="name"/> <input type="button" value="改变" @click="handleChange"/> </div> </div> </template> <script> export default { data() { return { name: '张三' } }, methods: { handleChange(){ this.name = '李四' } } } </script>

条件渲染:

作用:根据表达式的值来动态渲染页面元素

用法:v-if、v-else、v-else-if

<template> <div> <div v-if="sex == 1"> 男 </div> <div v-else-if="sex == 2"> 女 </div> <div v-else> 未知 </div> </div> </template> <script> export default { data() { return { sex: 1 } } } </script>

Axios:

Axios 是一个基于 promise 的网络请求库,作用于浏览器和 node.js 中,使用 Axios 可以在前端项目中发送各种方式的 http 请求

安装命令:npm install axios

导入:import axios from 'axios'

参数说明:url:请求路径;data:请求体数据,最常见的是 Json 格式数据;config:配置对象,可以设置查询参数、请求头信息

注意:在使用 axios 时,经常会遇到跨域问题;为了解决该问题,可以在 vue.config.js 文件中配置代理:

const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { port: 7070, proxy: { '/api': { target: 'http://localhost:8080', pathRewrite: { '^/api': '' } } } } })

Axios 的 Post 请求示例:

axios.post('/api/admin/employee/login',{       username:'admin',       password: '123456'     }).then(res => {       console.log(res.data)     }).catch(error => {       console.log(error.response)     })

Axios 的 Get 请求示例:

axios.get('/api/admin/shop/status',{         headers: {           token: ‘xxx.yyy.zzz’         }       })

Axios 提供的统一使用方式示例(可以发送各种方式的请求):

axios({       url: '/api/admin/employee/login',       method:'post',       data: {         username:'admin',         password: '123456'       }     }).then((res) => {       console.log(res.data.data.token)       axios({         url: '/api/admin/shop/status',         method: 'get',         params: {id: 100},         headers: {           token: res.data.data.token         }       })     }).catch((error) => {       console.log(error)     })

路由 Vue-Router:

介绍:

Vue 属于单页面应用,所谓路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容

在 Vue 应用中使用路由功能,需要安装 Vue-Router:

创建完带有路由功能的前端项目后,在工程中会生成一个路由文件用于路由的配置:

在前端项目的入口文件中创建 Vue 实例时,需要指定路由对象才能使用路由功能:

路由配置:

路由组成:

VueRouter:路由器,根据路由请求在路由视图中动态渲染对应的视图组件

<router-link>:路由链接组件,浏览器会解析成 <a>

<router-view>:路由视图组件,用来展示与路由路径匹配的视图组件

具体配置方式:

在路由文件中配置路由路径和视图的对应关系:

import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue' Vue.use(VueRouter) //维护路由表,某个路由路径对应哪个视图组件 const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue') } , { path: '/404', component: () => import('../views/404View.vue') }, { path: '*', redirect: '/404' //重定向 } ] const router = new VueRouter({ routes }) export default router

在视图组件中配置 router-link 标签,用于生成超链接:

<router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <router-link to="/test">Test</router-link> |

在视图组件汇总配置 router-view 标签:

<template> <div> <nav> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <router-link to="/test">Test</router-link> | </nav> <!-- 视图组件展示的位置 --> <router-view/> </div> </template>

要实现路由跳转,可以通过标签式和编程式两种方式:

标签式:

<router-link to="/about">About</router-link>

编程式:

<template> <div> <nav> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <router-link to="/test">Test</router-link> | <input type="button" value="编程式路由跳转" @click="jump"/> </nav> <!-- 视图组件展示的位置 --> <router-view/> </div> </template> <script> export default { methods: { jump() { //使用编程式路由跳转方式 this.$router.push('/about') } } } </script>

嵌套路由:

嵌套路由:组件内要切换内容,就需要用到嵌套路由(子路由),效果如下:

在 App.vue 视图组件中有 <router-view> 标签,其他视图组件可以展示在此

ContainerView.vue 组件可以展示在 App.vue 视图组件的 <router-view> 位置

ContainerView.vue 组件进行了区域划分(分为上、左、右),在右边编写了 <router-view> 标签,点击左侧菜单时,可以将对应的子视图组件展示在此

实现步骤:

安装并导入 Elementui,实现页面布局(Container 布局容器):

ContainerView.vue:

<template> <el-container> <el-header>Header</el-header> <el-container> <el-aside>Aside</el-aside> <el-main> </el-main> </el-container> </el-container> </template> <script> export default { } </script> <style> .el-header, .el-footer { background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #D3DCE6; color: #333; text-align: center; line-height: 200px; } .el-main { background-color: #E9EEF3; color: #333; text-align: center; line-height: 160px; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } </style>

提供子视图组件,用于效果展示,P1View.vue、P2View.vue、P3View.vue:

<template> <div> 这是P1 View </div> </template> <script> export default { } </script> <style> .el-header, .el-footer { background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #D3DCE6; color: #333; text-align: center; line-height: 200px; } .el-main { background-color: #E9EEF3; color: #333; text-align: center; line-height: 160px; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } </style>

在 src/router/index.js 中配置路由映射规则(嵌套路由配置):

const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue') }, { path: '/404', component: () => import('../views/404View.vue') }, { path: '/c', component: () => import('../views/container/ContainerView.vue'), redirect: '/c/p1', //嵌套路由(子路由),对应的组件会展示在当前组件内部 children: [//通过children属性指定子路由相关信息(path、component) { path: '/c/p1', component: () => import('../views/container/P1View.vue') }, { path: '/c/p2', component: () => import('../views/container/P2View.vue') }, { path: '/c/p3', component: () => import('../views/container/P3View.vue') } ] }, { path: '*', redirect: '/404' } ]

在 ContainerView.vue 布局容器视图中添加 <router-view>,实现子视图组件展示:

<template> <el-container> <el-header>Header</el-header> <el-container> <el-aside>Aside</el-aside> <el-main> <router-view/> </el-main> </el-container> </el-container> </template>

在 ContainerView.vue 布局容器视图中添加 <router-link>,实现路由请求:

<template> <el-container> <el-header>Header</el-header> <el-container> <el-aside> <router-link to="/c/p1">P1</router-link><br> <router-link to="/c/p2">P2</router-link><br> <router-link to="/c/p3">P3</router-link><br> </el-aside> <el-main> <router-view/> </el-main> </el-container> </el-container> </template>

状态管理 Vuex:

介绍:

Vuex 是一个专为 Vue.js 应用程序开发的状态管理库;可以在多个组件之间共享数据,并且共享的数据是响应式的,即数据的变更能及时渲染到模板;它采用集中式存储管理所有组件的状态

Vuex 应用的核心是 store(仓库),包含着你的应用中大部分的状态(state),改变 store 中的状态的唯一途径就是显式地提交(commit)mutation

安装 Vuex:npm install vuex@next --save

核心概念说明
state状态对象,集中定义各个组件共享的数据
mutations类似于一个事件,用于修改共享数据,要求必须是同步函数
actions类似于 mutation,可以包含异步操作,通过调用 mutation 来改变共享数据

使用方式:

第一步:创建带有 Vuex 功能的前端项目

在创建的前端工程中,自动创建了相关的文件:

在前端项目的入口文件中创建 Vue 实例时,需要将 store 对象传入 :

第二步:在 src/store/index.js 文件中集中定义和管理共享数据

import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) //集中管理多个组件共享的数据 export default new Vuex.Store({ //集中定义共享数据 state: { name: '未登录游客' }, getters: { }, //通过当前属性中定义的函数修改共享数据,必须都是同步操作 mutations: { }, //通过actions调用mutation,在actions中可以进行异步操作 actions: { }, modules: { } })

第三步: 在视图组件中展示共享数据

注:$store.state 为固定写法,用于访问共享数据

第四步:在 mutations 中定义函数,用于修改共享数据

//集中管理多个组件共享的数据 export default new Vuex.Store({ //集中定义共享数据 state: { name: '未登录游客' }, getters: { }, //通过当前属性中定义的函数修改共享数据,必须都是同步操作 mutations: { setName(state,newName) { state.name = newName } }, //通过actions调用mutation,在actions中可以进行异步操作 actions: { }, modules: { } })

第五步:在视图组件中调用 mutations 中定义的函数

第六步:如果在修改共享数据的过程中有异步操作,则需要将异步操作的代码编写在 actions 的函数中

//集中管理多个组件共享的数据 export default new Vuex.Store({ //集中定义共享数据 state: { name: '未登录游客' }, getters: { }, //通过当前属性中定义的函数修改共享数据,必须都是同步操作 mutations: { setName(state,newName) { state.name = newName } }, //通过actions调用mutation,在actions中可以进行异步操作 actions: { setNameByAxios(context){ axios({ //异步请求 url: '/api/admin/employee/login', method: 'post', data: { username: 'admin', password: '123456' } }).then(res => { if(res.data.code == 1){ //异步请求后,需要修改共享数据 //在actions中调用mutation中定义的setName函数 context.commit('setName',res.data.data.name) } }) } }, modules: { } })

第七步:在视图组件中调用 actions 中定义的函数

TypeScript:

介绍:

TypeScript(简称:TS) 是微软推出的开源语言,是 JavaScript 的超集,TypeScript = Type + JavaScript(在 JS 基础上增加了类型支持),TypeScript 文件扩展名为 ts;TypeScript 可编译成标准的 JavaScript,并且在编译时进行类型检查

安装命令:npm install -g typescript

TS 属于静态类型编程语言,在编译期做类型检查(可在编写代码的同时发现错误);而 JS 属于动态类型编程语言,在执行期做类型检查

创建基于 TS 的前端工程:

常用类型:

类型
字符串类型string
数字类型number
布尔类型boolean
数组类型number[],string[], boolean[] 等
任意类型any
复杂类型type 与 interface
函数类型() => void
字面量类型"a"|"b"|"c"
class 类class Animal

类型标注的位置:

标注变量、标注参数、标注返回值

//标注变量,指定变量 msg 的类型为string let msg:string = 'hello ts !' //标注参数和返回值,指定 m2 函数的参数类型 为string,并且返回值也为 string const m2 = (name:string):string => { return name.toLowerCase() + msg }

字符串、数字、布尔类型:

//定义字符串类型的变量 let username: string = 'zhu' //定义布尔类型的变量 let isTrue: boolean = false //定义数字类型的变量 let age: number = 19 console.log(username) console.log(isTrue) console.log(age)

字面量类型:

// 字面量类型,指定参数 alignment 的取值只能是 left、right、center function printText(s: string, alignment: "left" | "right" | "center") { console.log(s, alignment) } printText("hello", "left") printText("hello", "aaa") // 错误:取值只能是 left | right | center

interface 类型:

//定义接口Cat,规定对象必须包含name(string)和age(number)属性 interface Cat { name: string, age: number } //合法:属性完全匹配接口 const c1: Cat = { name: '耄耋', age: 1 } //错误示例: //const c2: Cat = { name: '大开门' } //缺少age属性 //const c3: Cat = { name: '听泉', age: 1, sex: '公' } //多出sex属性 console.log(c1)
//接口Cat中,age为可选属性(用?标记) interface Cat { name: string, age?: number // 可选属性:可以存在或不存在 } //合法:可选属性age可省略 const c1: Cat = { name: '耄耋' } //合法:可选属性age也可包含 const c2: Cat = { name: '大开门', age: 1 } //错误示例: //const c3: Cat = { name: '听泉', age: 1, sex: '公' } //多出sex属性

class 类型:

//定义类User,包含属性和方法 class User { name: string; //类的属性 //构造方法:创建实例时初始化属性 constructor(name: string) { this.name = name } //类的方法 study() { console.log(`${this.name}正在学习`) } } //创建User类的实例 const u = new User('张三') console.log(u.name) //输出:张三 u.study() //输出:张三正在学习
//定义接口Animal,规定必须包含name属性和eat方法 interface Animal { name: string eat(): void } //类Bird实现接口Animal,必须实现接口的所有属性和方法 class Bird implements Animal { name: string; constructor(name: string) { this.name = name } //实现接口的eat方法 eat(): void { console.log(this.name + ' eat') } } //创建Bird实例 const b1 = new Bird('鸽子') console.log(b1.name) //输出:鸽子 b1.eat() //输出:鸽子 eat
//Parrot类继承Bird类,自动获得Bird的属性和方法 class Parrot extends Bird { //新增自己的方法 say(): void { console.log(this.name + ' say hello') } } //创建Parrot实例 const myParrot = new Parrot('Polly') myParrot.say() //输出:Polly say hello(自己的方法) myParrot.eat() //输出:Polly eat(继承自Bird的方法)

Read more

OpenClaw 完整安装与配置文档(包含Minimax/deepseek模型接入、飞书机器人接入)

OpenClaw 完整安装与配置文档 文档说明:本文档适用于 Linux 系统(Debian/Ubuntu 系列),详细梳理 OpenClaw 从基础环境准备、核心程序安装,到模型配置(Minimax/DeepSeek)、飞书渠道对接的全流程,所有交互式配置选项完整呈现,步骤可直接复制执行,适配新手操作。 适用场景:OpenClaw 新手部署、企业内部飞书机器人对接、Minimax/DeepSeek 模型配置 前置说明: 1. 服务器需联网,确保能访问 GitHub、npm、飞书官网; 2. 操作全程使用终端命令行,建议使用远程工具(如 Xshell、Putty)连接服务器; 3. 复制命令时需完整复制,避免遗漏特殊符号; 4. 所有交互式配置选项均完整列出,按文档指引选择即可。 5. 拥有root用户/sudo权限。

最新版 springdoc-openapi-starter-webmvc-ui 常用注解详解 + 实战示例

当然可以!在 Spring Boot 3 + SpringDoc OpenAPI(Swagger 3 替代方案)生态中,springdoc-openapi-starter-webmvc-ui 是目前官方推荐的集成方式。它提供了一套丰富的注解,用于精细化控制 API 文档的生成,提升前端、测试、产品等协作方的体验。 ✅ 最新版 springdoc-openapi-starter-webmvc-ui 常用注解详解 + 实战示例 📌 当前最新稳定版本:springdoc-openapi 2.5+(2025年仍适用) 📌 所有注解位于包:io.swagger.v3.oas.annotations.* 🧩 一、核心注解概览 注解作用适用位置@OpenAPIDefinition全局 API 信息配置(标题、版本、联系人等)@Configuration 类@Tag标记 Controller 或方法所属的“标签/

Android WebRTC 视频通话开发实战:从零搭建到性能调优

快速体验 在开始今天关于 Android WebRTC 视频通话开发实战:从零搭建到性能调优 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 Android WebRTC 视频通话开发实战:从零搭建到性能调优 移动端P2P视频通话的三大挑战 开发Android端视频通话应用时,我们常遇到几个核心难题: * NAT穿透/NAT Traversal:

乡村政务办公系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】

乡村政务办公系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】

摘要 随着信息技术的快速发展,数字化政务管理成为提升乡村治理效率的重要手段。传统的乡村政务办公模式依赖纸质文档和人工操作,存在效率低、信息传递滞后、数据易丢失等问题。乡村政务信息管理系统的建设能够有效解决这些问题,实现政务信息的数字化、规范化和高效化管理。该系统通过整合SpringBoot后端、Vue前端和MySQL数据库技术,构建了一个功能完善、操作便捷的乡村政务办公平台。关键词:乡村政务、数字化管理、SpringBoot、Vue、MySQL。 该系统采用SpringBoot作为后端框架,提供高效的接口服务和数据处理能力;Vue作为前端框架,实现用户友好的交互界面;MySQL作为数据库,确保数据的稳定存储和高效查询。系统功能涵盖村民信息管理、帮扶信息管理、新闻公告发布等模块,支持数据的增删改查、多条件筛选和统计分析。系统设计注重实用性和可扩展性,能够满足乡村政务办公的多样化需求。关键词:村民信息管理、帮扶信息管理、新闻公告、数据统计分析。 数据表设计 村民信息数据表 村民信息数据表用于存储村民的基本信息,包括姓名、身份证号、联系方式等。创建时间通过函数自动获取,村民ID是该