基于前后端分离的增删改查

一.后端

1.了解前后端

至少两台服务器

访问
浏览器-->前端服务器-->后端服务器(注意端口不要一样)

返回数据

后端服务器-->前端服务器-->浏览器

2.Controller

package top.remained.controller;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.remained.bean.User;
import top.remained.service.UserService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Project:before-after
 * Date:2022/8/18
 * Time:18:37
 * Description:TODO
 *
 * @author lmk
 * @version 1.0
 */
@RestController
@RequestMapping("user")
@CrossOrigin(value = "http://localhost:8080",maxAge = 3600)
@Slf4j
@Api("user")
public class UserController {
    @Autowired
    UserService userService;
    @GetMapping("/login")
    public User login(String uName, String pwd){
        log.info("登录"+uName);
        return userService.login(uName, pwd) ;
    }

    @GetMapping("/findAllUsers")
    public Map findAllUsers( Integer index){
        if (index == null) {
            index =0;
        }
        int count = userService.getCount();
        int finalPage = count%3==0? count/3:count/3+1;
        Map<Object, Object> hashMap = new HashMap<>();
        List<User> users = userService.findAllUsers(index, 3);
        hashMap.put("users",users);
        hashMap.put("finalPage",finalPage);
        log.info("进入findAllUsers");
        return hashMap;
    }
    @RequestMapping("/delUser")
    public int  delUser(Integer uid){
        log.info("进入删除"+uid);
        if (uid != null) {
            userService.delUser(uid);
           return 1;
        }
        return 0;
    }
    @RequestMapping("/addUser")
    public int addUser(User user){

        log.info("添加用户"+user.getUId());
        return userService.addUser(user);
    }
    @RequestMapping("/updateUser")
    public int updateUser(User user){
        log.info("更改用户"+user.getUId());
        return userService.updateUser(user);
    }
    @RequestMapping("/findUserById")
    public User findUserById(Integer id){
        log.info("findUserById用户"+id);
        System.out.println( userService.findUserById(id).getUName());
        return userService.findUserById(id);
    }
//    根据uName进行模糊查询
    @RequestMapping("/findUserByLikeName")
    public List<User> findUserByLikeName(String uname){
        log.info("进入模糊查询"+uname);
        return userService.findUserByLikeName(uname);
    }
}

3.遇到的问题

1.跨域问题

value 是前端的路径

@CrossOrigin(value = "http://localhost:8080",maxAge = 3600)

2.为什么我第二个返回的是Map而不用List

我要传末页

List传回去的数据

[{"pwd":"123","type":1,"uname":"admin","uid":1},
{"pwd":"123456","type":2,"uname":"胡歌","uid":2},
{"pwd":"123456","type":2,"uname":"张哈哈","uid":5}]

前台获取数据

this.users=req.data

Map传的数据

{"users":[{"pwd":"123","type":1,"uid":1,"uname":"admin"},
{"pwd":"123456","type":2,"uid":2,"uname":"胡歌"},
{"pwd":"123456","type":2,"uid":5,"uname":"张哈哈"}],
"finalPage":8}

前台获取数据

this.users=req.data.users

注:从后台给的数据 变量都是小写的 即uId=>uid

二.前端

1.login.vue

<template>
    <div>
        <form>
            用户名:<input type="text" name="uName" v-model="uName"><br>
            密码:<input type="text" name="pwd" v-model="pwd"><br>
            <input type="button" value="登录" v-on:click="login" />
        </form>
<!--        映射 换模板 ,相当于超链接-->
<!--        <router-link to="/index">/index</router-link><br>-->
<!--        <router-link to="/test">/test</router-link><br>-->
<!--        <router-link to="/findAllUsers">查询所有用户</router-link>-->
    </div>
</template>

<script>
    export default {
        name: `login`,
        // 用来封装数据的
        data(){
            return{
                uName:'',
                pwd:''

            }

        },
        methods: {
            login: function(){
                //变量为未被使用时报错
                //获取模型中的数据
                let uName = this.uName;
                let pwd = this.pwd;
                // const  that=this
                //传给后台的数据
                this.$http.get("http://localhost:8081/user/login?uName="+uName+"&pwd="+pwd).then(req => {
                        // 判断有没有返回对象
                if(typeof(req.data) == 'object'){
                    this.$router.push({name:'user_list'})
                    //,params:{sname: uName}
                }else {
                    alert("用户名或密码错误");
                }




                }

                );
            }

        }

    }
