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

1.环境1.安装nvm2.安装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

Vetur Vetur是用来识别.vue文件的,用来给.vue文件中的代码做语法高亮的。用VSCode开发Vue项目,这个插件是必装的! ESLint ESLint是专门针对Vue项目单独开发的一个代码规范的插件。在团队中协作开发中,推荐安装此插件,能统一代码风格。 Vue3 Snippets 是否有良好的代码自动补全功能,是评判一个开发工具好坏的一个核心要素。而Vue VSCode Snippets则是专门做这个事情的,他根据Vue项目语法,添加了一些代码片段,大大提高了我们编写Vue项目的效率。 Bookmarks 用于做标记的,在大型项目中,如果经常要在几个地方跳来跳去,那么可以使用Bookmarks来实现跳转。使用方式和快捷命令可以在安装Bookmarks的时候,查看他的介绍。 Bracket Pair Colorizer 某段代码太长的时候,我们通常是根据代码缩进,来寻找匹配的符号,但是Bracket Pair Colorizer可以通过颜色来进行配对,能节省我们寻找代码的时间,大大提高效率。 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搭建结构

2.element-icon组件的使用

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

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

2.然后在script中导入

3.合适位置引用使用

3.iconfont组件的使用

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

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

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

1.安装

在工程目录下

npm install vue-router@4

2.页面跳转

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

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需要跳转的组件里添加路由信息

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

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 = null

this.user = null

this.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 = user

this.token = token

localStorage.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

});

// 请求之前的拦截器,用来设置JWT

this.http.interceptors.request.use(config => {

const token = auth.token

if (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验证

参考文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: