Flask学习笔记_异步CMS(五)

Flask学习笔记_异步CMS(五)

  • 1.环境
    • 1.安装nvm
    • 2.安装node
  • 2.使用vue-cli创建项目
  • 3.安装相关插件
  • 4.后台CMS开发
    • 1.页面结构
      • 1.app.vue搭建结构
      • 2.element-icon组件的使用
      • 3.iconfont组件的使用
    • 2.使用[Vue-router](https://router.vuejs.org/installation.html)实现页面跳转
      • 1.安装
      • 2.页面跳转
    • 3.[JWT](https://zlkt.net/post/detail/60)鉴权
    • 4.[SerializerMixin](https://zlkt.net/post/detail/61)实现ORM模型序列化
    • 5.CMS访问权限
    • 6.[axios](https://github.com/axios/axios)网络请求库
    • 7.轮播图
      • 3.跨域请求

这篇博客是上一篇的后台,使用Vue3+VueCli+VueRouter+Vuex搭建,这个是 学习手册,具体的代码放到了 仓库。

1.环境

1.安装nvm

nvm(Node Version Manager)是一个用来管理node版本的工具。首先去nvm下载,然后安装,环境变量自动添加,如果没有手动添加。nvm version查看安装好的版本有哪些。
常用命令

nvm install [version]:安装指定版本的node.js 。
nvm use [version]:使用某个版本的node。
nvm list:列出当前安装了哪些版本的node。
nvm uninstall [version]:卸载指定版本的node。
nvm node_mirror [url]:设置nvm的镜像。
nvm npm_mirror [url]:设置npm的镜像。

2.安装node

以管理员身份运行命令行

nvm install 16.13.0

下载node时就会自动下载npm(Node Package Manager)。然后添加环境变量:C:\Program Files\nodejs
初始化:
在新的项目中,需要先执行npm init初始化,创建一个package.json文件用来保存本项目中用到的包。
安装包:
安装包分为全局安装和本地安装。全局安装是安装在当前node环境中,在可以在cmd中当作命令使用。而本地安装是安装在当前项目中,只有当前这个项目能使用,并且可以通过require引用。安装的方式只有-g参数的区别:

npm install vue   # 本地安装
npm install vue --save   # 本地安装,并且保存到package.json的dependice中
npm install vue --save-dev # 本地安装,并且保存到package.json的dependice-dev中
npm install vue -g   #全局安装
npm install -g @vue/cli  #全局安装vue-cli

本地安装:将安装包放在./node_modules下(运行 npm 命令时所在的目录),如果没有node_modules目录,会在当前执行npm命令的目录下生成node_modules目录。可以通过require()来引入本地安装的包。
全局安装:将安装包放在/usr/local下或者你node的安装目录。可以直接在命令行里使用。
卸载包:

npm uninstall [package]

更新包:

npm update [package]

搜索包:

npm search [package]

项目目录结构

node_modules:本地安装的包的文件夹。
public:项目出口文件。
src:项目源文件:
assets:资源文件,包括字体,图片等。
components:组件文件。
App.vue:入口组件。
main.js:webpack在打包的时候的入口文件。
babel.config.js:es*转低级js语言的配置文件。
package.json:项目包管理文件。

2.使用vue-cli创建项目

npm install -g @vue/cli#全局安装
npm install @vue/cli-service#在项目根目录中安装 vue-cli-service 的本地版本

输入vue --version,如果出现了版本号,说明已经下载完成。
vue create [项目名称]创建项目,然后手动选择vue3,安装完成后按他的提示,cd到目录下,启动服务器,就可以打开工程的vue网页。

npm run server#运行这个项目

3.安装相关插件

在vscode里面安装Vue相关插件:Vetur

  1. Vetur
    Vetur是用来识别.vue文件的,用来给.vue文件中的代码做语法高亮的。用VSCode开发Vue项目,这个插件是必装的!

  2. ESLint
    ESLint是专门针对Vue项目单独开发的一个代码规范的插件。在团队中协作开发中,推荐安装此插件,能统一代码风格。

  3. Vue3 Snippets
    是否有良好的代码自动补全功能,是评判一个开发工具好坏的一个核心要素。而Vue VSCode Snippets则是专门做这个事情的,他根据Vue项目语法,添加了一些代码片段,大大提高了我们编写Vue项目的效率。

  4. Bookmarks
    用于做标记的,在大型项目中,如果经常要在几个地方跳来跳去,那么可以使用Bookmarks来实现跳转。使用方式和快捷命令可以在安装Bookmarks的时候,查看他的介绍。

  5. Bracket Pair Colorizer
    某段代码太长的时候,我们通常是根据代码缩进,来寻找匹配的符号,但是Bracket Pair Colorizer可以通过颜色来进行配对,能节省我们寻找代码的时间,大大提高效率。

  6. Element-Plus组件库:element plus组件库是由饿了么前端团队专门针对vue框架开发的组件库,专门用于电脑端网页的。因为里面集成了很多组件,所以使用他可以非常快速的帮我们实现网站的开发。

npm install element-plus@1.2.0-beta.3 --save

Element-Plus组件的引入:在main.js中引入

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'const app = createApp(App)app.use(ElementPlus)
app.mount('#app')

然后就可以使用Element-Plus组件库开发前端组件。

4.后台CMS开发

1.页面结构

1.app.vue搭建结构

<template><div class="frame"><el-container class="frame-container"><el-header class="header"><a href="/" class="brand"><strong>知了</strong>管理系统</a><div class="header-content"><div class="greet">欢迎,周杰伦</div><div class="signout">回到首页</div></div></el-header><el-container><el-aside width="200px" class="aside"><el-row class="menu-row"><el-col :span="24"><el-menudefault-active="1"background-color="#545c64"active-text-color="#fff"text-color="#ddd"><el-menu-item index="1"><template #title><el-icon></el-icon><span>首页</span></template></el-menu-item><el-menu-item index="2"><template #title><el-icon></el-icon><span>轮播图</span></template></el-menu-item><el-menu-item index="3"><template #title><el-icon></el-icon><span>帖子管理</span></template></el-menu-item><el-menu-item index="4"><template #title><el-icon></el-icon><span>评论管理</span></template></el-menu-item><el-menu-item index="5"><template #title><el-icon></el-icon><span>用户管理</span></template></el-menu-item></el-menu></el-col></el-row></el-aside><el-container><el-main class="main">这里放网页内容部分</el-main><el-footer class="footer">这是Footer</el-footer></el-container></el-container></el-container></div>
</template><script>
export default {name: "App"
};
</script><style scoped>
.frame-container {height: 100vh;
}
.header {height: 60px;background: #00a65a;display: flex;
}.header .brand {width: 200px;margin-left: -20px;background-color: #008d4c;font-size: 20px;color: #fff;display: flex;justify-content: center;align-items: center;
}
.header .header-content {flex: 1;display: flex;justify-content: space-between;align-items: center;margin-left: 20px;color: #fff;
}.header-content .signout {cursor: pointer;}.aside {background-color: #545c64;
}.aside .el-menu .is-active {background-color: #434a50 !important;
}.footer {background: gray;
}
</style><style scoped>
.el-menu{border-right: none;
}
</style><style>
* {margin: 0;padding: 0;border: 0;text-decoration: none;vertical-align: baseline;
}
</style>

2.element-icon组件的使用

1.使用element的icon组件,先要安装

 npm install @element-plus/icons-vue --save

2.然后在script中导入

<script>
import {House,PictureRounded,Postcard,Comment,User} from "@element-plus/icons"
export default {name: "App",components: {House,PictureRounded,Postcard,Comment,User}
};
</script>

3.合适位置引用使用

<el-icon><House /></el-icon>
<el-icon><PictureRounded /></el-icon>
<el-icon><Postcard /></el-icon>
<el-icon><Comment /></el-icon>
<el-icon><User /></el-icon>

3.iconfont组件的使用

更多的icon可以使用阿里巴巴的iconfont
1.在里面添加自己需要的icon到项目,然后点击Font class,复制链接,到index.html里面添加这个css文件链接

<link rel="stylesheet" href="//at.alicdn.com/t/c/font_4197214_rad25hwlak.css"/>

2.复制icon代码,然后在合适的地方引用

2.使用Vue-router实现页面跳转

1.安装

在工程目录下

npm install vue-router@4

2.页面跳转

1.在components目录下建自己的vue文件(Home.vue)

<template><div id="home"><h1>首页</h1></div>
</template><script>
export default {name: "HomeComponent",
}
</script><style scoped></style>

2.在src目录下建一个router.js写路由管理(@代表src)

import { createRouter,createWebHashHistory } from "vue-router";
import HomeComponent from "@/components/Home.vue";
const routes = [{path:"/",component:HomeComponent,name:"home"}]
const router=createRouter({history:createWebHashHistory(),routes})
export default router;

3.在main.js中把路由绑定到app上

import router from"@/router"
app.use(router);

4.在app.vue的menu组件里面添加属性router=true

:router="true"

5.在app.vue需要跳转的组件里添加路由信息

<el-menu-item index="1" :route="{name:'home'}">

6.在跳转链接需要加载的地方加上

<router-view></router-view>

3.JWT鉴权

1.安装

pip install flask-jwt-extended

2.在exts里面导入

from flask_jwt_extended import JWTManager
jwt = JWTManager()

3.在config里面设置钥和过期时间

SECRET_KEY="FASDFNMLKSDF"
JWT_ACCESS_TOKEN_EXPIRES=timedelta(days=7)

4.在app.py里面init

from exts import jwt
jwt.init_app(app)

5.在登录的视图函数中判断是否是员工,即有访问cms的权限,保存jwt生成的token,返回给前端

from flask_jwt_extended import create_access_token
token =""
if user.is_staff():token=create_access_token(identity=user.id)return restful.ok(data={'token':token})

5.在登录的js里面,判断保存token,如果后端返回了这个值,就把他保存到应用》本地存储空间》JWT_TOKEN_KEY

 success: function (result){if(result['code'] == 200){localStorage.setItem("JWT_TOKEN_KEY", token);}

6.再下一次访问cms时,会判断前端是否带有JWT_TOKEN_KEY值,在apps/cmsapi/views.py里面写cms的首页视图函数,并注册到app

from flask import Blueprint#views.py
from utils import restful
from flask_jwt_extended import jwt_required,get_jwt_identity
bp=Blueprint("cmsapi",__name__,url_prefix="/cmsapi/")
@bp.get('/')
@jwt_required()
def index():identity=get_jwt_identity()return restful.ok(message="成功",data={"identity": identity})
from .views import bp as cmsapi_bp#__init__.py
from apps.cmsapi import cmsapi_bp#app.py
app.register_blueprint(cmsapi_bp)

4.SerializerMixin实现ORM模型序列化

1.安装

pip install SQLAlchemy-serializer

2.在UserModel里面继承并确定要返回的字段

from sqlalchemy_serializer import SerializerMixin
class UserModel(db.Model,SerializerMixin):
serialize_rules=("-_password",)
serialize_only=("id",'email','username','avatar','signature','join_time','is_staff','is_active',)#这样写可以避免循环序列化

3.在登录的视图函数里,当登录成功时,返回如下

return restful.ok(data={'token':token,"user":user.to_dict()})

4.当成功返回到客户端时,可以在js里面接收到这些信息

success: function (result){if(result['code'] == 200){var token = result['data']['token'];var user = result['data']['user'];localStorage.setItem("JWT_TOKEN_KEY", token);localStorage.setItem("USER_KEY", JSON.stringify(user));console.log(user);window.location = "/"}else{alert(result['message']);}}

5.CMS访问权限

1.首先在src/utils/auth.js里面对服务器发来的数据进行验证

const USER_KEY = "USER_KEY"
const TOKEN_KEY = "JWT_TOKEN_KEY"class Auth{constructor(){this.token = nullthis.user = nullthis.token = localStorage.getItem(TOKEN_KEY)const userJson = localStorage.getItem(USER_KEY)if(userJson){this.user = JSON.parse(userJson)}}static getInstance(){if(!this._instance){this._instance = new Auth()}return this._instance}setUserToken(user,token){this.user = userthis.token = tokenlocalStorage.setItem(USER_KEY,JSON.stringify(user))localStorage.setItem(TOKEN_KEY,token)}clearUserToken(){this.user = null;this.token = null;localStorage.removeItem(USER_KEY)localStorage.removeItem(TOKEN_KEY)}get is_authed(){if(this.user && this.token){return true}else{return false}}get is_staff(){if(!this.is_authed){return false;}if(this.user.is_staff){return true;}return false;}
}
export default Auth.getInstance()

2.然后在main.js里将上面的身份验证导入到app,变为全局变量$auth

import auth from "@/utils/auth"
app.config.globalProperties.$auth=auth;

3.在app.vue里面利用vue的生命周期里的mounted进行验证并返回首页

mounted(){if(!this.$auth.is_staff){window.location='http://127.0.0.1:5000';}
},

6.axios网络请求库

1.下载

npm install axios --save
npm install qs --save

2.在src/utils/auth.js里面对axios进行封装

import axios from "axios"
import auth from "./auth"
import qs from "qs";// http://www.zlkt.net
// const SERVER_HOST = "http://127.0.0.1:5000"
// window.location.origin// const SERVER_HOST = window.location.origin;// const SERVER_HOST = process.env.VUE_APP_SERVER_HOST// 配置文件
// .env
// .env.[mode]// mode:development、test、production// npm run server:用的是development模式
// npm run build:默认用的是production模式
// npm run build -- --mode [模式,比如:development]来指定具体的模式// 不同的模式,会读取对应模式下的配置参数
// development模式:.env.development配置文件
// production模式:.env.development配置文件// 在配置文件中,只能有三种类型的配置项:NODE_ENV,BASE_URL,VUE_APP_开头的
// 比如:VUE_APP_SERVER_HOST// 配置项中,只能是字符串,不能填一些js代码。比如window.location.origin
// 这样去写,实际上是一个"window.location.origin"class Http {constructor() {if(process.env.NODE_ENV == 'production'){this.server_host = window.location.origin;}else{this.server_host = "http://127.0.0.1:5000"}this.http = axios.create({baseURL: this.server_host + "/cmsapi",timeout: 1000*60});// 请求之前的拦截器,用来设置JWTthis.http.interceptors.request.use(config => {const token = auth.tokenif (token) {config.headers.common.Authorization = "Bearer " + token}return config})// 响应拦截this.http.interceptors.response.use(response => {return response.data;})}_post(url, data){return this.http.post(url, qs.stringify(data));}addBanner(data){const url = "/banner/add"return this._post(url, data);}getBannerList(){const url = "/banner/list"return this.http.get(url);}deleteBanner(banner_id){const url = "/banner/delete"return this._post(url, {"id": banner_id})}editBanner(data){const url = "/banner/edit"return this._post(url, data);}getPostList(page){const url = "/post/list?page=" + (page?page:1)return this.http.get(url);}deletePost(post_id){const url = "/post/delete"return this._post(url, {"id": post_id})}getCommentList(){const url = "/comment/list"return this.http.get(url)}deleteComment(comment_id){const url = "/comment/delete"return this._post(url, {"id": comment_id})}getUserList(page){const url = "/user/list?page=" + (page?page:1)return this.http.get(url)}activeUser(user_id, is_active){const url = "/user/active"return this._post(url, {"id": user_id, "is_active": is_active})}getBoardPostCount(){const url = "/board/post/count"return this.http.get(url);}getDay7PostCount(){const url = "/day7/post/count"return this.http.get(url)}
}export default new Http()

3.在main.js里面绑定到全局变量上

import http from "@/utils/http"
app.config.globalProperties.$http=http;

7.轮播图

1.在banner.vue里面写前端显示,css和js
2.写点击上传的view和form验证,config里面写图片存的地址

3.跨域请求

1.安装flask-cors

pip install -U flask-cors

2.exts导入

from flask_cors import CORS
cors=CORS()

3.初始化到app

from exts import cors
cors.init_app(app,resources={r"/cmsapi/*":{"origins":"*"}})#9.cors绑定到app
csrf.exempt(cmsapi_bp)#这个蓝图的请求不进行crsf验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OnlyOffice社区版破解最大连接限制部署

onlyoffice社区版部署并且破解最大连接数 docker镜像 docker pull onlyoffice/documentserver:5.3.1.265.4或更高的版本已经解决了此方法的Bug 运行镜像 docker run -d --name onlyoffice --restartalways -p 暴露端口号:80 onlyoffice/documentserver:5.3.1.26进入容器内部…

策略模式——算法的封装与切换

1、简介 1.1、概述 在软件开发中&#xff0c;常常会遇到这种情况&#xff0c;实现某一个功能有多条途径。每一条途径对应一种算法&#xff0c;此时可以使用一种设计模式来实现灵活地选择解决途径&#xff0c;也能够方便地增加新的解决途径。为了适应算法灵活性而产生的设计模…

Python faker 生成测试数据

pip install Faker faker官网 基本使用 from faker import Fakerif __name__ __main__:fake Faker()print(fake.name())print(fake.user_name())print(fake.phone_number())print(fake.address()) # 输出&#xff1a; Jorge Campbell grobbins 769.415.0562x2019 255 Broo…

[机器学习]线性回归模型

线性回归 线性回归&#xff1a;根据数据&#xff0c;确定两种或两种以上变量间相互依赖的定量关系 函数表达式&#xff1a; y f ( x 1 , x 2 . . . x n ) y f(x_1,x_2...x_n) yf(x1​,x2​...xn​) ​ 回归根据变量数分为一元回归[ y f ( x ) yf(x) yf(x)]和多元回归[ y …

【深度学习Week4】MobileNet_ShuffleNet

报错&#xff1a;unsafe legacy renegotiation disabled 解决方案&#xff1a; 尝试了更换cryptography36.0.2版本&#xff0c;以及更换下载链接的方法&#xff0c;都不行&#xff0c;最后采用了手动下载mat文件并上传到colab的方法 高光谱图像分类数据集简介Indian Pines&…

【果树农药喷洒机器人】Part2:机器人变量喷药系统硬件选型

本专栏介绍&#xff1a;免费专栏&#xff0c;持续更新机器人实战项目&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff01; 文章目录 一、引言二、变量喷药系统总体要求2.1系统功能要求2.2系统技术要求 三…

4.1 Windows终端安全

数据参考&#xff1a;CISP官方 目录 安全安装保护账户安全本地安全策略安全中心系统服务安全其他安全设置软件安全获取 一、安全安装&#xff08;以安装windows系统为例&#xff09; 选择合适的版本 商业版本&#xff1a;家庭版、专业版、专业工作站版、企业版特殊版本&…

pytest-xdist分布式测试原理浅析

目录 pytest-xdist执行流程&#xff1a; pytest-xdist 模块结构&#xff1a; pytest-xdist分布式测试原理&#xff1a; pytest-xdist源码浅读&#xff1a; pytest-xdist执行流程&#xff1a; 解析命令行参数&#xff1a;pytest-xdist 会解析命令行参数&#xff0c;获取用户…

海外媒体发稿:软文写作方法方式?一篇好的软文理应合理规划?

不同种类的软文会有不同的方式&#xff0c;下面小编就来来给大家分析一下&#xff1a; 方法一、要选定文章的突破点&#xff1a; 所说突破点就是这篇文章文章软文理应以什么样的视角、什么样的见解、什么样的语言设计理念、如何文章文章的标题来写。不同种类的传播效果&#…

【hive经典指标,离线数仓指标,ADS层指标分析】最近7日内连续3日下单用户数

1.建表语句 DROP TABLE IF EXISTS ads_order_continuously_user_count; CREATE EXTERNAL TABLE ads_order_continuously_user_count (dt STRING COMMENT 统计日期,recent_days BIGINT COMMENT 最近天数,7:最近7天,order_continu…

【JMeter】 使用Synchronizing Timer设置请求集合点,实现绝对并发

目录 布局设置说明 Number of Simulated Users to Group Timeout in milliseconds 使用时需要注意的点 集合点作用域 实际运行 资料获取方法 布局设置说明 参数说明&#xff1a; Number of Simulated Users to Group 每次释放的线程数量。如果设置为0&#xff0c;等同…

MongoDB基本命令使用

成功启动MongoDB后&#xff0c;再打开一个命令行窗口输入mongo&#xff0c;就可以进行数据库的一些操作。 输入help可以看到基本操作命令&#xff1a; show dbs:显示数据库列表 show collections&#xff1a;显示当前数据库中的集合&#xff08;类似关系数据库中的表&#xf…

vue2路由跳转和浏览器回退时弹窗的开启

文章目录 前言一、跳转到B页面的新增弹框具体流程二、返回A页面时打开详情弹框 前言 我这里有个需求是在A页面中的详情弹框中&#xff0c;点击按钮跳转到B页面的新增弹框中&#xff0c;并把A页面中的数据带过去填到B页面新增的form表单中&#xff0c;此时如果点击了浏览器的回…

以Java的方式将文件上传到阿里云OSS

文章目录 1. 开通对象存储服务2. 创建 AccessKey 密钥3. 通用代码实现 1. 开通对象存储服务 控制台 → 对象存储 OSS → 立即开通 Bucket列表 → 点击创建 Bucket 填写名称、地域&#xff0c;名称创建后不可修改&#xff0c;地域选择最近的&#xff0c;存储类型选择标准存储&…

2023-08-08 LeetCode每日一题(任意子数组和的绝对值的最大值)

2023-08-08每日一题 一、题目编号 1749. 任意子数组和的绝对值的最大值二、题目链接 点击跳转到题目位置 三、题目描述 给你一个整数数组 nums 。一个子数组 [numsl, numsl1, …, numsr-1, numsr] 的 和的绝对值 为 abs(numsl numsl1 … numsr-1 numsr) 。 请你找出 …

Maltab之滤波带来的时延问题

直接使用lowpass, highpass, bandpass等函数时会自动对filtering带来的时延给予补偿.但是对于自己设计的filter, 利用filt来进行滤波的话就会带来时延. 可以使用函数 grpdelay(filter,N,Fs) 来查看.对于FIR filter, 造成的时延对于不同的频率相应是一致的, 那么直接移动滤波后的…

Mysql8.0变更特性

性能翻倍 账户与安全 用户的创建和授权 在MySQL之前的版本&#xff0c;创建用户和给创建的用户授权可以一条语句执行完成&#xff1a; grant all privileges on *.* to test% identified by suibowenkuangtu6;在MySQL 8中&#xff0c;创建用户和授权需要分开执行&#xff0c…

STM32基础入门学习笔记:核心板 电路原理与驱动编程

文章目录&#xff1a; 一&#xff1a;LED灯操作 1.LED灯的点亮和熄灭 延迟闪烁 main.c led.c led.h BitAction枚举 2.LED呼吸灯&#xff08;灯的强弱交替变化&#xff09; main.c delay.c 3.按键控制LED灯 key.h key.c main.c 二&#xff1a;FLASH读写程序(有…

LeNet卷积神经网络-笔记

LeNet卷积神经网络-笔记 手写分析LeNet网三卷积运算和两池化加两全连接层计算分析 修正上图中H,W的计算公式为下面格式 基于paddle飞桨框架构建测试代码 #输出结果为&#xff1a; #[validation] accuracy/loss: 0.9530/0.1516 #这里准确率为95.3% #通过运行结果可以看出&am…

Stable Diffusion - Style Editor 和 Easy Prompt Selector 提示词插件配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132122450 Stable Diffusion 的 Prompt 的功能&#xff0c;可以用文字来描述想要生成的图像&#xff0c;根据输入来创造出逼真的图像。Prompt 支持…