相关动态
Web前端最全Vue开发一个电商全栈项目,2024前端高级面试题汇总解答
2024-11-10 23:53

最后

全网独播-价值千万金融项目前端架构实战

Web前端最全Vue开发一个电商全栈项目,2024前端高级面试题汇总解答

从两道网易面试题-分析Javascript底层机制

RESTful架构在Nodejs下的最佳实践

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

一线互联网企业如何初始化项目-做一个自己的vue-cli

思维无价,看我用Nodejs实现MVC

代码优雅的秘诀-用观察者模式深度解耦模块

前端高级实战,如何封装属于自己的JS库

VUE组件库级组件封装-高复用弹窗组件

安装Vuex 数据持久化:

指令汇总(除创建项目外(需手动选择项,可全部复制,交给cmd 自动一步一步安装,最后一项需回车,或者复制上回车):vue create admin

cd admin

cnpm i axios --save

cnpm i element-ui --save

cnpm i vuex-persistedstate --save

第二步:精简项目(项目文件夹保留文件

  • public 静态资源目录

  • src

  • http 封装axios请求

  • components 封装公共组件

  • router 路由配置目录

  • store 状态管理目录

  • views 封装视图组件

  • App.vue 根组件

  • main.js 入口文件

  • package.json

第三步:在 中引入组件库

import ElementUI from ‘element-ui’;

import ‘element-ui/lib/theme-chalk/index.css’;

Vue.use(ElementUI);

第四步:启动项目(端口 8080

npm run serve

2.2、创建客户端APP

cmd返回上一级

第一步:创建项目并安装依赖

创建项目命令:( 使用 vue create 命令创建项目,项目名为 app)

注意:创建项目时,app系统选择hash模式(地址带个中#,选择n【 Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)】

进入项目文件夹 :

安装axios请求

安装组件库

安装Vuex 数据持久化:

指令汇总(除创建项目外(需手动选择项,可全部复制,交给cmd 自动一步一步安装,最后一项需回车,或者复制上回车):vue create app

cd app

cnpm i axios --save

cnpm i vant --save

cnpm i vuex-persistedstate --save

第二步:精简项目(项目文件夹保留文件

  • public 静态资源目录

  • src

  • http 封装axios请求

  • components 封装公共组件

  • router 路由配置目录

  • store 状态管理目录

  • views 封装视图组件

  • App.vue 根组件

  • main.js 入口文件

  • package.json

第三步:在 中引入组件库

import Vant from ‘vant’

import ‘vant/lib/index.css’

Vue.use(Vant)

第四步:启动项目(端口 8080

npm run serve

2.3、创建服务端

cmd返回上一级

第一步:创建项目并安装依赖

先检查是否安装Express,查看版本号(安装了显示版本号,提示没有内部外部命令就是没有安装,需要进行下一步安装

全局安装Express项目生成器(只需要安装一次,类似于脚手架工具

使用 express 命令创建项目,项目名为 server

进入项目文件

初始化依赖(因为当前建完项目没有任何依赖

链接数据库模块

解决跨域

全局安装 nodemon 热启动

指令汇总(除创建项目外(需手动选择项,可全部复制,交给cmd 自动一步一步安装,最后一项需回车,或者复制上回车):

express --version

cnpm i express express-generator -g

express server

cd server

cnpm i

cnpm i mongoose --save

cnpm i cors --save

cnpm i nodemon -g

第二步:精简项目

  • public 静态资源目录

  • db 用于管理数据连接的目录

  • models 用于管理数据模块对象的目录

  • crud 用于管理增删改查封装的目录

  • routes 用于管理路由的目录

  • views 视图模板引擎管理目录(可删除

  • app.js 入口文件

  • package.json

第三步:配置跨域请求

在 入口文件中引入 模块

var express = require(‘express’);

var cors = require(‘cors’); // 引入 cors

//var app = express();

app.use(cors())

// 将 cors 模块注册到中间件中,必须在路由跳转之前配置

//app.use(‘/’,indexRouter) ;

//app.use(‘,users’,usersRouter) ;

第四步:配置 启动

在 文件中配置 命令

“scripts”: {

“start”: “nodemon https://blog.csdn.net/2401_84620288/article/details/bin/www”

}

第五步:启动项目(端口 3000

npm start

3、开发服务端接口


server文件中创建文件搭建目录

↓ server

→ db //用于链接数据库

→ index.js

→ models //模块 用于创建数据模型

→ crud // 用于增删改查 缩写

→ index.js

3.1、连接数据库

第一步:在 中封装连接数据库的函数

//引入mongoose

//下载地址~官网 : https://www.mongodb.com/

// 前端教程网:https://web1024.cn/tool

var mongoose = require(‘mongoose’)

function dbConnect(){

// mongoose 是异步 返回一个 promise 对象

// mongodb 协议链接数据库在哪台机器上,本机:localhost:27017 ;指定链接库的名字:eshop2

mongoose.connect(‘mongodb://localhost:27017/eshop2’,{

//如果数据库中没有这个集合 将会自动创建

useNewUrlParser: true,

useUnifiedTopology: true

//调用 方法接收连接成功之后

}).then(()=>{

console.log(‘数据库连接成功’)

}).catch(err=>{

console.error(‘数据库连接失败’, err)

})

}

//函数抛出

module.exports = dbConnect

在MongoDBCompass.exe可视化中操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第二步:在 入口文件中调用数据库连接方法

//引入 db

var dbConnect = require(‘https://blog.csdn.net/2401_84620288/article/details/db’);

//调用方法

dbConnect();//连接数据库

第三步:启动服务

npm start

服务启动成功后,查看cmd 控制台是否输出了 “数据库连接成功” 的内容。

3.2、封装数据模块对象

在 目录下创建模型对象文件

例如:我们要设计一个商品分类的模块,就创建 文件,示例代码如下

//引入

var mongoose = require(‘mongoose’)

let schema = new mongoose.Schema({ // schema 用于定义和数据库中字段相同的属性名称和数据类型

name: String //分类的名称name 属性 值是String类型

})

//Classify就是把数据库转换成js后拿到的一个对象,将来做增删改查操作

let Classify = mongoose.model(‘classifys’, schema)

//抛出

module.exports = Classify

例如:我们要设计一个商品的模块,就创建 文件,示例代码如下

var mongoose = require(‘mongoose’)

let schema = new mongoose.Schema({ // schema 用于定义和数据库中字段相同的属性名称和数据类型

title: String, //商晶标题

price: Number, //商品价格

guige: Array, //商品规格

content: String, //商品详情

state: {

type: Number, //Number类型 可以多条件设置

default: 1 //商品状态,1为上架,2为下架

},

hot: {

type: Number,

default: 1 //是 否为热销商品,1为普通商品,2为热销商品

}

//等等。。。

})

let Goods = mongoose.model(‘goods’, schema)

module.exports = Goods

如果再创建其他模块,参考此步骤。

3.3、设计接口

此处以添加商品分类为例。

第一步:在 目录下创建对应的路由文件,例如 ,示例代码如下

//对应 3.6.1 接口规范

//没有调用封装的crud,就会每次都要写

var express = require(‘express’);

var router = express.Router();

var Classify = require(‘…/models/classify’);

//添加商品分类 /classify/add

router.post(‘/add’, function(req,res){

//接收参数

let {name} = req.body

//保存到数据库

Classify.create({name}).then(result=>{

if(result){

//添加成功后的响应

res.json({

code: 200, //自定义标识,不是状态码

msg: ‘添加成标识功’

})

}else{

res.json({

code: 300,

msg: ‘添加失败’

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘添加时出现异常’

})

})

})

//修改分类

router.post(‘/update’, function(req,res){

let C = req.body

if(!c._id){

res.json({

code:300,

msg:‘id参数不能为空!’

})

return

}

crud.update(Classify,{_id:c._id}, {name: c.name,no: c.no},res )

})

//删除分类

router.get(‘/de1’ , function(req,res){

let {_id} = req.query

if(!_id){

res.json({

code:300,

msg:‘id参数不能为空!’

})

return

}

crud.del(Classify,{_id},res)

})

//分页查询

router.get(‘/find’, function(req,res){

//let {page,pagesize,kw,s} = req.query

//let where = {}

//if(kw){

// where = {name: {$regex: kw}}

//}

//let sort = {}

//if(s == 1){

// sort = {no: -1}

//}else if(s == 2){

// sort = {no: 1}

//}

//crud-find(classify,page, pegeSize,where,sart ,res)

let {page,pagesize,sort = 1} = req.query //sort 排序 1降序 2升序,有值的话按值,没值的话按默认值

//s为排序的条件对象

let s = {}

if(sort == 1){

s = {no: -1}

}else if(sort == 2){

s = {no: 1}

}

crud.find(Classify,page, pegeSize,{},s ,res)

})

//非分页查询

router.get(‘/query’, function(req,res){

let {sort = 1} = req.query //sort 排序 1降序 2升序,有值的话按值,没值的话按默认值

//s为排序的条件对象

let s = {}

if(sort == 1){

s = {no: -1}

}else if(sort == 2){

s = {no: 1}

}

crud.query(Classify,{},s ,res)

})

module.exports = router;

在这里插入图片描述

第二步

在 入口文件引入路由,示例代码如下

//引入路由文件

var classifyRouter = require(‘https://blog.csdn.net/2401_84620288/article/details/routes/classify’);

//配置一个路由

app.use(‘/classify’, classifyRouter);

第三步:在 工具中测试路由是否可用

在这里插入图片描述

http://localhost:3000/classify/add

{

“name”: “男装”

}

{

code: 200,

msg: ‘添加成功’

}

在这里插入图片描述

在这里插入图片描述

3.4、封装CRUD(封装好的可以直接拿出来用

公共方法,写一遍不用动直接就可以用

在 中封装增删改查的方法,示例代码如下

添加的功能方法

function add(model,params,res){

model.create(params).then(result=>{

if(result){

//添加成功后的响应

res.json({

code: 200,

msg: ‘添加成功’

})

}else{

res.json({

code: 300,

msg: ‘添加失败’

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘添加时出现异常’

})

})

}

修改的公共方法

function update(model,where,params,res){

// 修改的时候传入两个条件(修改的条件,修改的值) 返回一个result

model.updateOne(where,params).then(result=>{

//result 里面放的是修改结果的对象

//result里面有个对象 n ,n>0 证明修改成功了很多条,n是几就是几条

//else 就是修改失败

//catch 就是修改时出现异常

if(result.n > 0){

res.json({

code: 200,

msg: ‘修改成功’

})

}else{

res.json({

code: 300,

msg: ‘修改失败’

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘修改时出现异常’

})

})

}

删除的公共方法

function del(model,where,res){

model.findoneAndDelete(where).then(result=>{

if(result){

//添加成功后的响应

res.json({

code: 200,

msg: ‘删除成功’

})

}else{

res.json({

code: 300,

msg: ‘删除失败’

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘删除时出现异常’

})

})

}

分页查询公共方法(与上面不分页查询按需要选其一即可

async function find(model,page,pageSize,where,sort,res){

//判断page是否存在

if(!page){

page = 1

}else{

page = parseInt(page)

if(isNaN(page)){ //非数字

page = 1

}else{ //是数字

if(page < 1){

page = 1

}

}

}

//判断pageSize是否为空

if(!pageSize){

pageSize = 10

}else{

//默认每页10条,如果进行赋值,每页最低每5条换页,最多不超过30条换页

pageSize = parseInt(pageSize)

if(isNaN(pageSize)){ //非数字

pageSize = 10

}else{ //是数字

if(pageSize < 5){

pageSize = 5

}else if(pageSize > 30){

pageSize = 30

}meyiye

}

}

//计算总页数,总页数 = Math.ceil(总记录数 ÷ 每页条数)

let count = 0

await model.find(where).countdocuments().then(result=>{

count = result

})

// await model.find(where).count().then(result=>{

// count = result

// })

//如果上一步还没执行完,就执行下一步,就会出错,所以要把异步变同步,所以要在上一步 和 执行查询操作 前面加上 await

//总页数 totalPage

let totalPage = Math.ceil(count/pageSize)

//判断当前页码是否大于总页数

//如果一条都没有的话,count为0 所以totalPage也会为0(0/每页条数 还为0

if(totalPage > 0 && page > totalPage){

page = totalPage

}

//skip查询的起始位置,起始位置 = (当前页码 - 1)× 每页条数

let start = (page - 1)*pageSize

//执行查询操作

//跳过多少条 skip从哪里开始看 limit看多少条

await model.find(where).sort(sort).skip(start).limit(pageSize).then(result=>{

if(result && result.length > 0){

res.json({

code: 200,

msg: ‘查询成功’,

data: result,

page,

pageSize,

count,

totalPage

})

}else{

res.json({

code: 300,

msg: ‘没有查询到数据’,

data: [],

page,

pageSize,

count,

totalPage

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘查询时出现异常’

})

})

}

非分页查询公共方法(与下面分页查询按需要选其一即可

function query(model,where,sort,res){

model.query(where).sort(sort).then(result=>{

if(result && result.length > 0){

res.json({

code: 200,

msg: ‘查询成功’,

data: result

})

}else{

res.json({

code: 300,

msg: ‘没有查询到数据’,

data: []

})

}

}).catch(err=>{

res.json({

code: 400,

msg: ‘查询时出现异常’

})

})

}

需要在 文件中抛出以上函数

module.exports = {

add, //添加

update, //修改

del, //删除

find, //分页查询

query //非分页查询

}

3.5、 将来实现一个功能模块(上面理解,这个要会用

实现一个用户有关的模块 (模型对象,路由在app中的引用,封装好的,写完不用再改,唯一修改的就是,有新的功能写一个新的二级路由

第一步:创建模型、在文件下创建一个模块

我们要设计一个用户模块,就创建 文件,示例代码如下

(与其他模块不一样的地方,需要改的就是schema里面的属性;集合的名称 users 改成对应的以及抛出对象的名称

//引入

var mongoose = require(‘mongoose’)

let schema = new mongoose.Schema({ // schema 用于定义和数据库中字段相同的属性名称和数据类型

username: String , //用户的名称

pwd: String //用户密码

})

// users 将来数据库中叫的名字 最后一个字母必须s

let Users= mongoose.model(‘users’, schema)

//抛出

module.exports = Users

第二步:创建路由、

在文件下创建一个文件

//通过 express 导入一个路由

var express = require(‘express’);

var router = express.Router();

//抛出一个路由

module.exports = router;

在 入口文件引入路由,示例代码如下

//引入路由文件

var usersRouter = require(‘https://blog.csdn.net/2401_84620288/article/details/routes/users’);

//配置一级路由

app.use(‘/users’, usersRouter );//确定有没有引入成功,可以按住 Ctrl 鼠标放在 usersRouter 上呈现小手状,点击直接跳转到路由界面,能定位到,说明引入成功

第三步:功能接口,在中(如果其他模块直接改掉 Users 对应部分)

//var express = require(‘express’); 这是第一步的内容保留,这里只是为了展示写入位置

//var router = express.Router(); 这是第一步的内容保留,这里只是为了展示写入位置

//保存到数据库里面,导入Users

var Users = require(‘…/models/users’);

//存储数据库的方法全在 crud 里封装着

var crud = require(‘…/crud’);

//与crud里面对应

//添加用户

//通过 post 或 get , /users 后面 /add 找到这个方法

//服务端路由,就是通过 url地址与一个 函数 之间的 映射

router.post(‘/add’, function(req,res){

//接收参数 只要是post请求 就用body封装

let {username,pwd} = req.body

//调用自己封装的方法 .add( 放现在操作的模型,添加的数据就是{username=username 直接写username, pwd=pwd直接写pwd },res响应)

crud.add(Users,{username,pwd},res) //可以按住 Ctrl 鼠标放在 add 上呈现小手状,点击直接跳转查看封装思维

//或者写成

//let user = req.body

//crud.add(Users,user,res)

})

//修改用户

router.post(‘/update’, function(req,res){

//接收参数 只要是post请求 就用body

//user 整个对象

let user = req.body

//数组里只有ID是唯一修改的条件

crud.update(Users,{_id:user._id},{

username:user.username,

pwd:user.pwd

},res)

})

//删除用户

router.get(‘/del’,function(req ,res){

let {_id} = req.query

crud.del(Users,{_id},res)

})

//分页查询

router.get(‘/find’ , function(req,res){

let {page,pageSize} = req.query

//目前没有 查询条件, 排序 不需要 所以{}

crud.find(Users,page,pageSize,{},{},res)

})

//module.exports = router; 这是第一步的内容保留,这里只是为了展示写入位置

3.6、接口规范

全局配置

baseURL: http://localhost:3000

3.6.1、分类管理模块

添加分类

接口地址(路由,发请求:/classify/add

请求方法:POST

返回数据格式:JSON

请求参数

| 参数名称 | 参数类型 | 是否必填 | 参数描述 |

| — | — | — | — |

| name | String | 是 | 分类的名称 |

| no | Number | 否,默认值0 | 分类的排序 |

响应参数

| 参数名称 | 参数类型 | 参数示例 | 参数描述 |

| — | — | — | — |

| code | Number | 200 | 自定义,请求的结果状态,200为成功,300为失败,400为服务端异常 |

| msg | String | “添加成功” | 请求的结果描述 |

修改分类

接口地址(路由,发请求:/classify/update

请求方法:POST

返回数据格式:JSON

请求参数

| 参数名称 | 参数类型 | 是否必填 | 参数描述 |

| — | — | — | — |

| _id | String | 是 | 要修改的分类id |

| name | String | 否 | 分类的新名称 |

| no | Number | 否,默认值0 | 分类的新排序 |

响应参数

| 参数名称 | 参数类型 | 参数示例 | 参数描述 |

| — | — | — | — |

| code | Number | 200 | 自定义,请求的结果状态,200为成功,300为失败,400为服务端异常 |

| msg | String | “修改成功” | 请求的结果描述 |

删除分类

接口地址(路由,发请求:/classify/del

请求方法:GET

返回数据格式:JSON

请求参数

| 参数名称 | 参数类型 | 是否必填 | 参数描述 |

| — | — | — | — |

| _id | String | 是 | 分类的id |

响应参数

| 参数名称 | 参数类型 | 参数示例 | 参数描述 |

| — | — | — | — |

| code | Number | 200 | 自定义,请求的结果状态,200为成功,300为失败,400为服务端异常 |

| msg | String | “删除成功” | 请求的结果描述 |

分页查询分类

接口地址:/classify/find

请求方法:GET

返回数据格式:JSON

请求参数

| 参数名称 | 参数类型 | 是否必填 | 参数描述 |

| — | — | — | — |

| page | Number | 否,默认值1 | 当前页码 |

| pageSize | Number | 否,默认值10 | 每页查询条数,最少5条,最多30条 |

| sort | Number | 否,默认值1 | 按no字段的排序规则,1为降序,2为升序 |

响应参数

| 参数名称 | 参数类型 | 参数示例 | 参数描述 |

| — | — | — | — |

| code | Number | 200 | 请求的结果状态,200为成功,300为失败,400为服务端异常 |

| msg | String | “查询成功” | 请求的结果描述 |

| data | any | [{name:’’,no:’’},{}] | 请求成功返回的数据 |

| page | Number | 1 | 当前访问的页码 |

| pageSize | Number | 10 | 每页返回条数 |

| count | Number | 2000 | 总记录数 |

| totalPage | Number | 50 | 总页数 |

非分页查询所有分类

接口地址:/classify/query

请求方法:GET

返回数据格式:JSON

请求参数

| 参数名称 | 参数类型 | 是否必填 | 参数描述 |

| — | — | — | — |

| sort | Number | 否,默认值1 | 按no字段的排序规则,1为降序,2为升序 |

响应参数

文末

篇幅有限没有列举更多的前端面试题,小编把整理的前端大厂面试题PDF分享出来,一共有269页

    以上就是本篇文章【Web前端最全Vue开发一个电商全栈项目,2024前端高级面试题汇总解答】的全部内容了,欢迎阅览 ! 文章地址:http://gzhdwind.xhstdz.com/quote/73582.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://gzhdwind.xhstdz.com/mobile/ , 查看更多   
发表评论
0评