</script>

<style scoped>

</style>

效果

 

2.user_list.vue

<template>

        <div id="body">
            <form>
            <input type="search" v-model="name">
                <input type="button" v-on:click="likeName" value="搜索">
            </form>
            <table  id="mytable" cellspacing="0">
                <caption> </caption>
                <tr>
                    <th scope="col">id</th>
                    <th scope="col">姓名</th>
                    <th scope="col">密码</th>
                    <th scope="col">类型</th>
                    <th scope="col">操作</th>

                </tr>
                <tr v-for="(item,index) in users" :key="index">
                    <td class="row">{{item.uid}}</td>
                    <td class="row">{{item.uname}}</td>
                    <td class="row">{{item.pwd}}</td>
                    <td class="row">{{item.type}}</td>
                    <td class="row">
                        <button id="del" class="btn btn-primary" v-on:click="del(item.uid)">删除</button>
                        <button  v-on:click="update(item.uid)">修改</button>
                    </td>
                </tr>
            </table>
            <button v-on:click="add()">添加</button>
<!--分页-->
            <button v-if="index>0" v-on:click="firstPage(0)">首页</button>
            <button v-if="index>0" v-on:click="upPage(index-1)">上一页</button>
            <button v-if="index<finalPage" v-on:click="downPage(index+1)">下一页</button>
            <button v-if="index<finalPage" v-on:click="endPage(finalPage)">末页</button>

<!--            接受页面跳转参数-->
            <h1>{{ $route.params.sname}}</h1>
        </div>
</template>

<script>

    export default {
        name: `user_list`,

        data(){

            return{


                users:[
                    {
                        //uId自动转换为uid
                        uid:'',
                        uname:'',
                        pwd:'',
                        type:''
                    }
                ],
                index:0,
                finalPage:0,
                name:'输入要搜索的名字',
            }

        },
        mounted(){


            this.$http.get("http://localhost:8081/user/findAllUsers?index=0&size=2").then(req => {

                this.users=req.data.users
                //获取末页,加载时获取一次就行 第一页index=0
                this.finalPage=req.data.finalPage-1




            })
        },
        methods: {
            //页面操作
            firstPage: function (index) {
                    this.$http.get("http://localhost:8081/user/findAllUsers?index="+index).then(req => {

                        this.users=req.data.users
                        this.index = index;

                    });
                },
            upPage: function (index) {
                this.$http.get("http://localhost:8081/user/findAllUsers?index="+index).then(req => {

                    this.users=req.data.users

                    this.index = index;

                });
            },
            downPage: function (index) {
                this.$http.get("http://localhost:8081/user/findAllUsers?index="+index).then(req => {

                    this.users=req.data.users

                    this.index =index;


                });
            },
            endPage: function (index) {
                this.$http.get("http://localhost:8081/user/findAllUsers?index="+index).then(req => {

                    this.users=req.data.users

                    this.index =index;


                });
            },
            //删
            del: function (uid) {
                this.$http.get("http://localhost:8081/user/delUser?uid="+uid).then(req => {
                    if (req.data==1) {
                        alert("删除成功")

                    }else {
                        alert("删除失败")
                    }
                    location.reload()
                });
            },
            //增
            add: function () {
                        this.$router.push({name:'user_add'})
            },
            //改
            update: function (uid) {

                //从后端返回的数据全部时小写的 传user对象
                this.$http.get("http://localhost:8081/user/findUserById?id="+uid).then(req => {

                    this.$router.push({name:'update_user',params:{user: req.data} })


                });
            },
            //查
            likeName: function () {

                //从后端返回的数据全部时小写的 传user对象
                this.$http.get("http://localhost:8081/user/findUserByLikeName?uname="+this.name).then(req => {

                    this.$router.push({name:'user_like_name',params:{users: req.data} })


                });
            }

        }
    }
</script>

