校园旧物商城系统

news2024/12/22 12:01:46

一、项目说明

校园旧物回收商城,使用Springboot+Vue2.x开发,使用了JWT、MybatisPlus、JWT、ElementUI

项目已经开源在https://github.com/astudent2020/Campus_waste_recycling

image-20230616152826043

文章目录

  • 一、项目说明
    • 一、说明书
      • 1、用户主页:
      • 2、登录注册页面
      • 3、后台页面
      • 4、Token测试点
    • 二、页面展示
      • 1、首页
      • 2、旧物上传
      • 3、购物车
      • 4、个人中心
      • 5、订单管理
      • 6、登录
      • 7、注册
      • 8、后台首页
      • 9、个人中心
      • 10、用户管理
      • 11、类别管理
      • 12、商品管理
      • 13、订单管理
  • 二、主页说明
    • 一、说明
      • 1、修改之前的前端结构,使用utils完成统一接口
      • 2、更新front和back中的header、aside
        • 1、FrontTemplate.vue表示前端模板【Header、Aside】
        • 2、BackTemplateb.vue表示后端模板【Header、Aside】
    • 二、主页前端
      • 1、header
        • header头像
      • 2、Aside
      • 3、主页详情内容展示
        • 1、创建数据库
    • 三、主页的条件查询
    • 四、主页的详情展示
    • 五、购物车的处理
    • 六、购物车结算
    • 七、订单展示
    • 八、注册页面
    • 九、旧物上传
    • 十、权限设置
  • 三、后台说明
  • 四、bug记录日志
    • 1、使用utils设置config.js导致Token未能正常放入请求头
    • 2、路由守卫失效
  • 五、创新性实验
    • Vue中方法重写

一、说明书

1、用户主页:

主页:http://localhost:8080/ 用户只需要使用
http://localhost:8080/ 即可访问主页 主页的真实路径是
http://localhost:8080/index/body
主页展示

2、登录注册页面

登录:http://localhost:8080/user/login
登录页面
提供管理员登录和用户登录
用户名:daetz
密码:123456
登陆成功后会返回主页,并给出相关的提示,提示登录成功

登录成功

注册:http://localhost:8080/user/register

注册页面
注册需要用户输入个人信息,大部分都是使用小组件完成

3、后台页面

后台主页:http://localhost:8080/admin
用户只需要使用
http://localhost:8080/admin 即可访问管理员后台
管路员主页的真实路径是 http://localhost:8080/admin/pageone
后台页面展示

4、Token测试点

用户可以使用 http://localhost:8080/admin/pagetwo
来检测数据前端后端数据是否互通,以及Token是否能正常被放入请求头中。

Token测试

二、页面展示

1、首页

image-20230611194220459

2、旧物上传

image-20230611194247363

3、购物车

image-20230611194317765

image-20230611194327945

4、个人中心

image-20230611194345355

信息修改

image-20230611194357389

5、订单管理

image-20230611194414469

6、登录

image-20230611194439446

7、注册

image-20230611194458626

8、后台首页

image-20230611194546846

9、个人中心

image-20230611194618802

10、用户管理

image-20230611194639507

11、类别管理

image-20230611194654461

12、商品管理

image-20230611194712330

13、订单管理

image-20230611194734401

二、主页说明

一、说明

1、修改之前的前端结构,使用utils完成统一接口

image-20230607103548515

2、更新front和back中的header、aside

描述:

1、FrontTemplate.vue表示前端模板【Header、Aside】

  • Header

访问路径

/index

/shoppingcart

/back

/login

/register

image-20230607112855289

  • Aside

访问路径

/front/digital

/front/food

/font/book

image-20230607112941075

2、BackTemplateb.vue表示后端模板【Header、Aside】

image-20230607112400949

Aside数据包括

image-20230608102813305

二、主页前端

1、header

设置访问路径

image-20230607154619252

image-20230607112855289

image-20230607154718228

header头像

image-20230608080806300

                <el-menu-item index="9">
                    <el-dropdown style="width: 150px; cursor: pointer; text-align: right">
                        <div style="display: inline-block">
                            <img :src="userImage" alt=""
                                 style="width: 40px; border-radius: 50%; position: relative; right: 5px">
                            <span style="color: white">{{username}}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
                        </div>
                        <el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
                            <el-dropdown-item style="font-size: 12px; padding: 5px 0">
                                <router-link to="/back" style="text-decoration: none">后台管理</router-link>
                            </el-dropdown-item>
                            <el-dropdown-item style="font-size: 12px; padding: 5px 0">
                                <span style="text-decoration: none" @click="logout">退出</span>
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </el-menu-item>

