SpringBoot2+Vue2实战(四)进行组件内容拆分及路由实现

news2024/11/25 20:40:04

一、拆分

新建包:

Aside和Header都是组件

User为视图

 Aside.vue:

<template>
  <el-menu :default-openeds="['1', '3']" style="min-height: 100%; overflow-x: hidden"
           background-color="rgb(48, 65, 86)"
           text-color="#fff"
           active-text-color="#ffd04b"
           :collapse-transition="false"
           :collapse="isCollapse"
           
  >
    <div style="height: 60px; line-height: 60px; text-align: center">
      <img src="../assets/logo.png" alt="" style="width: 20px; position: relative; top: 5px; right: 5px">
      <b style="color: white" v-show="logoTextShow">后台管理系统</b>
    </div>
    <el-menu-item index="/">
      <template slot="title">
        <i class="el-icon-s-home"></i>
        <span slot="title">主页</span>
      </template>
    </el-menu-item>

    <el-submenu index="2">
      <template slot="title">
        <i class="el-icon-menu"></i>
        <span slot="title">系统管理</span>
      </template>
        <el-menu-item index="/user">
          <template slot="title">
            <i class="el-icon-user"></i>
            <span slot="title">用户管理</span>
          </template>
        </el-menu-item>
    </el-submenu>
  </el-menu>
</template>

<script>
export default {
  name: "Aside",


//根据数据类型定义变量
  props:{
    isCollapse:Boolean,
    logoTextShow:Boolean
  },
  
}
</script>

<style scoped>

</style>

Head.vue

<template>
  <div style="font-size: 12px;line-height: 60px; display: flex">
    <div style="flex: 1;">
      <span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>

      <el-breadcrumb separator="/" style="display: inline-block;margin-left: 10px" >
        <el-breadcrumb-item :to="item.paths" :key v-for="item in paths">{{ item.name }}</el-breadcrumb-item>
      </el-breadcrumb>

    </div>
    <el-dropdown style="width: 70px; cursor: pointer">
      <span>王小虎</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
      <el-dropdown-menu slot="dropdown">
        <el-dropdown-item style="font-size: 14px; padding: 5px 0">个人信息</el-dropdown-item>
        <el-dropdown-item style="font-size: 14px; padding: 5px 0">退出</el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
export default {
  name: "Header",
  props:{
    collapseBtnClass: String,
    collapse:Function
  },
  data(){
    return{
      paths:[]
    }
  },
}
</script>

<style scoped>

</style>

User.vue

拆出页面布局及方法

<template>
<div>

  <div style="margin: 10px 0">
    <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
              v-model="username"></el-input>
    <el-input style="width: 200px" placeholder="请输入邮箱" suffix-icon="el-icon-message"
              v-model="email" class="ml-5"></el-input>
    <el-input style="width: 200px" placeholder="请输入地址" suffix-icon="el-icon-position"
              v-model="address" class="ml-5"></el-input>
    <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
    <el-button class="ml-5" type="warning" @click="reset">重置</el-button>
  </div>

  <div style="margin: 10px 0">
    <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
    <el-popconfirm
        class="ml-5"
        confirm-button-text='确定'
        cancel-button-text='我再想想'
        icon="el-icon-info"
        icon-color="red"
        title="这是一段内容确定删除吗?"
        @confirm="delBatch"
    >
      <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
    </el-popconfirm>
    <el-button type="primary" class="ml-5">导入 <i class="el-icon-bottom"></i></el-button>
    <el-button type="primary">导出 <i class="el-icon-top"></i></el-button>
  </div>

  <el-table :data="tableData" border stripe :header-cell-class-name="headerBg"
            @selection-change="handleSelectionChange">
    <el-table-column
        type="selection"
        width="55">
    </el-table-column>
    <el-table-column prop="id" label="ID" width="80"></el-table-column>
    <el-table-column prop="username" label="用户名" width="140"></el-table-column>
    <el-table-column prop="nickname" label="昵称" width="120"></el-table-column>
    <el-table-column prop="email" label="邮箱"></el-table-column>
    <el-table-column prop="phone" label="电话"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
    <el-table-column label="操作" width="200" align="center">
      <template slot-scope="scope">
        <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
        <el-popconfirm
            confirm-button-text='确定'
            cancel-button-text='我再想想'
            icon="el-icon-info"
            icon-color="red"
            title="这是一段内容确定删除吗?"
            @confirm="del(scope.row.id)"
        >

          <el-button type="danger" slot="reference" class="ml-5">删除 <i class="el-icon-remove-outline"></i>
          </el-button>
        </el-popconfirm>
      </template>
    </el-table-column>
  </el-table>
  <div style="padding: 10px 0">
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageNum"
        :page-sizes="[2, 5, 10, 20]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
    </el-pagination>
  </div>

  <!--新增表单-->
  <el-dialog title="用户信息" :visible.sync="dialogFormVisible" width="30%">
    <el-form label-width="80px" size="small">
      <el-form-item label="用户名">
        <el-input v-model="form.username" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="昵称">
        <el-input v-model="form.nickname" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="邮箱">
        <el-input v-model="form.email" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="电话">
        <el-input v-model="form.phone" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="地址">
        <el-input v-model="form.address" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false">取 消</el-button>
      <el-button type="primary" @click="save">确 定</el-button>
    </div>
  </el-dialog>
