一个Flask + vue 前后端分离的 二手书App

效果展示:

https://blog.csdn.net/qq_42239520/article/details/88534955

所用技术清单



项目地址:项目地址

vue代码地址:vue代码地址

项目部分过程笔记:

后台:

项目结构

Secondhanbook /   项目目录
apps
v1
__init__.py 导入 urls
urls.py 路由配置
forms.py
models.py
views
user_views.py 用户相关视图
book_vews.py 书籍相关视图
config.py 配置文件
run.py 项目启动文件
manage.py 数据库迁移文件
Secondhanbook.py 初始化文件
utils 工具类目录
......
......

1. Flask_RESTful 的返回 和 缓存时候的自定义返回

flask_restful 在视图方法上加上marshal_with 装饰器,并传递你返回的模式。但当自定义时,需要返回自己的模式

return marshal(books,self.resource_fields,envelope='data')
resource_fields:自定义返回模式
data: 返回时,数据包装

2. 使用Flask_RESTful 下表单验证以及csrf防御

每当用户进入提交Post请求的页面,实例化一个表单form,返回csrf_token

csrf_token = form.csrf_token.current_token
return restful.success(data=csrf_token)

3.路由配置

api = Api(prefix='/api')
#用户相关
api.add_resource(Login,'/login/',endpoint='login')
......
#书籍相关
api.add_resource(BookAddView,'/bookadd/',endpoint='bookadd')
......

4.使用itsdangerous生成临时身份令牌

生成令牌

    def generate_auth_token(self,expiration=172800):#两天过期
s = Serializer(config.BaseConfig.SECRET_KEY,expires_in=expiration)
return s.dumps({'id':self.id})

身份检验

    def verify_auth_token(token):
s = Serializer(config.BaseConfig.SECRET_KEY)
try:
data = s.loads(token)
except Exception as e:
return None
user = FrontUserModel.query.get(data['id'])
return user

5.配置文件的书写方式,类继承的方式

class BaseConfig(object):
pass
class DevelopmentConfig(BaseConfig):
pass
class OnlineConfig(BaseConfig):
pass

6. celery 处理费时任务

@celery.task
def send_mail(subject,recipients,user_id):
......
@celery.task
def BookCacheAdd(books):
......

7.redis 存储数据bytes 问题解决

cache = redis.StrictRedis(host='127.0.0.1',port=6379,db=0,decode_responses=True)

8. 封装jsonfy的返回

class HttpCode(object):
Ok = 200
ParamerError = 400
Unauth = 401
ServerError = 500
def RestfulResult(code,message,data):
return jsonify({'code':code,'message':message,'data':data})
def success(message="",data=None):
return RestfulResult(HttpCode.Ok,message=message,data=data)
......

9.对axios 提交bytes类型数据进行form验证

from werkzeug.datastructures import MultiDict
......
myform = json.loads((request.data.decode('utf-8')))
form = LoginForm(MultiDict(myform))
......

10. flask 接收 接收多个文件axios 上传的多个文件


** AddBookView **
files = request.files
for file in files.values():
filename = upload.change_filename(secure_filename(file.filename)) **upload.vue**
for (var i = 0; i < this.files.length; i++) {
this.formdata.append('file' + i, this.files[i])
}
axios.post('api/bookadd/', this.formdata, {
headers: {'Content-Type': 'multipart/form-data'}
}).then(this.handleAxiosDone)

11.表单对files, 输入字段验证

from werkzeug.datastructures import CombinedMultiDict
form = Yourform(CombinedMultiDict([request.form, request.files])) // 合并 数据和文件
文件验证:
定义表单时,采用FileField这个类型
验证器导入:flask_wtf.file
flask_wtf.file.FileRequired 验证是否为空
flask_wtf.file.FileAllowed 验证上传文件后缀名

前台部分知识点:

项目结构

......
src
common
footer 页脚
alert 提示
fade 动画
gallary 画廊
......
store
... vuex相关
pages
home
components
header.vue
......
Home.vue
detail
me
sign
......
......