2、Aside

访问路径

/front/digital

/front/food

/font/book

image-20230607112941075

image-20230608082039273

image-20230608082421307

3、主页详情内容展示

前台给出的数据

image-20230608082548573

1、创建数据库

  • id
  • name
  • price
  • imgUrl
  • description
  • sale
  • store

image-20230608083042401

增加部分数据

image-20230608083450642

三、主页的条件查询

image-20230608102149693

前端代码

<template>
  <div>
      <el-row>
          <el-col :span="8" v-for="item in goods" :key="item.id">
              <el-card shadow="hover" style="margin:20px 0;">
                  <div style="text-align: center;">
                      <img :src="item.imageUrl" style="height: 150px; width: 150px;">
                  </div>
                  <div style="padding: 14px;">
                      <span style="font-size: 14px;font-weight: bold">{{item.name}}</span>
                      <div style="margin-top:12px;">
                          <span style="font-size: 18px;color: #f60;">¥{{item.price}}</span>
                      </div>
                      <div style="text-align:right;margin-top:12px;">
                          <router-link :to="'/index/detail?'+item.id">
                              <el-button type="primary" size="small">查看详情</el-button>
                          </router-link>
                      </div>
                  </div>
              </el-card>
          </el-col>
      </el-row>
      <el-pagination
              background
              layout="prev, pager, next"
              :page-size=3
              :total="total"
              @current-change="page">
      </el-pagination>
  </div>
</template>

<script>
import request from "@/utils/request";
export default {
  name: 'book1',
  data () {
    return {
      total:null,
      goods:null,
    }
  },
  methods: {
      page(currentPage){ //alert("wait...") 动态分页
        const _this=this
        request.get('/goods/findByCategory/'+currentPage+'/3/1').then(function (resp){
          _this.goods=resp.data.data.records
          _this.total=resp.data.data.total
        })
      },
    },
  created() { //alert 初始化操作
      const _this=this
      request.get('/goods/findByCategory/1/3/1').then(function (resp){
        console.log(resp.data)
        _this.goods=resp.data.data.records
        _this.total=resp.data.data.total
        _this.size=resp.data.data.size
      })
    },
}
</script>

<style scoped>
</style>

后端代码

package com.example.cshand.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.cshand.DTO.ResultDataDTO;
import com.example.cshand.entity.Goods;
import com.example.cshand.mapper.GoodsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author daetz
 * @creat 2023/6/8
 **/
@RestController
@RequestMapping("/goods")
public class GoodsController {

		@Autowired
		private GoodsMapper goodsMapper;

		@RequestMapping("/findByCategory/{PageNum}/{size}/{categoryId}")
		public ResultDataDTO findGoods(
						@PathVariable("PageNum") Integer PageNum,
						@PathVariable("size") Integer size,
						@PathVariable("categoryId") Integer categoryId
		){
				Page<Goods> page = new Page<>(PageNum, size);

				// 创建查询条件对象
				QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("category_id", categoryId); // 根据categoryId进行条件查询

				Page<Goods> result = goodsMapper.selectPage(page, queryWrapper);
				return ResultDataDTO.success(result);
		}
}

四、主页的详情展示

image-20230608110347616

前端

<template>
    <div>
        <div style="margin-top: 20px; margin-left: 20px; font-size: 24px;">
            商品详情
        </div>
        <el-row style="margin-top: 20px;">
            <el-col :span="8">
                <img :src="goods.imageUrl" style="height: 350px; width: 350px; margin: 20px;">
            </el-col>
            <el-col :span="12" style="padding: 20px 20px 20px 40px;">
                <div style="margin-bottom: 20px; font-size: 28px; font-weight: bold;">{{ goods.name }}</div>
                <div style="font-size: 20px; color: #f60;">¥{{ goods.price }}</div>
                <div style="margin-top: 24px;">商品详情:{{ goods.description }}</div>
                <div style="margin-top: 24px;">销量:{{ goods.sale }}</div>
                <div style="margin-top: 24px;">库存:{{ goods.store }}</div>
                <div style="position: absolute; bottom: 20px; right: 40px;">
                    <el-button type="success" @click="buy">加入购物车</el-button>
                </div>
            </el-col>
        </el-row>
    </div>
</template>

<script>
import request from "@/utils/request";