<style scoped>


    #body {
        text-align:center;
        font: normal 11px  "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
        color: #4f6b72;
        background: #E6EAE9;
    }

    a {
        color: #c75f3e;
    }

    #mytable {
        width: 700px;
        padding: 0;
        margin: 0;
    }

    caption {
        padding: 0 0 5px 0;
        width: 700px;
        font: italic 20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
        text-align: right;
    }

    th {
        font: bold 20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
        color: #4f6b72;
        border-right: 1px solid #C1DAD7;
        border-bottom: 1px solid #C1DAD7;
        border-top: 1px solid #C1DAD7;
        letter-spacing: 2px;
        text-transform: uppercase;
        text-align: left;
        padding: 6px 6px 6px 12px;
        background: #CAE8EA  no-repeat;
    }

    th.nobg {
        border-top: 0;
        border-left: 0;
        border-right: 1px solid #C1DAD7;
        background: none;
    }

    td {
        border-right: 1px solid #C1DAD7;
        border-bottom: 1px solid #C1DAD7;
        background: #fff;
        font-size:20px;
        padding: 6px 6px 6px 12px;
        color: #4f6b72;
    }


    td.alt {
        background: #F5FAFA;
        color: #797268;
    }

    th.spec {
        border-left: 1px solid #C1DAD7;
        border-top: 0;
        background: #fff no-repeat;
        font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
    }

    th.specalt {
        border-left: 1px solid #C1DAD7;
        border-top: 0;
        background: #f5fafa no-repeat;
        font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
        color: #797268;
    }
    /*---------for IE 5.x bug*/
    html>body td{ font-size:11px;}
    body,td,th {
        font-family: 宋体, Arial;
        font-size: 12px;
    }
    .color1{
        color: blue;
    }
</style>

效果

 3.user_add.vue

<template>
    <div>
        <form>
           用户名: <input type="text"  v-model="uName" ><br>
            密码:  <input type="text"  v-model="pwd" ><br>
           类型:  <input type="text"  v-model="type" ><br>

            <input type="button" value="提交" v-on:click="add()">
        </form>
    </div>
</template>

<script>
    export default {
        name: `user_add`,
        data(){
            return {
                    uName: '',
                    pwd: '',
                    type: '',
        }
        },
        methods: {
            add: function(){
               
                this.$http.get("http://localhost:8081/user/addUser?uName="+this.uName+"&pwd="+this.pwd+"&type="+this.type).then(req => {

                    if (req.data===1) {
                        alert("添加成功")

                    }else {
                        alert("添加失败")
                    }
                    this.$router.push({name:'user_list'})

                    }

                );
            }

        }

    }


</script>

<style scoped>

</style>

4.update.vue

<template>
    <div>
        <form>
                    <input type="hidden" v-model="uId">
            用户名: <input type="text"  v-model="uName" ><br>
            密码:  <input type="text"  v-model="pwd"><br>
            类型:  <input type="text"  v-model="type"><br>
            <input type="button" value="保存" v-on:click="save">
        </form>
<!--      获取参数的展示  <h1>{{ $route.params.user.uname}}</h1>-->
    </div>
</template>

<script>
    export default {
        name: `update_user`,
        data(){
            return {
                uName: '',
                pwd: '',
                type:'',
                uId:''
            }
        },mounted(){
            this.uName = this.$route.params.user.uname
            this.pwd = this.$route.params.user.pwd
            this.type = this.$route.params.user.type
            this.uId = this.$route.params.user.uid
        },

        methods: {
            save: function(){

                this.$http.get("http://localhost:8081/user/updateUser?uName="+this.uName+"&pwd="+this.pwd+"&type="+this.type+"&uId="+this.uId).then(req => {
                        if (req.data==1){
                            alert("更改成功")

                        } else {
                            alert("更改失败")
                        }
                    alert("跳转")
                   this.$router.push({name:'user_list'})
                    
                    }

                );
            }

        }

    }


</script>

<style scoped>

</style>

5.user_list.vue

<template>
    <div>
        <table  id="mytable" cellspacing="0">
            <caption> </caption>
            <tr>
                <th scope="col">id</th>
                <th scope="col">姓名</th>
                <th scope="col">密码</th>
                <th scope="col">类型</th>


            </tr>
            <tr v-for="(item,index) in users" :key="index">
                <td class="row">{{item.uid}}</td>
                <td class="row">{{item.uname}}</td>
                <td class="row">{{item.pwd}}</td>
                <td class="row">{{item.type}}</td>

            </tr>
        </table>
    </div>
