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

Web学习笔记-Vue3(环境配置、概念、整体布局设计)

笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课。

CONTENTS

  • 1. 环境配置
  • 2. 基本概念
  • 3. 导航栏
  • 4. 页面创建
  • 5. 用户动态页面实现

Vue 官网:Vue.js。

Vue.js 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助开发者高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。Vue 的设计非常注重灵活性和“可以被逐步集成”这个特点。根据你的需求场景,你可以用不同的方式使用Vue。

Vue 与 React 的区别主要在于:

  • React 的思路是 HTML in JavaScript,也可以说是 All in JavaScript,通过 JavaScript 来生成 HTML,所以设计了 JSX 语法,还有通过 JS 来操作 CSS。
  • Vue 是把 HTML、CSS、JS 组合到一起,用各自的处理方式,Vue 有单文件组件,可以把 HTML、CSS、JS 写到一个文件中,HTML 提供了模板引擎来处理。
  • React 整体是函数式的思想,在 React 中是单向数据流,推崇结合 immutable 来实现数据不可变。
  • Vue 的思想是响应式的,也就是基于数据可变的,通过对每一个属性建立 Watcher 来监听,当属性变化的时候,响应式地更新对应的虚拟 DOM。

总的来说,React 的性能优化需要手动去做,而 Vue 的性能优化是自动的,但是 Vue 的响应式机制也有问题,就是当 state 特别多的时候,Watcher 会很多,会导致卡顿。所以大型应用(状态特别多的)一般用 React,更加可控。而考虑易用性方面,Vue 是更容易上手的,对于项目来说新人更容易接手。

1. 环境配置

首先需要安装 Node.js:NodeJS 的安装及配置(2023.10.14 V18.18.2)。

打开 PowerShell,安装 @vue/cli

npm i -g @vue/cli

Vue 相比于 React 的其中一个好处是默认提供了一个图形化的项目管理界面,在想要创建项目的文件夹下以管理员身份打开终端输入以下命令:

vue ui

然后我们创建一个名为 my_space 的项目,包管理器选择 npm,然后选上无新手指引的脚手架项目(Scaffold project without beginner instructions),预设选择 Vue3,然后创建项目。

项目创建好后在左侧能够看到导航栏,进入插件页面(Plugins)安装以下插件,其中 @vue/cli-plugin-router 用于多页面路由,@vue/cli-plugin-vuex 类似于 React 中的 Redux,可以让我们在多个组件之间维护同一个数据:

@vue/cli-plugin-router
@vue/cli-plugin-vuex

然后我们在依赖页面(Dependencies)安装 Bootstrap。

最后在任务页面(Tasks)的 serve 选项卡中可以运行项目,运行后在输出(Output)中可以看到网站链接:http://localhost:8080/,访问该链接即可看到 Vue 的初始化页面。

我们用 VS Code 打开项目的根目录,源代码位于 src 目录下,其中的 views 目录类似于 Django 中的 Views,每一个页面是一个 View;router 目录是路由,打开可以看到默认有两个路由分别是 //aboutcomponents 目录用于存放各种组件(views 也能存放组件,根据个人习惯决定);App.vue 为根组件,整个项目的入口在 main.js 文件中。

仔细看一下页面的链接会发现其中有一个 #,如果想去掉可以将 router 目录下 index.js 文件中的 createWebHashHistory 修改为 createWebHistory(有两处需要修改)。

main.js 文件中可以看到以下代码:

createApp(App).use(router).use(store).mount('#app')

其中创建了我们的根组件 Approuter 就表示路由,storevuex,然后将其挂载到 #app 标签上,该标签可以在 public/index.html 中看到。

2. 基本概念

每一个 .vue 文件都会由三个部分组成:HTML、CSS、JS。其中 CSS 的标签可以加一个属性 scoped,这样不同组件之间的 CSS 选择器就不会相互影响到了:

<style scoped>...
</style>