export default {
  name: 'ShoppingDetail',
  data() {
    return {
      goods: null,
    }
  },
  methods: {
    buy() {
      const cart={
        id:this.goods.id,
        goods_id:this.goods.goods_id,
        image_url:this.goods.image_url,
        count:1,
        price:this.goods.price,
      };
      request.post("/cart/saveOrUpdate", cart)
          .then(resp => {
            if (resp.data.code === "200") {
              this.$message.success("加入购物车成功");
            } else {
              this.$message.error("加入购物车失败");
            }
          });
      },
  },
  created() {
    const _this = this;
    request.get(`/goods/findById/${this.$route.query.id}`).then(function(resp) {
      console.log(resp.data);
      _this.goods = resp.data.data;
      console.log(_this.goods);
    });
    const storedUser = localStorage.getItem('user');
    const user = JSON.parse(storedUser);
    this.username=user.username
  },
}
</script>

<style scoped>
</style>

加入后端

package com.example.cshand.controller;

import com.example.cshand.DTO.ResultDataDTO;
import com.example.cshand.entity.Cart;
import com.example.cshand.service.impl.CartServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author daetz
 * @creat 2023/6/8
 **/
@RestController
@RequestMapping("/cart")
public class CartController {


		@Autowired
		private CartServiceImpl cartService;

		/**
		 * 加入购物车
		 * @param cart
		 * @return
		 */
		@PostMapping("/saveOrUpdate")
		public ResultDataDTO SaveCart(@RequestBody Cart cart){
				boolean save = cartService.saveOrUpdate(cart);
				return ResultDataDTO.success(save);
		}
}

五、购物车的处理

image-20230608111241115

image-20230608114630590

image-20230608114621179

      request.post("/cart/saveOrUpdate", cart)
          .then(resp => {
            if (resp.data.code === "200") {
              this.$message.success("加入购物车成功");
            } else {
              this.$message.error("加入购物车失败");
            }
          });
      },
  },

image-20230608121136599

六、购物车结算

image-20230608150841286

image-20230608152058185

image-20230608152350656

结算事件

image-20230608175101987

		}

		@RequestMapping("/deleteById/{id}")
		public ResultDataDTO deleteById(@PathVariable Integer id){
				boolean result = cartService.removeById(id);
				return ResultDataDTO.success(result);
		}
}
    // 将订单数据发送到服务器
        request.post("/order/create", order)
            .then(resp => {
              if (resp.data.code === "200") {
                this.$message.success("订单创建成功");
                request.post("/cart/deleteById/"+order.goodsId)
                    .then(resp => {
                      if (resp.data.code === "200"){
                        this.$message.info("购物车清除成功");
                      }else{
                        this.$message.error("购物车清除失败");
                      }
                    });
              } else {
                this.$message.error("订单创建失败");
              }
            });
      }

七、订单展示

image-20230608153749896

image-20230608153809103

<template>
    <div>
        <el-table :data="orders" style="width: 100%">
            <el-table-column prop="id" label="订单ID"></el-table-column>
            <el-table-column prop="username" label="用户姓名"></el-table-column>
            <el-table-column prop="goodsName" label="商品名称"></el-table-column>
            <el-table-column prop="count" label="数量"></el-table-column>
            <el-table-column prop="price" label="单价"></el-table-column>
            <el-table-column prop="subtotal" label="小计"></el-table-column>
        </el-table>
        <el-pagination
                background
                layout="prev, pager, next"
                :page-size="10"
                :total="total"
                @current-change="page">
        </el-pagination>
    </div>
</template>

<script>
import request from "@/utils/request";

export default {
  name:'OrderShow',
  data() {
    return {
      total:null,
      goods:null,
      orders: [] // 存储订单数据
    };
  },
  methods: {
    page(currentPage){ //alert("wait...") 动态分页
      const _this=this
      request.get('/order/findAll/'+currentPage+'/10').then(function (resp){
        _this.orders=resp.data.data.records
        _this.total=resp.data.data.total
      })
    },
  },
  created() { //alert 初始化操作
    const _this=this
    request.get('/order/findAll/1/10').then(function (resp){
      console.log(resp.data)
      _this.orders=resp.data.data.records
      _this.total=resp.data.data.total
      _this.size=resp.data.data.size
    })
  },
}
</script>

<template>
    <div>
        <el-table :data="orders" style="width: 100%">
            <el-table-column prop="id" label="订单ID"></el-table-column>
            <el-table-column prop="username" label="用户姓名"></el-table-column>
            <el-table-column prop="goodsName" label="商品名称"></el-table-column>
            <el-table-column prop="count" label="数量"></el-table-column>
            <el-table-column prop="price" label="单价"></el-table-column>
            <el-table-column prop="subtotal" label="小计"></el-table-column>
        </el-table>
    </div>
</template>

<script>
import request from "@/utils/request";