1. flask_result 返回时,提供默认值

返回数据时,当axios 未返回渲染到页面时,使用变量出错。

**** 解决方法: 定义默认值 例如有使用book.owner.username , book.owner.avatar时,否则报错无定义,并无法显示。

      book: {
owner: {......Object}
},

2. vuex store一个Message,供于消息提醒

项目基本上每个页面都有操作结果的提醒,封装一个消息提醒的组件 alert.vue

 <div v-show="isshow" class="alertBox" :style="{background:this.$store.state.color}">
{{mymessage}}
</div>
......
computed: {
mymessage () {
return this.$store.state.message
}
},
watch: {
mymessage (e) {
this.isshow = true
}
}
  state: {
message: '默认值',
color: ''
},
mutations: {
msgchange (state, res) {
state.message = res.message // color 自定义消息
state.color = res.color // color 自定义颜色
setTimeout(() => {
state.message = ''
state.color = ''
}, 3000)
}
} **** 重点:必须重置,否则下一次一样的消息将不显示 组件写一个发送提醒消息的方法,方便多次调用
handleemit (message, color) {
this.$store.commit('msgchange', {message: message, color: color})
}

3. 登陆注册:

利用 vue mounted 生命周期函数请求后端返回的csrf_token , 以及检验本地 localStorage,token是否过期。首次登陆成功返回存储token

 localStorage.setExpire('token', res.headers.token, 1000 * 60 * 60 * 24 * 2) // 设置两天过期
注册发送email 激活账号

4 . 使用better-scroll 加载更多

swiper 盒子必须小于content高度才能滚动

可以滚动后,页面将不能点击,解决:****
this.scroll = new BScroll(this.$refs.wrapper, {
click: true,
......
监听下拉方法,加载更多
pullUpLoad: {
// 当上拉距离超过盒子高度的的时候,就派发一个上拉加载的事件(触发条件)
threshold: 0
}
监听事件
this.scroll.on('pullingUp', () => {
axios.get('/api/booklist/?start=' + this.start).then(this.handleAxiosSuccess)
}) *** 对于下拉加载更多,双重遍历,遍历页码对应的数据
v-for="(p,index) in page"
v-for="item in booklist[index]" :key="item.id" // booklist[index] 为第几次下拉的返回的数据

5. vue-awesome-swiper

图片点击事件
监听事件:
on: {
click: function (e) {
window.open(e.target.src) // 跳转到网页
}
}
使用:
<swiper :options="swiperOption"> swiperOption为参数{ loop: true,effect: 'fade'......}
<!-- slides -->
<swiper-slide v-for ='item of swiperList' :key="item.id">
<img class="swiper-img" :src="item.url" alt=""> // 传递图片url
</swiper-slide>
</swiper> 画廊 组件关键参数:
// observer启动动态检查器(OB/观众/观看者),当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper。
// 默认false
observer: true,
observeParents: true

6. 过滤器,传递data中的值,并且使用v-html 显示

v-html="$options.filters.filemotion(comment.content,emotions)"  //       emotions: [] 是data中自定义的值
本过滤器是对,表情的插入表情标签的过滤 [赞] [哈哈] 替换成 图片
方法:
emotions格式 :
filemotion (value, emotions) {
value = value.replace(/(\[.+?\])/g, (e, e1) => {
for (var i in emotions) {
if ((emotions[i].value.indexOf(e1)) > -1) {
return '<img src="' + emotions[i].icon + '">'
}
}
})
return value
}

7. axios 更改请求头:

 axios.post('/api/comment/',参数, {
headers: {
'Content-Type': 'application/json'
......
}
})

8. Proxytable设置跨域,进行数据交互

    proxyTable: {
'/api': {
target: 'http://127.0.0.1:5000', //目标接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api': '/v1/api/' //重写接口
}
}
}

9.router 模式

路由 mode="history"模式

当前端项目结合到flask 项目中,当vue 路由为history模式时,出现“刷新页面报错404”的问题

这是因为这是单页应用…其实是因为调用了history.pushState API 所以所有的跳转之类的操作
都是通过router来实现的,解决这个问题很简单,只需要在后台配置如果URL匹配不到任何静态资源

进入新页面,不回到页面顶部解决:

  scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
},