我们的每个页面中都可能由多个组件组成,每个组件是一个 .vue 文件,可以用以下的方式引入 HelloWorld 组件,并传递 msg 属性给该组件:

<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/></div>
</template><script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
</script>

HelloWorld 组件需要 export 出去:

<script>
export default {name: 'HelloWorld',props: {msg: String}
}
</script>

其中 props 中的属性可以在创建该组件的父组件中传递进来。

现在我们来具体了解一下 <script> 中的 export default 的参数:

  • name:组件的名称。
  • components:存储 <template> 中用到的所有组件。
  • props:存储父组件传递给子组件的数据。
  • watch():当某个数据发生变化时触发。
  • computed:动态计算某个数据。
  • setup(props, context):初始化变量、函数。
    • ref:定义变量,可以用 .value 属性重新赋值。
    • reactive:定义对象,不可重新赋值。
    • props:存储父组件传递过来的数据。
    • context.emit():触发父组件绑定的函数。

然后是 <template> 中的内容:

  • <slot></slot>:存放父组件传过来的 children
  • v-on:click@click 属性:绑定事件。
  • v-ifv-elsev-else-if 属性:判断。
  • v-for 属性:循环,:key 循环的每个元素需要有唯一的 key
  • v-bind:::绑定属性。

<style> 部分需要注意的就是添加 scope 属性后,不同组件间的 CSS 不会相互影响。

最后是第三方组件:

  • view-router:实现路由功能。
  • vuex:存储全局状态,全局唯一。
    • state:存储所有数据,可以用 modules 属性划分成若干模块。
    • getters:根据 state 中的值计算新的值。
    • mutations:所有对 state 的修改操作都需要定义在这里,不支持异步,可以通过 $store.commit() 触发。
    • actions:定义对 state 的复杂修改操作,支持异步,可以通过 $store.dispatch() 触发。注意不能直接修改 state,只能通过 mutations 修改 state
    • modules:定义 state 的子模块。

这些概念先不用背,之后用到时再回来理解什么意思即可。

3. 导航栏

我们将整个页面分为导航栏(NavBar)和内容部分(Content),导航栏在每个页面都是固定不变的,变化的只有内容部分。我们将要实现首页、好友列表、用户动态、登录、注册以及404页面,每个页面我们都可以实现为一个组件。

在根 JS 文件 main.js 中引入 Bootstrap:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/js/bootstrap'createApp(App).use(router).use(store).mount('#app')

这时候会报错,提示我们没有找到模块 @popperjs/core,这时我们需要去项目管理页面的依赖页面中安装 @popperjs/core 依赖。

现在先把 HelloWorld.vue 删掉,然后把 HomeView.vue 中关于 HelloWorld 组件的内容删去,在 components 目录下创建 NavBar.vue,我们现在先不实现路由功能,直接去 Bootstrap 官网找一个导航栏复制过来:

<template><nav class="navbar navbar-expand-lg bg-body-tertiary"><div class="container"><a class="navbar-brand" href="#">My Space</a><buttonclass="navbar-toggler"type="button"data-bs-toggle="collapse"data-bs-target="#navbarText"aria-controls="navbarText"aria-expanded="false"aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarText"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><a class="nav-link" href="#">首页</a></li><li class="nav-item"><a class="nav-link" href="#">好友列表</a></li><li class="nav-item"><a class="nav-link" href="#">用户动态</a></li><li class="nav-item"><a class="nav-link" href="#">关于</a></li></ul><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="#">登录</a></li><li class="nav-item"><a class="nav-link" href="#">注册</a></li></ul></div></div></nav>
</template><script>
export default {name: "NavBar",
};
</script><style></style>

然后我们在 App.vue 中把导航栏组件添加进来,并删去原本的内容:

<template><NavBar /><router-view />
</template><script>
import NavBar from "@/components/NavBar.vue";export default {name: "App",components: {NavBar: NavBar,},
};
</script><style></style>

4. 页面创建

首先我们用 Bootstrap 的 Card 先实现一个卡片组件 Card.vue

