前端毕业设计:Nodejs+Vue菜鸟驿站仓库管理系统的设计与实现

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 本系统使用 Node.JS 语言开发,该编程语言简单易学,能够与多个框架完美结合,又具备面向对象、与平台无关、多线程等特点,因此比较容易进行开发工作。开发工具使用Visual Studio Code,它强大的整合能力能更好的对项目进行管理,丰富的提示功能可以使开发人员更加高效的进行开发工作。数据库使用MySQL,其简单易用、开源免费、社区庞大而完善的特点,对于初次尝试人员非常友好。系统的架构是B/S,也就是浏览器/服务器模型,客户端完成主要的业务,一些交互或发起请求在前端完成。对于用户非常简单,通过一个浏览

项目编号:BS-QD-004        

前言:

当前时代,全球的经济已经从工业经济到知识经济的改变,过去专家说知识经济的两个首要属性是信息化和全球化,要完成化和全球化,这时就需要稳定的网络和完备的数据库。但时至今日中国的服务价值意识提高,人力成本开始骤增,对于很多快递企业来说一个10元成本的单子,有5元是在最后一公里被消耗了。研究快递驿站的智能物流货架的应用方案,随着社会和科学技术的演变,仓储管理的方法也不断优化。从全部人工管理的方法,这样不仅效率低,工作量大,并且准确率差。尤其是当今快递行业飞速发展,货流量大,人工管理更显不足。为了提高仓库管理效率,减少仓库管理成本,特开发菜鸟驿站库存管理系统。

一,项目简介

本系统使用 Node.JS 语言开发,该编程语言简单易学,能够与多个框架完美结合,又具备面向对象、与平台无关、多线程等特点,因此比较容易进行开发工作。开发工具使用Visual Studio Code,它强大的整合能力能更好的对项目进行管理,丰富的提示功能可以使开发人员更加高效的进行开发工作。数据库使用MySQL,其简单易用、开源免费、社区庞大而完善的特点,对于初次尝试人员非常友好。系统的架构是B/S,也就是浏览器/服务器模型,客户端完成主要的业务,一些交互或发起请求在前端完成。对于用户非常简单,通过一个浏览器就可以与系统进行访问和交互。为了实现高效的开发和后期维护,系统采用了MVC架构,即数据模型层、视图表现层、路由控制层,客户通过视图交互实现数据功能的使用效果,路由控制层主要处理前端传过来的各种请求,通过路由和参数以及身份认证来处理逻辑,并把最终的结果给到前端,数据模型层主要是对数据的增删改查等操作,当然主要依赖于路由控制层。如上的开发工具和技术都能够满足开发需求,故在技术上是可行的。随着科学技术的不断提高,计算机科学应用也越来越普及,相比手工管理,使用计算机软件对仓储信息进行管理,无论从效率、科学性还是规范性方面都有着巨大的优势,该软件的开发不会侵犯国家、集体和他人的利益,所以其具备社会公认的可行性。系统开发不需要高端设备,大部分技术开源免费,哪怕开发过程中发生重大失误,改正即可,不会损耗材料,系统开发出来,可以无限备份投入使用,非常完全符合经济上的可行性。

业务流程图

image.gif编辑

系统数据流程图

image.gif编辑

二,环境介绍

2.2相关技术和开发环境

2.2.1 相关技术

(1)B/S结构(Browser/Server结构)简介

B/S(Brower/Server,浏览器/服务器)模式又称B/S结构,是Web兴起后的一种网络结构模式。Web浏览器是客户端最主要的应用软件。这种模式统一了客户端,将系统功能实现的核心部分集中到服务器上,简化了系统的开发、维护和使用;客户机上只需要安装一个浏览器,服务器上安装SQL Server, Oracle, MySql等数据库;浏览器通过Web Server同数据库进行数据交互。Browser指的是Web浏览器,极少数事务逻辑在前端实现,但主要事务逻辑在服务器端实现。B/S架构的系统无须特别安装,只有Web浏览器即可。