</template>

<script>
    export default {
        name: "user_like_name",
        data(){
            return{

                users:[
                    {
                        //uId自动转换为uid
                        uid:'',
                        uname:'',
                        pwd:'',
                        type:''
                    }
                ],
            }
        },
        mounted(){
                this.users=this.$route.params.users
        },
    }
</script>

<style scoped>

</style>

6.index.js

import Vue from  'vue'
import Router from 'vue-router'
import login  from "@/components/login"
import index from  '@/components/index'
import test from "@/components/test"
import user_list from "@/components/user_list"
import user_add from "@/components/user_add";
import update_user from "@/components/update_user";
import user_like_name from "@/components/user_like_name";

//导包爆红,没让他自动导入依赖,通过Vue加载Router
Vue.use(Router)

//创建路由管理器  一个组件 切换不同模板
export  default new Router({
//    创建路由的数组  一个资源对应一个router对应一个对象{}
    routes:[{
        path:'/',
        name:'login',
        component:login
    },{
        path:'/index',
        name:'index',
        component:index
    },
        {
            //    映射路径
            path:'/test',
            name:'test',
            //    对应import的名字
            component:test
        },  {
            path:'/user_list',
            name:'user_list',
            component:user_list
        }, {
        path:'/user_add',
        name:'user_add',
        component:user_add
}, {
            path:'/update_user',
            name:'update_user',
            component:update_user
        }, {
            path:'/user_like_name',
            name:'user_like_name',
            component:user_like_name
        }]



})

7.main.js

import Vue from 'vue'
import App from './App.vue'
import router from  './router'
import axios from 'axios'
Vue.config.productionTip = false
//给axios定义一个名字$http
Vue.prototype.$http=axios
//全局的 可以取全部插件
//全局加载
//动态加载不需要重启
new Vue({
  render: h => h(App),
  router
}).$mount('#app')

8.App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
// import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    // HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

9.遇到的问题

1.地址栏出现?

 form表单你****的***。type=button不是submit,这样就行了

2.创建vue的步骤