<template><div class="container"><div class="card"><div class="card-header"><h3>{{ title }}</h3></div><div class="card-body"><slot></slot></div></div></div>
</template><script>
export default {name: "Card",props: {title: String,},
};
</script><style scoped>
.card {margin-top: 20px;
}
</style>

注意,如果发现报错:Component name "Card" should always be multi-word vue/multi-word-component-names,说明文件名没有驼峰命名,可以在 package.json 文件的 rules 中添加一行代码,然后停止项目重新启动即可:

"vue/multi-word-component-names": "off"

然后我们在 HomeView 中即可使用这个组件:

<template><Card title="首页">这是首页内容</Card>
</template><script>
// @ is an alias to /src
import Card from "@/components/Card.vue"export default {name: "HomeView",components: {Card: Card,},
};
</script>

可以看到 Card 中使用 {{ msg }} 在 HTML 标签中获取 proptitle 的值,该值由父组件 HomeView 传入。<slot></slot> 类似 React 中的 this.props.children

现在我们可以根据 HomeView 创建其他页面:FriendListViewUserNewsViewLoginViewRegisterViewNotFoundView

创建好页面后我们需要实现路由,即根据地址来显示对应的组件。在 src/router/index.js 文件中修改:

import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView";
import FriendListView from "../views/FriendListView";
import UserNewsView from "../views/UserNewsView";
import LoginView from "../views/LoginView";
import RegisterView from "../views/RegisterView";
import NotFoundView from "../views/NotFoundView";const routes = [{path: "/",name: "home",component: HomeView,},{path: "/friendlist",name: "friendlist",component: FriendListView,},{path: "/usernews",name: "usernews",component: UserNewsView,},{path: "/login",name: "login",component: LoginView,},{path: "/register",name: "register",component: RegisterView,},{path: "/404",name: "404",component: NotFoundView,},{path: "/about",name: "about",component: () => import("../views/AboutView.vue"),},
];const router = createRouter({history: createWebHistory(),routes,
});export default router;

最后我们在导航栏 NavBar 中实现地址的跳转,如果直接在 <a> 标签上写地址那么为后端渲染,即每次切换页面都需要访问一遍后端请求数据,我们可以用 <router-link> 实现前端渲染:

<template><nav class="navbar navbar-expand-lg bg-body-tertiary"><div class="container"><router-link class="navbar-brand" :to="{name: 'home'}">My Space</router-link><buttonclass="navbar-toggler"type="button"data-bs-toggle="collapse"data-bs-target="#navbarText"aria-controls="navbarText"aria-expanded="false"aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarText"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><router-link class="nav-link" :to="{name: 'home'}">首页</router-link></li><li class="nav-item"><router-link class="nav-link" :to="{name: 'friendlist'}">好友列表</router-link></li><li class="nav-item"><router-link class="nav-link" :to="{name: 'usernews'}">用户动态</router-link></li><li class="nav-item"><router-link class="nav-link" :to="{name: 'about'}">关于</router-link></li></ul><ul class="navbar-nav"><li class="nav-item"><router-link class="nav-link" :to="{name: 'login'}">登录</router-link></li><li class="nav-item"><router-link class="nav-link" :to="{name: 'register'}">注册</router-link></li></ul></div></div></nav>
</template><script>
export default {name: "NavBar",
};
</script><style></style>

其中 :to 表示绑定 to 属性,参数是一个对象,其中的 name 属性表示名称,即之前在 router 中定义的 name

5. 用户动态页面实现

该页面可以划分为三个模块:用户信息部分、发动态部分(如果是自己才有发动态功能)、历史动态展示部分,因此我们可以用三个组件来实现(在 components 目录下创建 UserNewsInfo.vueUserNewsSend.vue 以及 UserNewsPosts.vue 三个组件)。

其中 UserNewsInfo 内容如下:

