这篇博客是上一篇的后台,使用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搭建结构
<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-menu
default-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 = 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导入文章来源:https://www.toymoban.com/news/detail-630790.html
from flask_cors import CORS
cors=CORS()
3.初始化到app文章来源地址https://www.toymoban.com/news/detail-630790.html
from exts import cors
cors.init_app(app,resources={r"/cmsapi/*":{"origins":"*"}})#9.cors绑定到app
csrf.exempt(cmsapi_bp)#这个蓝图的请求不进行crsf验证
到了这里,关于Flask学习笔记_异步CMS(五)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!