,1.配置路由index.js
   (1 import test from "@/components/test"引入
(2  

//    创建路由的数组  一个资源对应一个router对应一个对象{}
    routes:[{
        path:'/',
        name:'login',
        component:login
    },{
        path:'/index',
        name:'index',
        component:index
    },}


2.script写入模板语法

script>
    export default {
        name: `test`,
        data(){
            return{
            //    里面json数据
                msg: 'hello',
                books:[{
            id:1,
            name: 'ss',
            author: 'zz'
            },{
                    id:2,
                    name: 'aa',
                    author: 'bb'
                }]
            }
        },
        //初始化时加载 mounted
        created(){
                alert(123)
        },    methods: {
            save: function(){

                this.$http.get("http://localhost:8081/user/updateUser?uName="+this.uName).then(req => {
                        if (req.data==1){
                            alert("更改成功")

                        } else {
                            alert("更改失败")
                        }
                    alert("跳转")
                   this.$router.push({name:'user_list'})

                    }

                );
            }

        }
    }
</script>

注意v-model和`login`

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前后端分离实现方式有很多种,以下是一种基于 Flask 和 Vue.js 的实现方式: 1. 后端使用 Flask 框架搭建 API,可以使用 Flask-RESTful 库来方便地实现 RESTful API。例如: ```python from flask import Flask, jsonify, request from flask_cors import CORS app = Flask(__name__) CORS(app) tasks = [ { 'id': 1, 'title': 'Task 1', 'description': 'This is task 1', 'done': False }, { 'id': 2, 'title': 'Task 2', 'description': 'This is task 2', 'done': False } ] @app.route('/tasks', methods=['GET']) def get_tasks(): return jsonify({'tasks': tasks}) @app.route('/tasks/<int:task_id>', methods=['GET']) def get_task(task_id): task = [task for task in tasks if task['id'] == task_id] if len(task) == 0: abort(404) return jsonify({'task': task[0]}) @app.route('/tasks', methods=['POST']) def create_task(): if not request.json or not 'title' in request.json: abort(400) task = { 'id': tasks[-1]['id'] + 1, 'title': request.json['title'], 'description': request.json.get('description', ''), 'done': False } tasks.append(task) return jsonify({'task': task}), 201 @app.route('/tasks/<int:task_id>', methods=['PUT']) def update_task(task_id): task = [task for task in tasks if task['id'] == task_id] if len(task) == 0: abort(404) if not request.json: abort(400) task[0]['title'] = request.json.get('title', task[0]['title']) task[0]['description'] = request.json.get('description', task[0]['description']) task[0]['done'] = request.json.get('done', task[0]['done']) return jsonify({'task': task[0]}) @app.route('/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id): task = [task for task in tasks if task['id'] == task_id] if len(task) == 0: abort(404) tasks.remove(task[0]) return jsonify({'result': True}) if __name__ == '__main__': app.run(debug=True) ``` 2. 前端使用 Vue.js 框架搭建页面,通过 AJAX 调用后端提供的 API 来实现增删改查功能。例如: ```html <!DOCTYPE html> <html> <head> <title>Tasks</title> <meta charset="utf-8"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <v-app> <v-container> <v-text-field label="Title" v-model="title"></v-text-field> <v-text-field label="Description" v-model="description"></v-text-field> <v-btn color="primary" @click="createTask">Create</v-btn> <v-data-table :headers="headers" :items="tasks" :search="search" item-key="id"> <template v-slot:top> <v-toolbar flat> <v-toolbar-title>Tasks</v-toolbar-title> <v-spacer></v-spacer> <v-text-field v-model="search" append-icon="search" label="Search"></v-text-field> </v-toolbar> </template> <template v-slot:item.actions="{ item }"> <v-icon small class="mr-2" @click="editTask(item)">edit</v-icon> <v-icon small @click="deleteTask(item)">delete</v-icon> </template> </v-data-table> <v-dialog v-model="dialog" persistent max-width="600px"> <v-card> <v-card-title> <span class="headline">{{ formTitle }}</span> </v-card-title> <v-card-text> <v-text-field label="Title" v-model="editedTask.title"></v-text-field> <v-text-field label="Description" v-model="editedTask.description"></v-text-field> </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="blue darken-1" text @click="closeDialog">Cancel</v-btn> <v-btn color="blue darken-1" text @click="saveTask">Save</v-btn> </v-card-actions> </v-card> </v-dialog> </v-container> </v-app> </div> <script> new Vue({ el: '#app', data: { title: '', description: '', headers: [ { text: 'ID', value: 'id' }, { text: 'Title', value: 'title' }, { text: 'Description', value: 'description' }, { text: 'Done', value: 'done' }, { text: 'Actions', value: 'actions' } ], tasks: [], search: '', dialog: false, formTitle: '', editedTask: { id: 0, title: '', description: '', done: false } }, created: function () { this.fetchTasks(); }, methods: { fetchTasks: function () { axios.get('/tasks') .then(response => { this.tasks = response.data.tasks; }) .catch(error => { console.log(error); }); }, createTask: function () { axios.post('/tasks', { title: this.title, description: this.description }) .then(response => { this.tasks.push(response.data.task); this.title = ''; this.description = ''; }) .catch(error => { console.log(error); }); }, editTask: function (task) { this.formTitle = 'Edit Task'; this.editedTask = Object.assign({}, task); this.dialog = true; }, saveTask: function () { axios.put('/tasks/' + this.editedTask.id, { title: this.editedTask.title, description: this.editedTask.description, done: this.editedTask.done }) .then(response => { var index = this.tasks.findIndex(task => task.id == response.data.task.id); Vue.set(this.tasks, index, response.data.task); this.dialog = false; }) .catch(error => { console.log(error); }); }, deleteTask: function (task) { axios.delete('/tasks/' + task.id) .then(response => { var index = this.tasks.findIndex(t => t.id == task.id); this.tasks.splice(index, 1); }) .catch(error => { console.log(error); }); }, closeDialog: function () { this.dialog = false; setTimeout(() => { this.editedTask = { id: 0, title: '', description: '', done: false }; }, 300); } } }); </script> </body> </html> ``` 以上代码仅供参考,具体实现方式可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值