<template><div class="card"><div class="card-body"><div class="row"><div class="col-md-4"><imgclass="img-fluid"src="https://cdn.acwing.com/media/user/profile/photo/82581_lg_e9bdbcb8aa.jpg"/></div><div class="col-md-8"><div class="username">AsanoSaki</div><div class="fans">粉丝:123</div><button type="button" class="btn btn-secondary btn-sm">+关注</button></div></div></div></div>
</template><script>
export default {name: "UserNewsInfo",
};
</script><style scoped>
img {border-radius: 50%;
}button {padding: 2px 4px;font-size: 14px;
}.username {font-size: 20px;font-weight: bold;
}.fans {font-size: 14px;color: gray;
}
</style>

相关文章:

Web学习笔记-Vue3(环境配置、概念、整体布局设计)

笔记内容转载自 AcWing 的 Web 应用课讲义&#xff0c;课程链接&#xff1a;AcWing Web 应用课。 CONTENTS 1. 环境配置2. 基本概念3. 导航栏4. 页面创建5. 用户动态页面实现 Vue 官网&#xff1a;Vue.js。 Vue.js 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML…...

【React-Native开发3D应用】React Native加载GLB格式3D模型并打包至Android手机端

【React-Native开发3D应用】React Native加载GLB格式3D模型并打包至Android手机端 【加载3D模型】**React Native上如何加载glb格式的模型**第零步&#xff0c;选择相关模型第一步&#xff0c;导入相关模型加载库第二步&#xff0c;自定义GLB模型加载钩子第三步&#xff0c;借助…...

python的列表

定义 列表 是python中的一种数据类型&#xff0c;可以存放多个数据&#xff0c;列表中的数据可以是任意类型的。 格式 格式&#xff1a; my_list [] my_list list() 定义一个空的列表&#xff0c;有如上两种方式 遍历 for 循环 while循环 列表添加操作 列表添加操作有…...