</div>
</template>

<script>
export default {
  name: "User",
  data(){
    return {
      dialogFormVisible: false,
      multipleSelection: [],
      tableData: [],
      total: 0,
      pageNum: 1,
      pageSize: 2,
      form: {},
      username: "",
      email: "",
      address: "",
      headerBg: 'headerBg'
    }
  },
  created() {
    this.load()
  },
  methods:{
    load() {
      this.request.get("/user/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          username: this.username,
          address: this.address,
          email: this.email
        }
      }).then(res => {
        console.log(res)
        this.tableData = res.records
        this.total = res.total
      })

    },
    reset() {
      this.username = ""
      this.email = ""
      this.address = ""
    },

    //新增方法
    handleAdd() {
      this.dialogFormVisible = true
      this.form = {}
    },
    save() {
      this.request.post("/user/saveUser", this.form).then(res => {
        if (res) {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
          this.dialogFormVisible = false
        }
      })
    },

    /*编辑方法*/
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },

    //删除方法
    del(id) {
      this.request.delete("/user/" + id).then(res => {
        if (res) {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },
    //批量删除
    delBatch() {
      //把对象的数组变成纯id数组
      let ids = this.multipleSelection.map(v => v.id)
      this.request.post("/user/del/batch", ids).then(res => {
        if (res) {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },

    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },

    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    }
  }
}
</script>

<style>
.headerBg {
  background: #eee !important;
}
</style>

Manage.vue

调用拆分的视图及组件

视图:使用router-view调用

组件:导入组件包:

//导入
import Aside from "@/components/Aside.vue";
import Header from "@/components/Header.vue";

创建组件包含内容

//调用组件
  components: {
    Aside,
    Header,
  },

调用组件:

<el-aside :width="sideWidth + 'px'" style="box-shadow: 2px 0 6px rgb(0 21 41 / 35%);">
      <Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow"/>
    </el-aside>



<el-container>
      <el-header style=" border-bottom: 1px solid #ccc;">
        <Header :collapseBtnClass="collapseBtnClass" :collapse="collapse"/>
      </el-header>

      <el-main>
        <!--表示当前页面的子路由会在router-view展示-->
        <router-view/>
      </el-main>

    </el-container>
<template>
  <el-container style="min-height: 100vh">

    <el-aside :width="sideWidth + 'px'" style="box-shadow: 2px 0 6px rgb(0 21 41 / 35%);">
      <Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow"/>
    </el-aside>

    <el-container>
      <el-header style=" border-bottom: 1px solid #ccc;">
        <Header :collapseBtnClass="collapseBtnClass" :collapse="collapse"/>
      </el-header>

      <el-main>
        <!--表示当前页面的子路由会在router-view展示-->
        <router-view/>
      </el-main>

    </el-container>
  </el-container>
</template>

<script>
//导入
import Aside from "@/components/Aside.vue";
import Header from "@/components/Header.vue";

export default {
  name: 'Home',
  data() {
    return {
      collapseBtnClass: 'el-icon-s-fold',
      isCollapse: false,
      sideWidth: 200,
      logoTextShow: true,
    }
  },

//调用组件
  components: {
    Aside,
    Header,
  },

  methods: {
    collapse() {  // 点击收缩按钮触发
      this.isCollapse = !this.isCollapse
      this.logoTextShow = !this.logoTextShow
      if (this.isCollapse) {  // 收缩
        this.sideWidth = 64
        this.collapseBtnClass = 'el-icon-s-unfold'
        this.logoTextShow = false
      } else {   // 展开
        this.sideWidth = 200
        this.collapseBtnClass = 'el-icon-s-fold'
        this.logoTextShow = true
      }
    },

  }
}
</script>

<style>
</style>

router/index.js

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

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: () => import('../views/Manage.vue'),
    redirect:"/home",
    children:[
      {path: 'user', name: '用户管理', component: () => import('../views/User.vue'),},
      {path: 'home', name: '首页', component: () => import('../views/Home.vue'),}

    ]
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/AboutView.vue')
  }
]

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