export default {
  name:'OrderShow',
  data() {
    return {
      orders: [] // 存储订单数据
    };
  },
  mounted() {
    // 在组件加载完成后获取订单数据
    this.fetchOrders();
  },
  methods: {
    fetchOrders() {
      // 发起请求获取订单数据
      request.get('/order/findAll')
          .then(response => {
            console.log(response);
            console.log(response.data.data)
            // 请求成功,将订单数据赋值给 orders 数组
            this.orders = response.data.data;
          })
          .catch(error => {
            // 处理错误
            console.error(error);
          });
    }
  }
}
</script>

分页查询

image-20230608181800634

		@RequestMapping("/findAll/{PageNum}/{size}")
		public ResultDataDTO findAll(@PathVariable("PageNum") Integer PageNum, @PathVariable("size") Integer size){
				Page<Orders> page = new Page<>(PageNum, size);
				Page<Orders> result = ordersMapper.selectPage(page, null);
				return ResultDataDTO.success(result);
		}
}

image-20230608181842521

八、注册页面

image-20230608190828039

修复用户头像无法正常显示

image-20230608194636661

  methods: {
    handleSelect(key, keyPath) {
      console.log(key, keyPath);
    },
    logout() {
      // 调用 Vue Router 的 push 方法,将路径跳转到 '/login'
      router.push('/index/login')
      // 删除本地存储的用户信息
      localStorage.removeItem('user')
      // 显示退出成功的消息
      this.$message.success('退出成功')
    }
  },
  created() {
    const storedUser = localStorage.getItem('user');
    const user = JSON.parse(storedUser);
    this.username=user.username
    this.userImage=user.avatar
  },
}

九、旧物上传

image-20230608201743367

增加数据库

image-20230609153226354

image-20230611150555570

image-20230611151437336

image-20230611152357713

image-20230611152346719

image-20230611152457580

十、权限设置

路由守卫

import Vue from 'vue'
import VueRouter from 'vue-router'

import Index from "@/views/front/Index.vue";
import adminHome from "@/views/back/adminHome.vue";
import UserLogin from "@/views/front/UserLogin.vue";//用户登录页面
import Register from "@/views/front/UserRegister.vue";

import AddUserInformation from "@/views/back/AddUserInformation.vue";
import UserUpdate from "@/views/back/UserUpdate.vue";
import AdminLogin from "@/views/back/AdminLogin.vue";


//后台
import PageTwo from "@/views/back/PageTwo.vue";
import PageThree from "@/views/back/PageThree.vue";
import PageFour from "@/views/back/PageFour.vue";
import PageFive from "@/views/back/PageFive.vue";
import GoodsUpdate from "@/views/back/GoodsUpdate.vue";



/**
 * 主页
 */


//主页设计和详情展示
import ShoppingHome from "@/views/front/ShoppingHome.vue";
import ShoppingDetail from "@/views/front/ShoppingDetail.vue";
import UserInformation from "@/views/front/UserInformation.vue";
import ChangeInformation from "@/views/front/ChangeInformation.vue";

//后端信息
import AdminInformation from "@/views/back/AdminInformation.vue";
import AdminChangeInformation from "@/views/back/AdminChangeInformation.vue";
//aside

import digital1 from "@/views/Aside/digital1.vue"
import digital2 from "@/views/Aside/digital2.vue"
import digital3 from "@/views/Aside/digital3.vue"

import book1 from "@/views/Aside/book1.vue";
import book2 from "@/views/Aside/book2.vue";
import book3 from "@/views/Aside/book3.vue";

import food1 from  "@/views/Aside/food1.vue";
import food2 from  "@/views/Aside/food2.vue";
import food3 from  "@/views/Aside/food3.vue";