Flask + vue 前后端分离的 二手书App的更多相关文章

  1. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题

    原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...

  2. 解决Django+Vue前后端分离的跨域问题及关闭csrf验证

      前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道   在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...

  3. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  4. 两个开源的 Spring Boot + Vue 前后端分离项目

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  5. beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)

    具体过程就不说,是搞这个的自然会动,只把关键代码贴出来. beego和vue前后端分离开发,beego承载vue前端分离页面部署 // landv.cnblogs.com //没有授权转载我的内容,再 ...

  6. Springboot+vue前后端分离项目,poi导出excel提供用户下载的解决方案

    因为我们做的是前后端分离项目 无法采用response.write直接将文件流写出 我们采用阿里云oss 进行保存 再返回的结果对象里面保存我们的文件地址 废话不多说,上代码 Springboot 第 ...

  7. dotnetcore vue+elementUI 前后端分离架二(后端篇)

    前言 最近几年前后端分离架构大行其道,而且各种框架也是层出不穷.本文通过dotnetcore +vue 来介绍 前后端分离架构实战. 涉及的技术栈 服务端技术 mysql 本项目使用mysql 作为持 ...

  8. shiro vue 前后端分离中模拟登录遇到的坑

    系统采用jeeplus框架(ssm+redis+shiro+mongodb+redis),默认是了JSP未做前后端分离,由于业务需要已经多终端使用的需求(H5.小程序等),需要实现前后端分离.但是由于 ...

  9. ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

    前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...

随机推荐

  1. SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf 4节课

    1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...

  2. nginx入门二

    反向代理: proxy_pass server { listen 80; location /n { proxy_pass http://127.0.0.1:8000/test; } location ...

  3. K中心点算法之PAM

    一.PAM聚类算法:         选用簇中位置最中心的对象,试图对n个对象给出k个划分:代表对象也被称为是中心点,其他对象则被称为非代表对象:最初随机选择k个对象作为中心点,该算法反复地用非代表对 ...

  4. 《Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks》

    <Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks> 论文主要的三个贡 ...

  5. QML C++插件dll引用

    插件的创建非常简单,但是它可以复用,并且为不同的应用程序扩展类型.使用创建的插件是非常灵活的解决方案.关于插件一个很好的例子见QmlBook-In-Chinese 中最后一章介绍的例子. 本文主要备忘 ...

  6. 使用光盘搭建本地yum源

    刚装好的系统,想安装一些常用软件和一些包组的时候,就可以使用安装光盘搭建本地yum 第一步:挂载安装光盘 mount /dev/cdrom /mnt 第二步:编辑repo yum源文件 [root@l ...

  7. Go语言规格说明书 之 内建函数(Built-in functions)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  8. Hibernate 常用jar包 分析

    antlr-2.7.6.jar的作用 ANTLR (ANother Tool for Language Recognition) 是一个PCCTS制定的语言工具,它为他创建认定者,程序编译者,翻译者提 ...

  9. TestNG配置注解

    以下是TestNG支持的注释列表: 注解 描述 @BeforeSuite 在该套件的所有测试都运行在注释的方法之前,仅运行一次. @AfterSuite 在该套件的所有测试都运行在注释方法之后,仅运行 ...

  10. pytest十:用例 a 失败,跳过测试用例 b 和 c 并标记失败 xfail

    当用例 a 失败的时候,如果用例 b 和用例 c 都是依赖于第一个用例的结果,那可以直接跳过用例 b 和 c 的测试,直接给他标记失败 xfail用到的场景,登录是第一个用例,登录之后的操作 b 是第 ...