[100天算法】-最短无序连续子数组(day 66)

题目描述 给定一个整数数组&#xff0c;你需要寻找一个连续的子数组&#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。你找到的子数组应是最短的&#xff0c;请输出它的长度。示例 1:输入: [2, 6, 4, 8, 10, 9, 15] 输出: 5 解释: 你只需要…...

001. 变量、环境变量

1、在终端中显示输出 shell脚本通常以shebang起始&#xff1a;#&#xff01;/bin/bash/ shebang是一个文本行&#xff0c;其中#!位于解释器路径之前。/bin/bash是Bash的解释器命令路径。bash将以#符号开头的行视为注释。脚本中只有第一行可以使用shebang来定义解释该脚本所使…...

软考软件设计师刷题笔记整理

软件设计师 HTML代码中&#xff0c;创建指向邮箱地址的链接正确的是ARP攻击造成网络无法跨网段通信的原因是在软件开发过程中进行风险分析关于哈夫曼树的叙述关于风险管理的叙述ISO/IEC9126软件质量模型关于结构化开发方法的叙述分布式数据库中的分片透明、复制透明、位置透明和…...

Canal

canal译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费。 1.canal 工作原理 canal 模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 MySQL slave &#xff0c;向 MySQL master 发送dump 协议MySQL master 收到…...

SpringBoot实现mysql与clickhouse多数据源

一、我们来实现一个mysql与clickhouse多数据源配置 二、数据源配置 # 指定服务名称 spring:application:name: demobigdatadatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/db?createDatabaseIfNotExisttrue&useUnicodetrue&…...

为什么是LangChain?

文章目录 一、前言二、认识langchain1. langchain的主要组成2. 总览LangChain2. LangChain的六大核心模块1. Models&#xff1a;模型统一接口2. Prompts&#xff1a;管理 LLM 输入3. Chains&#xff1a;将 LLM 与其他组件相结合&#xff0c;执行多个chain4. Indexes&#xff1a…...

Labview的分支判断

和其他的编程语言一样的。都会有switch,case, if ,else; 再combo box中实现 再后台程序中对应的写上逻辑就好了。...

蓝桥杯双周赛算法心得——串门(双链表数组+双dfs)

大家好&#xff0c;我是晴天学长&#xff0c;树和dfs的结合&#xff0c;其邻接表的存图方法也很重要。需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .串门 2) .算法思路 串门&#xff08;怎么存图很关键&#xf…...

mysql 配置主从复制 及 Slave_SQL_Running = no问题排查

一、配置主数据库 1、在mysql 配置文件my.cnf中设置主数据库配置 server-id1 //唯一的标示符 log-binmysql-bin //开启二进制日志2、重启数据库 3、安全规范的写法是新建一个用户给这个用户复制的权限&#xff08;直接用root也可以不建议&#xff09; CREATE USER repl% IDEN…...

再获5G RedCap能力认证!宏电5G RedCap工业智能网关通过中国联通5G物联网OPENLAB开放实验室测试验证

​近日&#xff0c;中国联通5G物联网OPENLAB开放实验室携手宏电股份完成5G RedCap工业智能网关端到端的测试验证&#xff0c;并颁发OPENLAB实验室面向RedCap终端的认证证书&#xff0c;为RedCap产业规模推广、全行业赋能打下坚实基础。 中国联通5G物联网OPENLAB开放实验室是中国…...

牛客--汽水瓶python

某商店规定&#xff1a;三个空汽水瓶可以换一瓶汽水&#xff0c;允许向老板借空汽水瓶&#xff08;但是必须要归还&#xff09;。 小张手上有n个空汽水瓶&#xff0c;她想知道自己最多可以喝到多少瓶汽水。 数据范围&#xff1a;输入的正整数满足 1≤n≤100 注意&#xff…...

TSINGSEE智能分析网关V4车辆结构化数据检测算法及车辆布控

车辆结构化视频AI检测技术&#xff0c;可通过AI识别对视频图像中划定区域内的出现的车辆进行检测、抓拍和识别&#xff0c;系统通过视频采集设备获取车辆特征信息&#xff0c;经过预处理之后&#xff0c;接入AI识别算法并与车辆底库进行对比&#xff0c;快速识别车辆身份和属性…...

git解决冲突的方法。

1、 cherry-pick git fetch ssh://jingyou.caigerrit.transtekcorp.com:29418/leshan refs/changes/23/34123/3 && git cherry-pick FETCH_HEAD2、 文件解冲突&#xff01; 3、 cherry-pick完整。 git cherry-pick --continue4、查看状态。 5、 push。 git push o…...

[MT8766][Android12] 取消WIFI热点超过10分钟没有连接自动关闭设定

文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: MT8766 版本: Android 12 kernel: msm-4.19 问题描述 之前有个需求要设备默认开启WIFI热点&#xff0c;默认开启usb共享网络&#xff1b;而热点在原生的设定里面有个超时机制&#xff0c;如果在限定时间内…...

智能中仍存在着许多未被发现的逻辑

自然规律不仅包括精确的也包括模糊的&#xff0c;即模糊的基本自然律意味着自然界中的现象与规律并不是绝对精确的&#xff0c;存在一定的模糊性和不确定性。因此&#xff0c;用数学来完全描述和预测这些现象可能会有限制。 智能与人工智能&#xff08;AI&#xff09;抑或智能化…...

基于公共业务提取的架构演进——外部依赖防腐篇

背景 有了前两篇的帐号权限提取和功能设置提取的架构演进后&#xff0c;有一个问题就紧接着诞生了&#xff0c;对于诸多业务方来说&#xff0c;关键数据源的迁移如何在各个产品落地&#xff1f; 要知道这些数据都很关键&#xff1a; - 对于帐号&#xff0c;获取不到帐号信息是…...

uniapp小程序接入腾讯云【增强版人脸核身接入】

文档地址&#xff1a;https://cloud.tencent.com/document/product/1007/56812 企业申请注册这边就不介绍了&#xff0c;根据官方文档去申请注册。 申请成功后&#xff0c;下载【微信小程序sdk】 一、解压sdk&#xff0c;创建wxcomponents文件夹 sdk解压后发现是原生小程序代…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...