zoukankan      html  css  js  c++  java
  • 前后端分离的一个小demo

    0、写在前面

    最近听人说现在的项目的都是前后端分离了,原来那种后端渲染模板的方式已然过时。

    而且最近自己做项目发现,前后端维护一个包里的代码确实痛苦不堪、、、

    为了让自己跟上时代的尾巴,加强开发的体验,就学习了vue.js和restful规范。

    发现果然是好东西,那就先攒出来一个小demo,后期再上大项目。

    1、资源接口表

    HTTP方法

    资源操作

    URL

    描述

    GET

    SELECT

    /book/api/v1.0/books

    查多个资源

    POST

    INSERT

    /book/api/v1.0/books

    新增资源

    GET

    SELECT

    /book/api/v1.0/books/<id>

    查单个资源

    PUT

    UPDATE

    /book/api/v1.0/books/<id>

    更新单个资源

    DELETE

    DELETE

    /book/api/v1.0/books/<id>

    删除单个资源

     

    2、实现

    前端vue.js+webpack模板+elemen-ui

     1 import Axios from 'axios'
     2 
     3 Axios.defaults.baseURL='http://localhost:5000'
     4 
     5 const BookListURL = '/book/api/v1.0/books'
     6 const BookURL = '/book/api/v1.0/books/'
     7 
     8 export function getBookListAPI() {
     9     return Axios.get(BookListURL).then(res=>res.data)
    10 }
    11 
    12 export function postBookListAPI(data) {
    13     return Axios.post(BookListURL,data).then(res=>res.data)
    14 }
    15 
    16 export function getBookAPI(id) {
    17   return Axios.get(BookListURL+'/'+id).then(res=>res.data)
    18 }
    19 
    20 export function putBookAPI(id,data) {
    21   return Axios.put(BookListURL+'/'+id,data).then(res=>res.data)
    22 }
    23 
    24 export function deleteBookAPI(id) {
    25   return Axios.delete(BookListURL+'/'+id).then(res=>res.data)
    26 }
    /src/restful/api.js
      1 <template>
      2     <div id="book">
      3         <h2>{{ msg }}</h2>
      4         <el-table
      5           :data="tableData"
      6           style=" 100%"
      7           align="center"
      8         >
      9           <el-table-column
     10             prop="id"
     11             label="ID"
     12             width="60">
     13           </el-table-column>
     14           <el-table-column
     15             prop="name"
     16             label="书名"
     17             width="180">
     18           </el-table-column>
     19           <el-table-column
     20             prop="price"
     21             label="价格"
     22             width="180">
     23           </el-table-column>
     24           <el-table-column label="操作">
     25       <template slot-scope="scope">
     26         <el-button
     27           size="mini"
     28           @click="handleGet(scope.$index, scope.row)">查看</el-button>
     29         <el-button
     30           size="mini"
     31           type="warning"
     32           @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
     33         <el-button
     34           size="mini"
     35           type="danger"
     36           @click="handleDelete(scope.$index, scope.row)">删除</el-button>
     37       </template>
     38     </el-table-column>
     39     </el-table>
     40       <br>
     41       <div id="add-form">
     42         <el-form ref="form" :model="form" label-width="80px">
     43         <el-form-item label="书名">
     44           <el-input v-model="form.name"></el-input>
     45         </el-form-item>
     46           <el-form-item label="价格">
     47           <el-input v-model="form.price"></el-input>
     48         </el-form-item>
     49           <el-form-item>
     50             <el-button type="primary" @click="addBook">新增</el-button>
     51             <el-button type="warning" @click="editBook">修改</el-button>
     52         </el-form-item>
     53         </el-form>
     54       </div>
     55     </div>
     56 </template>
     57 
     58 <script>
     59   export default {
     60     name: "Book",
     61     data() {
     62       return {
     63         msg: '图书管理系统',
     64         bookList:[],
     65         tableData: [],
     66         form:{
     67           name:'',
     68           price:''
     69         },
     70         current_id:''
     71       }
     72     },
     73     methods:{
     74       addBook(){
     75         this.$http.postBookListAPI(
     76           { 'name':this.form.name,
     77             'price':this.form.price,
     78           }
     79         ).then(
     80           res=>{
     81             this.tableData.push({
     82               id: res.data[0].id,
     83               name: res.data[0].name,
     84               price: res.data[0].price,
     85             })
     86           }
     87         ).catch(
     88           err=>{
     89             console.log(err.data)
     90           }
     91         )
     92       },
     93       handleGet(index,row){
     94         this.$http.getBookAPI(row.id).then(
     95           res=>{
     96             console.log(res.data)
     97           }
     98         ).catch(
     99           err=>{
    100             console.log(err.data)
    101           }
    102         )
    103       },
    104       handleEdit(index,row){
    105         this.form.name = row.name
    106         this.form.price = row.price
    107         this.current_id = row.id
    108 
    109       },
    110       handleDelete(index,row){
    111         this.$http.deleteBookAPI(row.id).then(
    112           res=>{
    113             console.log(res.data)
    114             this.tableData.splice(index,1)
    115           }
    116         ).catch(
    117           err=>{
    118             console.log(err.data)
    119           }
    120         )
    121       },
    122       editBook(){
    123         this.$http.putBookAPI(this.current_id,{
    124           'name':this.form.price,'price':this.form.price
    125         }).then(
    126           res=>{
    127             console.log(res.data)
    128             this.reloadData()
    129           }
    130         ).catch(
    131           err=>{
    132             console.log(err.data)
    133           }
    134         )
    135       },
    136       reloadData(){
    137         this.$http.getBookListAPI().then(
    138         res=>{
    139           this.bookList = res.data
    140           this.tableData = []
    141           for (let i=0; i<this.bookList.length; i++){
    142             this.tableData.push({
    143               id: this.bookList[i].id,
    144               name: this.bookList[i].name,
    145               price: this.bookList[i].price,
    146             })
    147           }
    148         }
    149       ).catch(
    150         err=>{
    151           console.log(err.data)
    152         }
    153       )
    154     }
    155     }
    156     ,
    157     created() {
    158       this.$http.getBookListAPI().then(
    159         res=>{
    160           this.bookList = res.data
    161           for (let i=0; i<this.bookList.length; i++){
    162             this.tableData.push({
    163               id: this.bookList[i].id,
    164               name: this.bookList[i].name,
    165               price: this.bookList[i].price,
    166             })
    167           }
    168         }
    169       ).catch(
    170         err=>{
    171           console.log(err.data)
    172         }
    173       )
    174     }
    175   }
    176 </script>
    177 
    178 <style scoped>
    179 
    180 </style>
    /src/components/Book.vue

    后端flask+flask_restful

      1 # -*- coding: UTF-8 -*-
      2 
      3 from flask import Flask,jsonify,request
      4 from flask_sqlalchemy import SQLAlchemy
      5 from flask_restful import reqparse, abort, Api, Resource
      6 
      7 
      8 
      9 app = Flask(__name__)
     10 api = Api(app)
     11 
     12 class Config:
     13     SECRET_KEY = '1a1@z2'
     14     SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@127.0.0.1/book?charset=utf8'
     15 
     16     #SQLALCHEMY_TRACK_MODIFICATIONS = True
     17     #解决返回无法显示汉字问题
     18     JSON_AS_ASCII = False
     19     RESTFUL_JSON = dict(ensure_ascii=False)
     20     @staticmethod
     21     def init_app(app):
     22         pass
     23 
     24 app.config.from_object(Config)
     25 db=SQLAlchemy(app)
     26 
     27 
     28 #数据库模型
     29 class Book(db.Model):
     30     __tablename__ = 'book'
     31     id = db.Column(db.Integer, primary_key=True, index=True,autoincrement=True)
     32     name = db.Column(db.String(64), unique=True, index=True)
     33     price = db.Column(db.String(64))
     34 
     35     def __repr__(self):
     36         return '<Book %r>'%(self.name)
     37 
     38 
     39 
     40 def get_book(id):
     41     book_obj = Book.query.filter_by(id=id).first()
     42     if not book_obj:
     43         abort(404, message="id(%s) is not found"%(id))
     44     return book_obj
     45 
     46 #视图
     47 #解决前端跨域访问的问题
     48 @app.after_request
     49 def after_request(response):
     50     response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,session_id')
     51     response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS,HEAD')
     52     # 这里不能使用add方法,否则会出现 The 'Access-Control-Allow-Origin' header contains multiple values 的问题
     53     response.headers['Access-Control-Allow-Origin'] = '*'
     54     return response
     55 
     56 @app.route('/')
     57 def hello_world():
     58     return 'Hello World!'
     59 
     60 @app.route('/db_create')
     61 def db_create():
     62     db.create_all()
     63     return 'db create success!'
     64 
     65 #资源组的增查,对应get,post
     66 class BookListAPI(Resource):
     67     def __init__(self):
     68         self.reqparse = reqparse.RequestParser()
     69         self.reqparse.add_argument('name',type=str, required = True,
     70             help = "pleas send name", location = ['json','form'])
     71         self.reqparse.add_argument('price',type=str, required = True,
     72             help = "pleas send price", location = ['json','form'])
     73         self.returnData = { 'state':1,'data':[],'url':'','items_url':'' }
     74         super(BookListAPI, self).__init__()
     75 
     76     def get(self):
     77         self.returnData['url'] = '/book/api/v1.0/books'
     78         self.returnData['items_url'] = '/book/api/v1.0/books/<id>'
     79         books = Book.query.order_by(Book.id.asc()).all()
     80         for book_obj in books:
     81             book_info = { 'id': book_obj.id,
     82                           'name':book_obj.name,
     83                           'price':book_obj.price,
     84                           'url':'/book/api/v1.0/books/'+str(book_obj.id)
     85                           }
     86             self.returnData['data'].append(book_info)
     87         print self.returnData
     88         return jsonify(self.returnData)
     89 
     90     def post(self):
     91         book_name = self.reqparse.parse_args()['name']
     92         book_price = self.reqparse.parse_args()['price']
     93         new_book = Book(name=book_name,price=book_price)
     94         db.session.add(new_book)
     95         db.session.commit()
     96         book_info = {'id': new_book.id,
     97                      'name': new_book.name,
     98                      'price': new_book.price}
     99         self.returnData['data'].append(book_info)
    100         return jsonify(self.returnData)
    101 
    102 #单个资源的查询,对应get,put,delete
    103 class BookAPI(Resource):
    104     def __init__(self):
    105         self.reqparse = reqparse.RequestParser()
    106         self.reqparse.add_argument('name',type=str, required = True,
    107             help = "pleas send name", location = ['json','form'])
    108         self.reqparse.add_argument('price',type=str, required = True,
    109             help = "pleas send price", location = ['json','form'])
    110         self.returnData = {'state': 1, 'data': []}
    111         super(BookAPI, self).__init__()
    112 
    113     def get(self,id):
    114         book_obj = get_book(id)
    115         book_info = {'id': book_obj.id,
    116                      'name': book_obj.name,
    117                      'price': book_obj.price}
    118         self.returnData['data'].append(book_info)
    119         return jsonify(self.returnData)
    120 
    121     def put(self,id):
    122         book_obj = get_book(id)
    123         book_name = self.reqparse.parse_args()['name']
    124         book_price = self.reqparse.parse_args()['price']
    125         db.session.add(book_obj)
    126         db.session.commit()
    127         book_info = {'id': book_obj.id,
    128                      'name': book_obj.name,
    129                      'price': book_obj.price}
    130         self.returnData['data'].append(book_info)
    131         return jsonify(self.returnData)
    132 
    133     def delete(self,id):
    134         book_obj = get_book(id)
    135         db.session.delete(book_obj)
    136         db.session.commit()
    137         return jsonify(self.returnData)
    138 
    139 api.add_resource(BookListAPI, '/book/api/v1.0/books')
    140 api.add_resource(BookAPI, '/book/api/v1.0/books/<id>')
    141 
    142 if __name__ == '__main__':
    143     app.run(debug=True)
    app.py

    3、经验总结

    简单的练习下前后端分离的项目模式,感觉restful的风格也不是必须的,最后只要前后端接口能统一就Ok了、、

  • 相关阅读:
    从零开始学架构(三)UML建模
    【网址收藏】博客园主题美化
    完美解决国内访问GitHub速度太慢的难题
    SpringBoot+slf4j线程池全链路调用日志跟踪 二
    SpringBoot+slf4j实现全链路调用日志跟踪 一
    2021年java最全面试宝典【核心知识整理】
    [中级]系统集成项目管理工程师历年真题及参考答案
    线程池ThreadPoolExecutor最全实战案例
    大厂git分支管理规范:gitflow规范指南
    IdentityServer4
  • 原文地址:https://www.cnblogs.com/cx59244405/p/11402992.html
Copyright © 2011-2022 走看看