import CartShow from "@/views/front/CartShow.vue";
import OrderShow from "@/views/front/OrderShow.vue";
import GoodsUpload from "@/views/front/GoodsUpload.vue";

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect:'/index/home',
  },
  {
    path: '/index',
    name: '起始页',
    component: Index,
    children:[
      {
        path:'home',
        name:'商品购物主页',
        component: ShoppingHome,
      },
      {
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },
        name: '更新个人信息',
        component: ChangeInformation,
        path: 'change'
      },
      {
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },
        name:'个人信息',
        path: 'information',
        component: UserInformation,
      },
      {
        name:'商品详情展示',
        component: ShoppingDetail,
        path:'detail',
      },
      {
        path: 'login',
        name:'用户登录页面',
        component: UserLogin
      },
      {
        path: 'register',
        name:'用户注册页面',
        component: Register
      },
      {
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },
        name:'购物车结算',
        component: CartShow,
        path:'cart',
      },
      {
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },        name:'旧物上传',
        component: GoodsUpload,
        path: 'upload'
      },
      {
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },
        name:'订单中心',
        component: OrderShow,
        path: 'order'
      },
      {
        path:'digital1',
        name:'电脑',
        component: digital1,
      },
      {
        path:'digital2',
        name:'手机',
        component: digital2,
      },
      {
        path:'digital3',
        name:'平板',
        component: digital3,
      },
      {
        path:'food1',
        name:'面包',
        component: food1,
      },
      {
        path:'food2',
        name:'牛奶',
        component: food2,
      },
      {
        path:'food3',
        name:'饮料',
        component: food3,
      },
      {
        path:'book1',
        name:'教材',
        component: book1,
      },
      {
        path:'book2',
        name:'人文',
        component: book2,
      },
      {
        path:'book3',
        name:'艺术',
        component: book3,
      },

    ]
  },

  {
    path: '/admin',
    name: '管理员主页',
    component: adminHome,
    meta: {
      requiresAuth: true // 设置需要登录才能访问
    },
    children:[
      {
        path: 'information',
        name: '后台用户信息展示',
        component: AdminInformation,
      },
      {
        path: 'changeinfo',
        name: '后台更新用户信息',
        component: AdminChangeInformation,
      },
      {
        path:'pagetwo',
        name:'用户',
        component: PageTwo,
      },
      {
        path:'pagethree',
        name:'商品1',
        component: PageThree,
      },
      {
        path:'pagefour',
        name:'商品2',
        component: PageFour,
      },
      {
        path:'pagefive',
        name:'商品3',
        component: PageFive,
      },
      {
        path: 'addUser',
        name:'用户信息添加',
        component: AddUserInformation,
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        }
      },
      {
        path: 'update',
        name:'用户更新',
        component: UserUpdate,
        meta: {
          requiresAuth: true // 设置需要登录才能访问
        },
      },
      {
        name:'修改商品状态',
        path: 'change',
        component: GoodsUpdate,
      }
    ]
  },
  {
    path: '/adminLogin',
    name:'后台管理员登录',
    component: AdminLogin
  },

]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

// 路由守卫
router.beforeEach((to, from, next) => {
  // 判断当前路由是否需要登录才能访问
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 判断用户是否已经登录
    if (!localStorage.getItem('user')) {
      // 如果没有登录,给出提示
      Vue.prototype.$message.error('您还未登录,请先登录!')
      // 等待2秒后跳转
      setTimeout(() => {
        next('/index/home')
      }, 2000)
      return // 终止路由导航
    }
  }
  // 其他情况继续跳转
  next()
})


export default router

v-if自动渲染

image-20230614091612477

注意这里面不能使用 role===1来判断

如果你通过 JSON 解析或从服务器获取的数据中,role 的值是字符串类型的 '1',那么在比较时确实需要将条件判断中的值也使用字符串形式来进行比较,如 role === '1'

在进行 JSON 解析时,属性值的类型会被转换为相应的 JavaScript 数据类型。如果 role 在 JSON 数据中被定义为字符串类型的 '1',那么在解析后,role 将保持为字符串类型。这就解释了为什么在比较时需要使用字符串形式的 '1'

确保在解析 JSON 数据后,检查 role 的类型,并根据需要进行类型转换或使用适当的条件判断进行比较。

三、后台说明

点击开关调整商品状态

忘记增加数据持久化

image-20230611164056999

image-20230611164251148

image-20230611164302071

        <div class="demo-input-suffix">
            <el-input
                    placeholder="按照日期查找"
                    suffix-icon="el-icon-date"
                    v-model="input1"
                    style="width: 150px;float: left;margin:5px" >
            </el-input>
            <el-input
                    placeholder="按照姓名查找"
                    prefix-icon="el-icon-search"
                    v-model="input2"
                    style="width: 150px;float: left;margin:5px">
            </el-input>
            <el-button style="width: 70px;float: left;margin:5px" @click="search">查询</el-button>
            <el-button style="width: 70px;float: left;margin:5px" @click="resetForm">重置</el-button>
            <el-button style="width: 70px;float: left;margin:5px"  @click="addUser" type="primary" plain>新增</el-button>
            <el-button style="width: 140px;float: left;margin:5px" type="danger" plain>批量删除</el-button>
        </div>
        search(){
          const _this = this;
          request.get('/admin/findByName/'+_this.input2).then(function(resp) {
            console.log(resp)
            _this.tableData=resp.data
            _this.total=resp.data.length
          });
        },
        addUser(){
          this.$router.push('/addUser')
        },
        resetForm(){
            this.input1='';
            this.input2='';
        },
        deleteUser(row){
          const _this=this
          request.delete('/admin/delete/'+row.id).then(function (resp){
            //console.log(resp)
            alert("删除成功")
            window.location.reload();
          })
        },
        edit(row) {
          this.$router.push({
            path:'/update',
            query:{
              id:row.id
            }
          })
           //row.id<点击的id>
        },