export default router

Vue路由使用:

Aside:

<template>
  <el-menu :default-openeds="['1', '3']" style="min-height: 100%; overflow-x: hidden"
           background-color="rgb(48, 65, 86)"
           text-color="#fff"
           active-text-color="#ffd04b"
           :collapse-transition="false"
           :collapse="isCollapse"
//添加就能跳转
           router
  >
    <div style="height: 60px; line-height: 60px; text-align: center">
      <img src="../assets/logo.png" alt="" style="width: 20px; position: relative; top: 5px; right: 5px">
      <b style="color: white" v-show="logoTextShow">后台管理系统</b>
    </div>
    <el-menu-item index="/home">
      <template slot="title">
        <i class="el-icon-house"></i>
        <span slot="title">主页</span>
      </template>
    </el-menu-item>
    <el-submenu index="2">
      <template slot="title">
        <i class="el-icon-menu"></i>
        <span slot="title">系统管理</span>
      </template>
      <el-menu-item index="/user">
        <i class="el-icon-s-custom"></i>
        <span slot="title">用户管理</span>
      </el-menu-item>
    </el-submenu>
  </el-menu>
</template>

<script>
export default {
  name: "Aside",
  props: {
    isCollapse: Boolean,
    logoTextShow: Boolean
  }
}
</script>

<style scoped>

</style>

router/index.js

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

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: () => import('../views/Manage.vue'),
    redirect:"/home",
    children:[
      {path: 'user', name: '用户管理', component: () => import('../views/User.vue'),},
      {path: 'home', name: '首页', component: () => import('../views/Home.vue'),}

    ]
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/AboutView.vue')
  }
]

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

/*// 路由守卫
router.beforeEach((to, from, next) => {
  localStorage.setItem("currentPathName", to.name)  // 设置当前的路由名称,为了在Header组件中去使用
  store.commit("setPath")  // 触发store的数据更新
  next()  // 放行路由
})*/

export default router

Head.vue

<template>
  <div style="line-height: 60px; display: flex">
    <div style="flex: 1;">
      <span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>

      <el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px">
        <el-breadcrumb-item v-if="this.$route.name !== '主页'">{{ this.$route.name }}</el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <el-dropdown style="width: 70px; cursor: pointer">
      <span>王小虎</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
      <el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
        <el-dropdown-item style="font-size: 14px; padding: 5px 0">个人信息</el-dropdown-item>
        <el-dropdown-item style="font-size: 14px; padding: 5px 0">退出</el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
export default {
  name: "Header",
  props: {
    collapseBtnClass: String,
    collapse: Function,
  },
  /*computed: {
    currentPathName () {
      return this.$store.state.currentPathName;  //需要监听的数据
    }
  }*/
}
</script>