其实就是我们前端现在做的一些事情,大部分的逻辑交给后台来实现,我们前端大部分是做一些数据渲染,请求等比较少的逻辑。通过三层结构模型,大大减轻了客户端的压力,降低了开发和维护的成本,也降低了客户的总成本。

(2)Mysql简介

MySQL是Web世界中使用最广泛的数据库服务器。SQLite的特点是轻量级、可嵌入,但不能承受高并发访问,适合桌面和移动应用。而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也远远大于SQLite。

此外,MySQL内部有多种数据库引擎,最常用的引擎是支持数据库事务的InnoDB。存储引擎就是存储数据,建立索引,更新、查询数据等技术的实现方式。存储引擎是基于表的。mysql支持多种存储引擎,而oracle、sqlserver等只有一种存储引擎

即市场占有率最大的关系型数据库,类似于excel表格

DML:select、insert、update、delete

DDL:drop、create等

    1. MySQL数据库的优点

    MySQL的主要优势如下:

    1、速度: 系统运行速度非常快。

    2、价格:MySQL对多数个人来说是免费使用的。

    3、容易使用:相比于其他数据库的设置和管理相比,相对于比较简单,容易学习。

    4、可移植性: 跨平台能力,可以适用于不同的系统平台之下,例如:Windows 、Linux、Unix、MacOS等。

    5、丰富的接口: 提供了用于C 、C++、Eiffel、Java、Perl、PHP、Python、Rudy和TCL 等语言的API。

    6、支持查询语言:MySQL可以利用标准SQL语法和支持ODBC(开放式数据库连接)的应用程序。

    7、安全性和连接性; 非常灵活的安全和校验机制,允许主机验证。连接到服务器时,所有的密码

    都采用加密形式,从而保证了密码安全。并且由于MySQL时网络化的,因此可以在因特网网上的任何地方访问,提高数据共享效率。

    (4)HTML简介

    HTML 是用来描述网页的一种语言。

    HTML 指的是超文本标记语言 (Hyper Text Markup Language)

    HTML 不是一种编程语言,而是一种标记语言 (markup language)

    标记语言是一套标记标签 (markup tag)

    HTML 使用标记标签来描述网页

    HTML 标签

    HTML 标记标签通常被称为 HTML 标签 (HTML tag)。

    HTML 标签是由尖括号包围的关键词,比如 <html>

    HTML 标签通常是成对出现的,比如 <b> 和 </b>

    标签对中的第一个标签是开始标签,第二个标签是结束标签

    开始和结束标签也被称为开放标签和闭合标签

    HTML 文档 = 网页

    HTML 文档描述网页

    HTML 文档包含 HTML 标签和纯文本

    HTML 文档也被称为网页

    (5)Node.js简介

    Node.js是基于google公司旗下的产品Chrome浏览器,其中使用的V8引擎就来自于此。由于浏览器的特殊性,引擎最显著的特点就是事件驱动、异步的I/O模式,在不断的优化下,非常的高效和轻量

    (6)Visual Studio Code简介

    相比于Visual Studio的重量级产品不同,Visual Studio Code可谓非常的轻量级,它诞生于2015年4月30日的开发者大会上,并且跨平台的特性,以及针对现代web应用和云平台的源代码编辑器。软件只有几十兆,因为不绑定任何的插件,但是因为拥有强大的插件系统和插件商城,所以开发者可以有选择的使用各种插件,提高效率,对于内置支持的Javascript和TypeScript,并且可以通过扩展来支持其他语言,比如C++、C、JAVA、Python等语言。

    (7)Nginx简介

    Nginx是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。

      master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

      worker进程则是处理基本的网络事件。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

    2.2.2 系统的开发环境

    系统设计平台:Microsoft Windows 10

    数据库设计工具:MySQL

    程序设计工具:Visual studio code

    三,系统展示

    4.2.1 注册界面

    注册界面是管理系统最重要的环节,只有注册才能有能力访问管理后台系统,以及进一步的操作,这样也就规避了不同人员在没有权限下,操作管理后台。

    没有权限操作数据,会对整个数据造成破坏,产生不可挽回的影响。

    具体代码如下:

    let { name, password, password2, phone, username } = ctx.request.body;

    let adminUserList = await query('select * from admin_user');

    let time = dayjs().format('YYYY-MM-DD HH:mm:ss')

    if (adminUserList.some(item => item.username === username)) {

      ctx.body = {

    code: -1,

    data: null,

    message:  '该用户已经注册'

    };

    } else {

     try {

       let str = `INSERT INTO admin_user(username, password, name, phone, time) VALUES('${username}', '${password}', '${name}', '${phone}', '${time}')`;

       console.log(str);

       await query(str);

       ctx.response.redirect('/login');

    } catch(err) {

       console.log(err);

      ctx.response.redirect('/register');

    }

    }

    注册操作需要的信息有:用户名(登录名)、用户密码、确认密码、真实姓名、用户手机号。具体操作页面如4-1所示:

    image.gif编辑

    4.2.2 登录界面

    管理员登录是验证用户身份最主要的手段,后台系统通过token保存用户身份,前端把token放到浏览器storage中存储,每次请求带上token数据。整体的实现也非常简单,通过输入用户名和密码,前端发起http请求,给到后端,后端拿到用户名和密码,进一步判断是否与数据库的数据一致,如果通过验证则跳到首页,否则就会返回给客户端相应的错误。通过认证后,用户就会与之创建连接,就可以完成之后的后续操作了。

    具体实现代码如下所示:

    let adminUserList = await query(`

    SELECT id, username, name, phone

    FROM admin_use

    WHERE username='${username}' && password='${password}'

    `);

    if (adminUserList.length > 0) {

      let token = jwt.sign({ ...adminUserList[0] }, secret);

      ctx.body = {

       code: 1,

         data: {

           token,

               username: username

         },

    message: '登录成功'

    }

    具体的功能页面如下图4-2所示:

    image.gif编辑

    图4-2 登录界面

    4.2.3 入库界面

    每为确保公司货货物进出入库能得到管制,确保仓库库存数据的准确,必须规范好商品的出入库

    流程。最重要的就是入库管理,通过点击顶部的商品入库跳到对应页面

    具体代码如下:

    操作界面如图4-3:

     router.post('/instock', async function (ctx, next) {

       let { token } = ctx.request.header;

       let { name, phone, goodsName } = ctx.request.body;

       try {

         let userInfo = jwt.verify(token, secret);

         let time = dayjs().format('YYYY-MM-DD HH:mm:ss');

         console.log(name, phone, goodsName, userInfo);

         // 1. 先用手机号查customer表,是否有此用户

         let customerList = await query(`select id, phone from customer`);

         let curCustomer = customerList.find(item => item.phone == phone);

         let customerId;

       

         if (!curCustomer) {

           // 先加一下这个用户

           customerId = customerList.length + 1;

           await query(`insert into customer(id, name, phone, time) values(${customerId}, '${name}', '${phone}', '${time}')`);

         } else {

           customerId = curCustomer.id;

         }

       

         // 2. 找一个空的货架单元

         // 把所有库存的仓库都找出来

         let storehouseGoodsList = await query(`select storehouse_id from storehouse_goods where is_out<>1`);

         let storehouseList = await query(`select id from storehouse`);

         let emptyStoreId = '';

         if (storehouseGoodsList.length > 0) {

           let emptyStoreList = storehouseList.filter(item => !storehouseGoodsList.some(it => it.storehouse_id === item.id))

           if (emptyStoreList.length === 0) throw new Error('没有空余的货架,请出库以腾出空位!');

           emptyStoreId = emptyStoreList[0].id;

         } else {

           emptyStoreId = storehouseList[0].id;

         }

       

         // 写入出库

         let goodsList = await query(`select id from goods`);

         let goodsId = goodsList.length + 1;

         await query(`insert into goods(id, name, customer_id, admin_id) values(${goodsId}, '${goodsName}', ${customerId}, ${userInfo.id})`);

         await query(`insert into storehouse_goods(goods_id, storehouse_id, is_out, instock_time) values(${goodsId}, ${emptyStoreId}, 0 ,'${time}');`);

         ctx.body = {

           code: 1,

           data: null,

           message: '商品入库成功!'

         }

       } catch(err) {

         console.log(err);

         ctx.response.redirect('/login');

       }

     });

    image.gif编辑

    图4-3 商品入库

    4.2.4 出库界面

    仓当客户收到取件码后,通过扫码就可以获得对应的库存id(因为没有具体的物理设备,此操作通过查询步骤,给出库存id),通过检验身份信息,此功能通过点击顶部的商品出库跳到对应的页面完成

    相关代码如下:

    具体操作页面如图4-4:

     router.post('/outstock', async function (ctx, next) {

       let { token } = ctx.request.header;

       let { val } = ctx.request.body;

       try {

         let userInfo = jwt.verify(token, secret);

         let sgList = await query(`select id, goods_id, is_out from storehouse_goods where id=${val}`);

         if (sgList.length === 0) throw new Error('库存id无效');

         if (sgList[0].is_out === 1) throw new Error('该商品已经出库');

         let time = dayjs().format('YYYY-MM-DD HH:mm:ss');

         await query(`UPDATE storehouse_goods SET is_out=1, outstock_time='${time}' where id=${val}`);

         ctx.body = {

           code: 1,

           data: null,

           message: '出库成功'

         }

       } catch(err) {

         ctx.body = {

           code: -1,

           data: null,

           message: err.message

         }

       }

     });

    image.gif编辑

    图4-4 商品出库界面

    4.2.5 查询界面

    相关代码如下:

    具体操作页面如图4-5所示:

     router.get('/queryorder', async function (ctx, next) {

       let { token } = ctx.request.header;

       let { value } = ctx.request.query;

       try {

         let userInfo = jwt.verify(token, secret);

         let reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;

         let arr = [];

       

         // , G.is_out, G.instock_time, G.outstock_time

         // 如果是手机号

         if (reg_tel.test(value)) {

           let customerList = await query(`SELECT id FROM customer WHERE phone='${value}'`);

     

           if (customerList.length === 0) throw new Error('没有这个手机号的记录');

           // 找到这个商品

           let goodsList = await query(`SELECT G.id, G.name AS 'good_name', A.name AS 'admin_name', C.name AS 'customer_name' FROM goods G, admin_user A, customer C WHERE G.customer_id=${customerList[0].id} AND C.id=${customerList[0].id} AND A.id=G.admin_id`);

         

           if (goodsList.length > 0) {

             for (let i=0; i<goodsList.length; i++) {

               let _item = { ...goodsList[i] };

             

               let sgList = await query(`SELECT * FROM storehouse_goods WHERE goods_id=${_item.id}`);

               if (sgList.length === 0) throw new Error('没有找到此库存');

               let storeList = await query(`SELECT * FROM storehouse WHERE id=${sgList[0].storehouse_id}`);

               if (storeList.length === 0) throw new Error('没有找到此仓库');

               // 找这个仓库

               _item.store_id = storeList[0].id;

               _item.store_code = storeList[0].name;

               _item.sg_id = sgList[0].id;

               _item.is_out = sgList[0].is_out;

               _item.instock_time = sgList[0].instock_time;

               _item.outstock_time = sgList[0].outstock_time;

               arr.push(_item);

             }

           

           }

           console.log(goodsList);

         } else {

           // 使用取件码查询

           // 1. 查询库存表是否有这个仓库

           let storeList = await query(`SELECT id, name FROM storehouse WHERE name='${value}'`);

           if (storeList.length === 0) throw new Error(`${value}这个取件码无效`);

           // 2. 找到这个库存

           let sgList = await query(`SELECT * FROM storehouse_goods WHERE storehouse_id=${storeList[0].id}`);

           if (sgList.length === 0) throw new Error(`没有找到这个库存`);

           // 3. 找到这个商品

           let goodsList = await query(`SELECT G.id, G.name AS 'good_name', A.name AS 'admin_name', C.name AS 'customer_name' FROM goods G, admin_user A, customer C WHERE G.id=${sgList[0].id} AND C.id=G.customer_id AND A.id=G.admin_id`);

           if (goodsList.length > 0) {

             arr.push(goodsList[0]);

             arr[0].store_id = storeList[0].id;

             arr[0].store_code = storeList[0].name;

             arr[0].sg_id = sgList[0].id;

             arr[0].is_out = sgList[0].is_out;

             arr[0].instock_time = sgList[0].instock_time;

             arr[0].outstock_time = sgList[0].outstock_time;

           }

         }

         ctx.body = {

           code: arr.length > 0? 1: -1,

           data: arr,

           message: arr.length > 0? 'query ok': '没有找到指定的库存'

         }

       

       } catch(err) {

         ctx.body = {

           code: -1,

           data: null,

           message: err.message

         }

       }

     })

    image.gif编辑

    图4-5 库存查询页面

    4.2.6 库存异常界面

    在常规的快递库存管理过程中,不可避免的会遇到快递长期无人领取,一方面有可能是客户工作繁忙等原因,也有可能是因为某些原因客户没有收到通知短信,导致库存长期被占用。这里有两个问题:第一、因为库存被占用,不能存放其他快递;第二、客户没有接收到快递,降低用户体验,并且有可能造成用户的经济损失。基于以上原因,特设库存异常功能,解决此类问题,相关代码如下:

         let arr = [];

         let timeWhere = '';

         switch (val) {

           case '1': // 超时一周

             timeWhere = `instock_time < '${ dayjs(dayjs() - 7*24*60*60*1000).format('YYYY-MM-DD HH:mm:ss') }'`;

             break;

           case '2': // 超时3周

             timeWhere = `instock_time < '${ dayjs(dayjs() - 3*7*24*60*60*1000).format('YYYY-MM-DD HH:mm:ss') }'`;

             break;

           case '3': // 超时一个月

             timeWhere = `instock_time < '${ dayjs(dayjs() - 30*24*60*60*1000).format('YYYY-MM-DD HH:mm:ss') }'`;

             break;

           case '4': // 超时三个月

             timeWhere = `instock_time < '${ dayjs(dayjs() - 90*24*60*60*1000).format('YYYY-MM-DD HH:mm:ss') }'`;

             break;

           case '5': // 超时一年

             timeWhere = `instock_time < '${ dayjs(dayjs() - 365*24*60*60*1000).format('YYYY-MM-DD HH:mm:ss') }'`;

             break;

         }

         let sgList = await query(`select * from storehouse_goods where is_out<>1 and ${timeWhere}`);

         for (let i=0; i<sgList.length; i++) {

           let item = { ...sgList[i], instock_time: dayjs(sgList[i].instock_time).format('YYYY-MM-DD HH:mm:ss') };

           let storeList = await query(`select id, name from storehouse where id=${item.storehouse_id}`);

           let goodsList = await query(`select G.id, G.name AS 'good_name', A.name AS 'admin_name', C.name AS 'customer_name' from goods G, admin_user A, customer C where G.id=${item.goods_id} AND C.id=G.customer_id AND A.id=G.admin_id`);

           if (goodsList.length > 0) {

             item.store_id = storeList[0].id;

             item.store_code = storeList[0].name;

             item.admin_name = goodsList[0].admin_name;

             item.customer_name = goodsList[0].customer_name;

             item.good_name = goodsList[0].good_name;

           }

           arr.push(item);

         }

    具体操作界面如图4-6所示:

    image.gif编辑

    图4-6 库存异常界面

    4.2.7 客户信息

    有些场景我们需要查找客户信息,比如某一快递异常,找客户的手机号,给客户发消息,这时就需要客户信息功能界面,可以模糊查询。

    具体代码如下:

    queryWhere = `where name like '%${val}%'`;

    let arr = await query(`select * from customer ${queryWhere}`);

    arr = arr.map(item => ({ ...item, time: dayjs(item.time).format('YYYY-MM-DD HH-mm-ss') }));

    具体界面如图4-7所示:

    image.gif编辑

    图4-7 客户信息界面

    四,项目总结

    5.1测试的目的

    系统测试(System Testing),系统测试是把已经完成的硬件、软件、外设、网络等所有组成部分结合在一起,对整个系统进行单元测试和总体测试,通过与系统的需求做比较,找到所开发的系统与用户需求之间的差别,进而优化系统的手段。目前无论大企业还是中小企业,都再利用互联网进行信息的管理和分享,所以一个软件系统进行系统的测试和总结,是必要的和必需的,而且通过测试工作的进行,可以反映出最初没有考虑到的细节或流程,也有查漏补缺的功能,进而提高软件的质量。

    5.2测试的方法

    5.2.1 白盒测试

    白盒测试又被称为:结构测试或者叫做逻辑驱动测试,这是一种需要基于代码的测试,白盒是一种形象的比喻,系统程序就像透明盒子一样,是可以看见的,也就是我们可以系统的各个模块是如何运行和调用的。比如:大部分公司首先会进行白盒测试,也就是按功能模块系统的对子模块进行系统的测试,包括运行的异常和文本域或模拟用户行为创建并不符合系统的输入,从而建立全面准确并具有说服力了的测试用例。虽然白盒测试有很多优点,但也有几个无法规避的问题,一个系统程序运行会有很多条类似于tree结构的不同路径,不可能测试所有的情况,也为程序不稳定埋下了伏笔。

    5.2.2 黑盒测试

    黑盒测试通常也成为数据驱动的测试方法,黑盒顾名思义就是,把系统程序看作看不见的黑盒子,完全不用考虑系统的流程,数据的流动,以及各个字段的类型。在完全不考虑程序本身的前提下,更多从用户使用情况或用户体验出发,测试每个模块是否可以正常稳定运行,按照程序需求文档,逐条验证是否可以输入数据而产生预期的正确结果,白盒测试着眼于内部,而黑盒子着眼于外部,当然这里有一个弊端,就是黑盒测试不能系统功能是否设计合理等细节问题。

    5.2.3 灰盒测试

    白盒测试和黑盒测试都有各自的优缺点,而灰盒测试介于黑盒测试和白盒测试之间,综合了各自的优点,有又规避了其中的缺点,不仅像白盒测试那样测试系统程序内部的功能逻辑,还会重点关注输入、输出的准确性。比如某个程序段运行时,通过外部的异常表现,转而进入程序内部,结合程序内部逻辑结构综合分析,这样就可以全面的诊断和测试系统程序。

    5.2.4 静态测试

    静态测试是比较独特,不像其他测试方法,需要运行被测试的系统程序,静态测试通过系统的分析程序结构,语法,接口规范,过程来检查程序的手段。

    5.2.5 动态测试

    动态测试是运行被测试的系统程序,分析程序运行的结果和预期达到的结果的差异,并总结出具体的程序性能指标,正确率等。

    5.3测试用例

    5.3.1 系统登录功能测试

    系统的测试是甲方验收的重要的依据,通过输入所需信息查看是否和预期一样。是否可以完整成功运行整个系统。如表5-1所示

    图5-1 测试用例

    名称

    功能

    操作

    期望结果

    实际结果

    测试状态

    用户注册

    注册管理员

    输入用户名:wxs;

    密码:12345678;

    确认密码:12345678

    真实名字:王先生

    手机号:18201107931

    注册成功

    编辑

    与期望相同

    用户登录

    管理员登录

    用户名:wxs;

    密码:12345678

    登录成功

    编辑

    与期望相同

    查询库存

    库存列表

    输入用户手机号:,查询它的商品快递

    查询成功

    编辑

    与期望相同

    商品入库

    商品入库

    收件人姓名:李先生;

    收件人手机号:18435250911;

    商品名称:小米手环S1

    入库成功

    编辑

    与期望相同

    商品出库

    商品出库

    输入库存id:6

    出库成功

    编辑

    与期望相同

    库存异常

    查询异常库存

    选择超时一年未取的选项

    查询成功

    编辑

    与期望相同

    客户信息

    客户信息

    输入用户姓名

    查询成功

    编辑

    与期望相同

    5.4测试总结

    时间不知不觉程序已经测试完成,虽然功能总体来说比较简单,但是通过自己的双手一步一步的完成此论文,非常的激动。系统总体达到了总目标,编码结果和测试结果完成预期规划,此次测试从系统的各个环节进行了全面测试,基本达到系统独立应用的能力,基本功能已经实现。

    通过测试,功能更加齐全和稳定,在测试中不断会有bug产生,通过不断的寻找解决方法,最终完成预期效果。


    相关实践学习
    每个IT人都想学的“Web应用上云经典架构”实战
    本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
    MySQL数据库入门学习
    本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
    相关文章
    |
    9月前
    |
    JavaScript 前端开发 Java
    制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
    这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
    905 1
    |
    10月前
    |
    移动开发 前端开发 JavaScript
    Vue与React两大前端框架的主要差异点
    以上就是Vue和React的主要差异点,希望对你有所帮助。在选择使用哪一个框架时,需要根据项目的具体需求和团队的技术栈来决定。
    586 83
    |
    11月前
    |
    JSON 自然语言处理 前端开发
    【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
    【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
    604 72
    【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
    |
    9月前
    |
    JavaScript 前端开发 编译器
    Vue与TypeScript:如何实现更强大的前端开发
    Vue.js 以其简洁的语法和灵活的架构在前端开发中广受欢迎,而 TypeScript 作为一种静态类型语言,为 JavaScript 提供了强大的类型系统和编译时检查。将 Vue.js 与 TypeScript 结合使用,不仅可以提升代码的可维护性和可扩展性,还能减少运行时错误,提高开发效率。本文将介绍如何在 Vue.js 项目中使用 TypeScript,并通过一些代码示例展示其强大功能。
    414 22
    |
    11月前
    |
    资源调度 JavaScript 前端开发
    前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
    本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
    10916 23
    |
    11月前
    |
    人工智能 JavaScript 前端开发
    Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
    Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
    |
    JavaScript 前端开发 搜索推荐
    Vue的数据驱动视图与其他前端框架的数据驱动方式有何不同?
    总的来说,Vue 的数据驱动视图在诸多方面展现出独特的优势,其与其他前端框架的数据驱动方式的不同之处主要体现在绑定方式、性能表现、触发机制、组件化结合、灵活性、语法表达以及与后端数据交互等方面。这些差异使得 Vue 在前端开发领域具有独特的地位和价值。
    299 58
    |
    JavaScript 前端开发 jenkins
    抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
    本文探讨了在不依赖Node和VSCode的情况下,仅使用记事本和浏览器开发一个完整的Vue3前端项目的方法。通过CDN引入Vue、Vue Router、Element-UI等库,直接编写HTML文件实现页面功能,展示了前端开发的本质是生成HTML。虽然日常开发离不开现代工具,但掌握这种基础方法有助于快速实现想法或应对特殊环境限制。文章还介绍了如何用Node简单部署HTML文件到服务器,提供了一种高效、轻量的开发思路。
    334 10
    |
    JavaScript 关系型数据库 MySQL
    基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
    基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
    |
    前端开发 JavaScript 开发者
    React与Vue:前端框架的巅峰对决与选择策略
    【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略