image-20230611170031973

信息卡片

image-20230611173415911

image-20230611175438049

image-20230611180738619

image-20230611180754032

image-20230611182458237

image-20230611182506672

image-20230611183131315

image-20230611190645054

image-20230611191704762

image-20230611193947286

四、bug记录日志

1、使用utils设置config.js导致Token未能正常放入请求头

image-20230530182053448

检测发现是命名未统一,包含userusername

image-20230530182148835

仍然出错,忘记修改成request了

确保你在发送请求时使用了request对象来发起请求,而不是直接使用axios

请确保你使用了request对象发送请求,并且在发送请求时会自动应用拦截器中设置的请求头。如果你直接使用axios对象发送请求,那么拦截器中设置的请求头将不会生效。

image-20230530190125643

2、路由守卫失效

  • 忘记导入Vue

在代码中,导入Vue是为了使用Vue.prototype.$message.error,该语句用于在路由守卫中显示错误消息。

Vue.prototype.$message.error是使用Vue的原型属性$message来显示错误消息的方法。通过导入Vue,你可以在路由守卫中访问Vue实例,并使用$message.error方法来显示错误消息。

请注意,确保你的项目中已经安装并正确导入了Vue库。如果你的项目中没有使用Vue,或者没有安装Vue相关依赖,那么你可能不需要导入Vue。但在代码中使用了Vue.prototype.$message.error的情况下,需要确保Vue正确导入和配置。

import request from '@/utils/request'; // 导入自定义的request对象

export default {
    name: "PageTwo",
    methods:{
      search() {
          const _this = this;
          request.get('/admin/findByName/' + _this.input2).then(function(resp) {
            console.log(resp);
            _this.tableData = resp.data;
            _this.total = resp.data.length;
          });
        },
        addUser(){
          this.$router.push('/addUser')
        },
        resetForm(){
            this.input1='';
            this.input2='';
        },
        deleteUser(row){
          const _this=this
          request.post('/admin/delete/'+row.id).then(function (resp){
            //console.log(resp)
            alert("删除成功")
            window.location.reload();
          })
        },
        edit(row) {
          this.$router.push({
            path:'/update',
            query:{
              id:row.id
            }
          })
           //row.id<点击的id>
        },
        page(currentPage){ //alert("wait...") 动态分页
            const _this=this
            request.get('/findUser/'+currentPage+'/3').then(function (resp){
                _this.tableData=resp.data.records
                _this.total=resp.data.total
            })
        }
    },
  created() {
      const _this = this;
      request.get('/findUser/1/3').then(function(resp) {
        _this.tableData = resp.data.records;
        _this.total = resp.data.total;
        _this.size = resp.data.size;
        console.log(resp.data);
      });
    },
    data() {
        return {
            input1: '',
            input2: '',
            total:null,
            tableData:null,
            avatar:''
        }
    }
}

五、创新性实验

Vue中方法重写

如果在<view>标签中嵌套了另一个<view>标签,并且您想在内部的嵌套视图中使用created函数进行分页查询,您可以按照以下步骤进行操作。

在Vue组件中,可以通过在嵌套的<view>组件中定义created生命周期钩子来执行分页查询逻辑。

<template>
  <div>
    <!-- 外部view -->
    <view>
      <view>
        <!-- 内部view -->
        <!-- 其他代码 -->
      </view>
    </view>
  </div>
</template>