<style scoped>

</style>

Vuex下载

npm i vuex -S

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        currentPathName: ''
    },
    mutations: {
        setPath (state) {
            state.currentPathName = localStorage.getItem("currentPathName")
        }
    }
})

export default store

main.js

import store from './store'


new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

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

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

相关文章

I2C总线协议详解

I2C总线物理拓扑结构 I2C总线物理拓扑图 I2C 总线在物理连接上非常简单&#xff0c;分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制&#xff0c;来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时&#…

linux下使用pyqt5的QMediaPlayer制作简易播放器(存在进度条、前进、后退、暂停、打开、播放等操作)

目录 1. 问题2. 解决3. 效果 1. 问题 关于pyqt5的qmediaplayer模块制作简易播放器&#xff0c;网上很多博客都是win下的&#xff0c;放在linux系统会出问题&#xff1b;另外&#xff0c;部分博客缺少文件&#xff0c;无法直接使用。 参考博客《基于pyqt5的QMediaPlayer实现视…

android studio git使用

pull代码 我们从远程仓库拉取代码时&#xff0c;一般有下面的两个选项 当使用Android Studio拉取代码时&#xff0c;有两种常见的选项&#xff1a;合并&#xff08;merge&#xff09;传入的更改到当前分支和变基&#xff08;rebase&#xff09;。 合并&#xff08;Merge&…

【Django学习】(九)自定义校验器_单字段_多字段校验_模型序列化器类

之前学习了视图集里运用序列化器进行序列化和反序列化操作&#xff0c;定义序列化器类&#xff0c;需要继承Serializer基类或者Serializer的子类&#xff1b; 这次我们将学习如何自定义校验器、如何进行单字段或者多字段校验&#xff0c;最后初步使用模型序列化器 一、自定义…

OPPO手机无网络可支持3km通信,对讲机将被淘汰?

OPPO在2019世界移动通信大会即MWC上海发布了一项新技术&#xff0c;被称为“无网络通信技术”&#xff08;MeshTalk&#xff09;。这是OPPO自主研发的一项去中心化通讯技术&#xff0c;能够在没有蜂窝网络、Wi-Fi、蓝牙的情况下&#xff0c;实现3km内通讯。 无网通信技术 不过…

Java教程-Java异常抛出

在Java中&#xff0c;异常允许我们编写高质量的代码&#xff0c;可以在编译时检查错误而不是在运行时&#xff0c;并且我们可以创建自定义异常&#xff0c;使代码的恢复和调试更加容易。 Java的throw关键字 Java的throw关键字用于显式地抛出异常。 我们指定要抛出的异常对象。异…

华为breeze ideploy部署流程示例

https://www.cnblogs.com/withfeel/p/11640877.html 华为breeze ideploy部署流程示例

Canal对MySQL进行数据迁移

Canal简单介绍 贴个官方网址&#xff1a;阿里巴巴MySQL binlog 增量订阅&消费组件 架构图&#xff1a; 基于日志增量订阅和消费的业务包括 数据库镜像数据库实时备份索引构建和实时维护(拆分异构索引、倒排索引等)业务 cache 刷新带业务逻辑的增量数据处理 当前的 cana…

CSS知识点汇总(十一)--回流重绘

文章目录 怎么理解回流跟重绘&#xff1f;什么场景下会触发&#xff1f;1、回流和重绘是什么&#xff1f;2、如何触发回流和重绘3、如何避免回流和重绘的发生 怎么理解回流跟重绘&#xff1f;什么场景下会触发&#xff1f; 1、回流和重绘是什么&#xff1f; 在HTML中&#xf…

二十、socket套接字编程(二)——TCP

文章目录 一、TCP套接字接口&#xff08;一&#xff09;inet_aton &#xff08;和inet_addr一样&#xff0c;换一种方式而已&#xff09;&#xff08;二&#xff09;socket()&#xff08;三&#xff09;bind()&#xff08;四&#xff09;listen()&#xff08;五&#xff09;acc…

ASP.NET Core MVC -- 入门