<script>
export default {
  components: {
    view: {
      created() {
        // 在内部view的created生命周期钩子中执行分页查询逻辑
        this.createdPagination();
      },
      methods: {
        createdPagination() {
          // 在这里编写使用created进行分页查询的代码逻辑
          // 可以调用API或执行其他必要的操作
        }
      }
    }
 

在Vue组件中,您可以在外部的<div>标签中定义一个方法,并在内部的嵌套视图中进行重写。这可以通过使用Vue的组件通信机制来实现。

在外部组件中,定义一个方法,并将其传递给内部视图组件作为属性。然后,内部视图组件可以通过监听属性的变化或使用自定义事件来触发重写的方法。

以下是一个示例代码:

html
<template>
  <div>
    <!-- 外部view -->
    <view :override-method="outerMethod">
      <!-- 内部view -->
      <!-- 其他代码 -->
    </view>
  </div>
</template>

<script>
export default {
  methods: {
    outerMethod() {
      // 在外部定义的方法
      console.log('Outer method');
    }
  },
  components: {
    view: {
      props: ['overrideMethod'],
      created() {
        // 在内部view的created生命周期钩子中执行重写的方法
        this.overrideMethod();
      },
      methods: {
        overrideMethod() {
          // 在内部重写的方法
          console.log('Override method');
        }
      }
    }
  }
};
</script>

在上述示例中,我们在外部组件中定义了一个名为outerMethod的方法。然后,我们通过将该方法作为属性传递给内部视图组件<view>,并使用:override-method="outerMethod"绑定。

在内部视图组件中,我们通过props接收外部传递的方法,并在created生命周期钩子中调用this.overrideMethod()来执行重写的方法。内部视图组件中的overrideMethod方法将覆盖外部视图组件中的同名方法。

当外部视图组件的方法被重写时,内部视图组件可以选择是否调用原始方法,或者完全替代原始方法的逻辑。

请根据您的具体需求调整示例代码,并在内部视图组件中实现适当的重写逻辑。

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

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

相关文章

在Maya、ZBrush和UE中制作龙香炉

大家好&#xff0c;今天云渲染小编给大家带来的分享是来自印尼的CG艺术家Stephen Herman“龙香炉”道具分解幕后花絮。 介绍 大家好&#xff01;我叫 Stephen Herman&#xff0c;是来自印度尼西亚雅加达的 3D 艺术家。 目前&#xff0c;我在 Bandai Namco Studios Malaysia …

数字电路基础---时序逻辑

时序逻辑 通过前面的组合逻辑的学习&#xff0c;我们知道了组合逻辑电路是没有记忆功能的&#xff0c;也就是说在任何时刻产生的输出信号都仅仅取决于该时刻电路的输入信号&#xff0c;而与它以前的输入信号是无关的。下来我们来学习下什么是时序逻辑。 1、简介 时序电路是有…

C语言实现顺序表

绪论 从本章开始就是开始数据结构的开端&#xff0c;本章将会写出数据结构中的顺序表的代码实现&#xff0c;多会以注释的方法来描述一些细节&#xff08;注释是我们程序员必须常用的工具&#xff09;。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xf…

分析:如何多线程运行测试用例

这是时常被问到的问题&#xff0c;尤其是UI自动化的运行&#xff0c;过程非常耗时&#xff0c;所以&#xff0c;所以多线程不失为一种首先想到的解决方案。 多线程是针对的测试用例&#xff0c;所以和selenium没有直接关系&#xff0c;我们要关心的是单元测试框架。 unittest …

生态伙伴 | 华秋硬创联合湾加速,共同加速企业发展

01 大赛介绍 中国硬件创新创客大赛始于2015年&#xff0c;由深圳华秋电子有限公司主办&#xff0c;至今已经成功举办八届&#xff0c;赛事范围覆盖华南、华东、华北三大地区&#xff0c;超10个省市区域。 大赛影响了超过45万工程师群体&#xff0c;吸引了35000多名硬创先锋报…

云可观测性技术的应用领域及价值有哪些?

随着云计算的迅速发展&#xff0c;云可观测性技术成为了越来越重要的一项技术。它可以帮助企业实时监测、分析和优化其在云环境中运行的应用程序和系统&#xff0c;那云可观测性技术的应用领域及价值有哪些&#xff1f; 一、应用性能监测与优化 云可观测性技术使得企业能够实时…

(字符串) 844. 比较含退格的字符串——【Leetcode每日一题】

❓844. 比较含退格的字符串 难度&#xff1a;简单 给定 s 和 t 两个字符串&#xff0c;当它们分别被输入到空白的文本编辑器后&#xff0c;如果两者相等&#xff0c;返回 true 。# 代表退格字符。 注意&#xff1a;如果对空文本输入退格字符&#xff0c;文本继续为空。 示例…

【SpringBoot】整合Elasticsearch 快速入门操作索引

官网操作文档&#xff1a;Elasticsearch Clients | Elastic 踩坑太多了。。。这里表明一下Spring Boot2.4以上版本可能会出现问题&#xff0c;所以我降到了2.2.1.RELEASE。对于现在2023年6月而言&#xff0c;Es版本已经到了8.8&#xff0c;而SpringBoot版本已经到了3.x版…

【实战】Python爬虫之代理使用详解

在Python爬虫中&#xff0c;代理的使用非常常见。代理的主要作用是隐藏客户端的真实IP地址&#xff0c;从而实现更高的网络访问速度和更好的访问隐私保护。下面我们将通过Python爬虫的实例&#xff0c;带你详细了解Python爬虫中代理的使用方法。 目录 ## 1. 代理原理和作用 …

多维度员工信息整合查询——红海云员工信息数字化管理实用指南(中)

红海云员工全生命周期数字化管理平台从信息源头开始管控员工数据质量&#xff0c;在员工数据的采集、更新、审核环节采用多种方式保障员工信息的准确性、完整性、时效性和一致性&#xff0c;为企业搭建坚实可靠的人力资源管理数字化基座。但在有了准确可靠的员工数据基础后&…

APP测试应该从哪些方面入手?其实就这几点

前言 还在苦恼怎么去测APP吗&#xff1f; 一定要记住这几个方向&#xff0c;然后流程化的去执行&#xff0c;一来严谨规范&#xff0c;二来不会有遗漏。 1、需求检查&#xff1a; 在需求评审的时候展现你的业务能力啦&#xff01;不过还是得口下留情哟。&#xff08;PM心里瑟…

GitOps指南

GitOps基于CICD和IaC&#xff0c;以一致的方式管理代码和部署&#xff0c;是DevOps最佳实践之一。本文完整介绍了GitOps的理念和实践&#xff0c;并介绍了Weave Cloud的GitOps模型和工具&#xff0c;从整体上提供了实践GitOps的路径和方案。原文&#xff1a;Guide To GitOps[1]…

C++中的一些小技巧,numeric_limits、static_cast、reinterpret_cast方法内存验证

1、获取指定类型的最大值和最小值 在准备求一堆double数据中的最大值最小值的时候&#xff0c;常规做法是预估这堆数据的最大最小值&#xff0c;然后进行比较求&#xff0c;在重构别人代码的时候发现&#xff0c;可以准确知道double类型最大值或者最小值&#xff0c;获取方法如…

Apikit 自学日记:分享 API 文档

开启/关闭在线分享 您可以在线分享项目给团队以外的人&#xff0c;其他人可以通过分享链接在线查看API文档并且进行API测试。通过这种方式查看API文档不需要注册账号&#xff0c;用户可方便查看接口文档和测试接口。 在项目内&#xff0c;点击进入项目管理菜单&#xff0c;选择…

银河麒麟部署达梦8数据库开发者版本详细教程

我的系统信息如下&#xff1a; 系统架构&#xff1a;X86架构 系统信息&#xff1a;银河麒麟&#xff08;V10&#xff09; CPU&#xff1a;interl E5 官方安装文档&#xff1a;安装及卸载 | 达梦技术文档 (dameng.com) 数据库下载&#xff1a; 下载地址&#xff1a;产品下载…

【深度学习】2-5 神经网络-批处理

批处理&#xff08;Batch Processing&#xff09;是指在深度学习中每次迭代更新模型参数时同时处理多个样本的方式。 批处理时要注意对应维度的元素个数要一致 关于之前手写数字识别的例子&#xff1a; 用图表示&#xff0c;可以发现&#xff0c;多维数组的对应维度的元素个数…

体验DIY物联网浏览器(谷歌内核兼容性好支持H264视频播放)

一、功能及快捷键说明(说明32位兼容64位,版本往下看) 功能及快捷键图说明,不可多得的浏览器,支持右键自定义菜单... 二、下载安装包 2.1 版本 100.0.230 (支持H264版本)介绍 cefsharp物联网浏览器-支持H264(100.0.230)_cefsharp h264_久爱物联网的博客-CSDN博客 …

《论文阅读》用于情感分析的融合预训练表情符号特征增强

《论文阅读》用于情感分析的融合预训练表情符号特征增强 前言简介模型构架实验结果总结前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后感到失望? 小白如何从零读懂论文?和我一起来探索吧! 今天为大家带来的是《Fusion Pr…

SonarScanner扫描本地项目代码

一、Windows系统扫描 下载SonarScanner 去SonarQube官网下载相应系统的SonarScanner 点这里跳转 设置环境变量 下载好试个压缩文件&#xff0c;解压到你想存放的位置&#xff0c;设置环境变量 新增变量名&#xff1a;SONAR_SCANNER_HOME&#xff0c;值&#xff1a;你解压Sona…

ansible知识

在物理机查看环境&#xff0c;[kioskfoundation0 ~]$ cat /etc/rht 先清空当前环境&#xff0c;[kioskfoundation0 ~]$ rht-clearcourse 0 再切换rh294环境&#xff0c;[kioskfoundation0 ~]$ rht-setcourse rh294 验证环境是否切换成功&#xff0c;[kioskfoundation0 ~]$ cat…