先决条件&#xff08;开发配置二选一&#xff09;&#xff1a; 带有 ASP.NET 和 Web 开发工作负载的Visual Studio Visual Studio Code Visual Studio Code用于 Visual Studio Code 的 C#&#xff08;最新版本&#xff09;.NET 7.0 SDK 创建Web应用 visual studio ctrl F5 …

云原生之深入解析Kubernetes网络流量的流转路径

一、Kubernetes 网络要求 Kubernetes 网络模型定义了一组基本规则&#xff1a; 在不使用网络地址转换 (NAT) 的情况下&#xff0c;集群中的 Pod 能够与任意其他 Pod 进行通信&#xff1b; 在不使用网络地址转换 (NAT) 的情况下&#xff0c;在集群节点上运行的程序能与同一节点…

王道《计算机网络》思维导图汇总

第一章 1.1.1 概念与功能 1.1.2 组成与分类 1.1.3 标准化工作及相关组织 1.1.4 性能指标 速率 带宽 吞吐量 时延 时延带宽积 往返时延RTT 利用率 1.2.1 分层结构、协议、接口、服务 1.2.2 OSI参考模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 1.2.4 TCP/IP 参…

内核角度看IO模型

聊聊Netty那些事儿之从内核角度看IO模型 网络包接收流程 当网络数据帧通过网络传输到达网卡时&#xff0c;网卡会将网络数据帧通过DMA的方式放到环形缓冲区RingBuffer中。RingBuffer是网卡在启动的时候分配和初始化的环形缓冲队列。当RingBuffer满的时候&#xff0c;新来的数据…

【AUTOSAR】BMS开发实际项目讲解(十三)----电池管理系统碰撞安全功能和SFR

SG-BMS-7 : BMS系统应避免碰撞保护功能异常引起的安全事故&#xff08;ASIL A&#xff09; 功能框图&#xff08;SG-BMS-7&#xff09; 功能组件说明 功能组件ID 功能组件名称 描述 ASIL等级 FSC-FC-05 Relay Drive 驱动继电器开启和关断 ASIL A FSC-FC-11 Detection …

【vue】可选链运算符(?.)和空值合并运算符(??):

文章目录 一、问题一:二、问题二:三、使用:【1】空值合并运算符&#xff08;??&#xff09;【2】可选链运算符&#xff08;?.&#xff09; 一、问题一: http://www.codebaoku.com/question/question-sd-1010000042870944.html //1、npm安装 npm install babel/plugin-propo…

批量修改文件命名的shell脚本

Android 制作开机动画的方法参考&#xff1a;linux开机动画制作教程 其中往往会把里面的png图片命名位XX_0001.png , 002.png……等 Window批量修改文件名时会带有空格和括号。 这里写了一个脚本&#xff0c;可以在批量修改文件名后&#xff0c;将文件名转换为XX_00001 格式&…

基于matlab使用 YOLO V2深度学习进行多类对象检测(附源码)

一、前言 此示例演示如何训练多类对象检测器。 深度学习是一种强大的机器学习技术&#xff0c;可用于训练强大的多类对象检测器&#xff0c;例如 YOLO v2、YOLO v4、SSD 和 Faster R-CNN。此示例使用该函数训练 YOLO v2 多类室内对象检测器。经过训练的物体检测器能够检测和识…

ModaHub魔搭社区:Milvus 监控指标和使用 Grafana 展示 Milvus 监控指标

目录 Milvus 监控指标 Milvus 性能指标 系统运行指标 硬件存储指标 Milvus 监控指标 Milvus 会生成关于系统运行状态的详细时序 metrics。你可以通过 Prometheus、Grafana 或任何可视化工具展现以下指标&#xff1a; Milvus 性能指标系统运行指标&#xff1a;CPU/GPU 使用…

单片机学习 11-中断系统(定时器中断+外部中断)

中断系统 中断介绍 ​ 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的&#xff0c;中断功能的存在&#xff0c;很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功能之一&#xff0c;是我们学习单片机必须要掌握的。很多初学者被困在…