JIANGzihao0222

导航

 

    假期最后一周的随笔了,马上开学,这个假期也马上完了。真是快呀,学了一些东西,学了一些hadooop的相关知识,也学了一些前端的知识,写了一个登录,真删改查的模板,

    然后之前跟着视频做了一个前端的页面,也做了写笔记。

Vue通用后台模板

一:创建vue项目:再路径上替换为cmd,后进行输入

vue create `项目名`

二: 启动脚手架

npm run serve

三:element-ui

安装 element-ui

npm i element-ui -S

引入 element-ui

完整引入

main.js 中写入以下内容:

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

四:路由 vue-router

安装 vue-router(vue2)

npm install vue-router@3

新建router文件,建立index.js

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
import Vue from "vue";
import VueRouter from "vue-router";
// 1. 定义 (路由) 组件。
import HomePage from "@/views/HomePage";
import UserPage from "@/views/UserPage";
//使用Vueroute组件
Vue.use(VueRouter)
// 2. 定义路由

// 每个路由应该映射一个组件。 其中"component" 可以是
const routes = [
    { path: '/home', component: HomePage },
    { path: '/user', component: UserPage }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
    routes // (缩写) 相当于 routes: routes
})

//进行外界暴露
export default router
// 现在,应用已经启动了!

建立页面组件的集合包 views

进行main.js的引入定义

import Vue from 'vue'
import App from './App.vue'
//element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//引入router
import router from "@/router";
//生产模式
Vue.config.productionTip = false

//使用 element-ui 插件
Vue.use(ElementUI);

new Vue({
  render: h => h(App),
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    router
}).$mount('#app')

为了保持风格统一:在vue.config.js 中关闭eslint校验,加入

lintOnSave:false

App.vue中进行渲染路由

<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>

五:嵌套路由

创建主路由:MainPage,在router.index,js上进行定义main的子路由

const routes = [
    {
        path: '/',
        component: MainPage,
        children:[
            { path: 'home',
              component: HomePage
            },
            { path: 'user',
              component: UserPage
            }
        ]
    },

此时,App.vue上的路由展示的为MainPage,需在MainPage.vue内定义路由出口

MainPage.vue

<template>
  <div>
    <h1>MainPage</h1>
    <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "MainPage"
}
</script>

<style scoped>

</style>

六:布局搭建(element-ui)

选取中意的布局,进行粘贴

<el-container>
  <el-aside width="200px">Aside</el-aside>
  <el-container>
    <el-header>Header</el-header>
    <el-main>Main</el-main>
  </el-container>
</el-container>

七:左侧菜单搭建

选择中意的菜单模板:在创建的AsideMenu组件中进行粘贴

<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
  <el-submenu index="1">
    <template slot="title">
      <i class="el-icon-location"></i>
      <span slot="title">导航一</span>
    </template>
    <el-menu-item-group>
      <span slot="title">分组一</span>
      <el-menu-item index="1-1">选项1</el-menu-item>
      <el-menu-item index="1-2">选项2</el-menu-item>
    </el-menu-item-group>
    <el-menu-item-group title="分组2">
      <el-menu-item index="1-3">选项3</el-menu-item>
    </el-menu-item-group>
    <el-submenu index="1-4">
      <span slot="title">选项4</span>
      <el-menu-item index="1-4-1">选项1</el-menu-item>
    </el-submenu>
  </el-submenu>
  <el-menu-item index="2">
    <i class="el-icon-menu"></i>
    <span slot="title">导航二</span>
  </el-menu-item>
  <el-menu-item index="3" disabled>
    <i class="el-icon-document"></i>
    <span slot="title">导航三</span>
  </el-menu-item>
  <el-menu-item index="4">
    <i class="el-icon-setting"></i>
    <span slot="title">导航四</span>
  </el-menu-item>
</el-menu>
<style>
  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
  }
</style>

<script>
  export default {
    data() {
      return {
        isCollapse: true
      };
    },
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath);
      }
    }
  }
</script>

后进行一二级菜单调整

调整为一级菜单在上,有二级菜单在下,二级菜单有有一个子菜单

<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
    <el-menu-item index="2">
      <i class="el-icon-menu"></i>
      <span slot="title">导航二</span>
    </el-menu-item>
    <el-submenu index="1">
      <template slot="title">
        <i class="el-icon-location"></i>
        <span slot="title">导航一</span>
      </template>
      <el-menu-item-group>
        <el-menu-item index="1-1">选项1</el-menu-item>
      </el-menu-item-group>
    </el-submenu>
  </el-menu>

进行菜单栏的数据定义:包含:path,name,label,icon,url。

进行页面的实现:

1、定义计算属性,来区别有子菜单和无菜单的进行渲染

computed:{
    //没有子菜单
    noChildren()
    {
      return this.menuData.filter(item => !item.children)
    },
    //拥有子菜单
    haveChildren()
    {
      return this.menuData.filter(item => item.children)
    },
  },

2、进行利用v-for进行渲染

<!--无子菜单  -->
<el-menu-item v-for="item in noChildren" :key="item.name" :index="item.name">
      <i :class="`el-icon-${item.icon}`"></i>
<!--Es6进行字符串拼接-->
      <span slot="title">{{item.label}}</span>
    </el-menu-item>
<el-submenu v-for="item in haveChildren" :key="item.label" :index="item.label">
      <template slot="title">
        <i :class="`el-icon-${item.icon}`"></i>
        <span slot="title">{{item.label}}</span>
      </template>
      <el-menu-item-group v-for="subItem in item.children" :key="subItem.name">
        <el-menu-item :index="subItem.name">{{ subItem.label }}</el-menu-item>
      </el-menu-item-group>
    </el-submenu>

进行左侧菜单栏颜色渲染

      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"

左侧菜单栏高度设定

height:100vh

less的引入

引入

less下载
npm i less@4.1.2
less-loader下载
npm i less-loader@6

使用

<style lang="less">
  html,body{
    margin: 0;
    padding: 0;
  }
</style>

接上对菜单栏页面的修改

对于一些小细节进行修改

对于默认样式进行修改,在App.vue中添加:

<style lang="less">
  html,body,h3{
    margin: 0;
    padding: 0;
  }
</style>

对菜单栏的一些小细节

.el-menu{
    height: 100vh;
    h3{
      color: white;
      text-align: center;
      line-height: 48px;
      font-size: 16px;
      font-width: 400;;
    }
  }

八:点击实现路由跳转

首先,对于跳转的页面进行注册,否者跳转后无法找到页面以致报错

跳转后为界面,在view里定义ManagerPage,PageOne,PageTwo组件

而后进行路由注册:

const routes = [
    {
        path: '/',
        component: MainPage,
        children:[
            {
                path: 'home',
                component: HomePage
            },
            {
                path: 'user',
                component: UserPage
            },
            {
                path: 'manager',
                component: ManagerPage
            },
            {
                path: 'page1',
                component: PageOne
            },
            {
                path: 'page2',
                component: PageTwo
            }
        ]
    },

]

要求与menuData里path属性一致。

绑定点击事件

<h3>通用后台管理</h3>
<el-menu-item v-for="item in noChildren" @click="clickMenu(item)" :key="item.name" :index="item.name">
<i :class="`el-icon-${item.icon}`"></i>
<span slot="title">{{item.label}}</span>
</el-menu-item>
<el-submenu v-for="item in haveChildren" :key="item.label" :index="item.label">
<template slot="title">
<i :class="`el-icon-${item.icon}`"></i>
<span slot="title">{{item.label}}</span>
</template>
<el-menu-item-group  v-for="subItem in item.children" :key="subItem.name">
<el-menu-item @click="clickMenu(subItem)" :index="subItem.name">{{ subItem.label }}</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>

进行点击后跳转,定义点击方法

   //点击菜单
    clickMenu(item){
      // console.log(item)
      // 进行跳转
      this.$router.push(item.path)
    }

'/'重定向到'/home',在router.index.js中进行

path: '/',
        component: MainPage,
        //当访问为'/',重定向为/home'
        redirect:'/home',

解决相应的问题:

当前页面进行跳转当前页面会报错,将跳转方法进行修改

clickMenu(item){
      // console.log(item)
      //当页面路由与跳转路由不一致
      if(this.$route.path !== item.path && !(this.$route.path === '/home' && item.path === '/'))
      {
        // 进行跳转
        this.$router.push(item.path)
      }
    }

九:对header头部进行制作

定义一个组件HeaderMenu

<template>
  <div class="header-container">
    <div class="l-content"></div>
    <div class="r-content"></div>
  </div>
</template>

<script>
export default {
  name: "HeaderMenu"
}
</script>

<style lang="less" scoped>
.header-container{
  background: #333;
  height: 60px;
}

</style>

后修改MainPage.vue里的header为组件<HeaderMenu/>

去掉原有默认padding

<style lang="less" scoped>
 .el-header{
   padding: 0;
 }
</style>

后进行左右侧内容进行编写,利用element-ui

左侧:

选取一个button样式,选取合适尺寸

<el-button icon="el-icon-menu" size="mini" ></el-button>

定义到相应位置,修改.header-containe

.header-container{
  padding: 0 20px;
  background: #333;
  height: 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

进行面包屑的搭建

<div class="l-content">
      <el-button icon="el-icon-menu" size="mini" ></el-button>
<!--      添加面包屑效果-->
      <span class="text">首页</span>
</div>
<!--      修改样式-->
<style lang="less" scoped>
.header-container{
  padding: 0 20px;
  background: #333;
  height: 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .text{
    color: white;
    font-size: 14px;
    margin-left: 10px;
  }
}

右侧:

选取合适的下拉菜单样式

<el-dropdown>
  <span class="el-dropdown-link">
    下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
  </span>
  <el-dropdown-menu slot="dropdown">
    <el-dropdown-item>黄金糕</el-dropdown-item>
    <el-dropdown-item>狮子头</el-dropdown-item>
    <el-dropdown-item>螺蛳粉</el-dropdown-item>
    <el-dropdown-item disabled>双皮奶</el-dropdown-item>
    <el-dropdown-item divided>蚵仔煎</el-dropdown-item>
  </el-dropdown-menu>
</el-dropdown>

后进行修改,将下拉菜单改成头像,悬浮后有个人中心和退出选项

     <el-dropdown>
        <span class="el-dropdown-link">
          <img class="user" src="../assets/images/user.jpg" >
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item>个人中心</el-dropdown-item>
          <el-dropdown-item>退出</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>

header-container内添加头像的样式

.r-content{
    .user{
      width: 40px;
      height: 40px;
      //圆角
      border-radius: 50%;
    }

右侧完成

进行点击左侧按钮实现左侧菜单的收起和展开

vuex的使用

利用vuex进行实现(不同组件之间的通信)

引入vuex

npm i vuex@3

建立store文件夹作为仓库,建立index.js进行配置

import Vue from "vue";
//引入Vuex
import Vuex from 'vuex'
//引入tab
import tab from './tab'
//使用Vuex插件
Vue.use(Vuex)
//创建Vuex实例
new Vuex.Store({
    modules:{
        tab,//控制菜单数据
    }
})

建立tab.js

//管理菜单的数据 进行暴露
export default {
    //数据
    state:{
        isCollapse:false //用于控制菜单展开还是收起
    },
    // 方法
    mutations:{
        //修改菜单展开还是收起的方法
        collapseMenu(state)
        {
            state.isCollapse = !state.isCollapse
        }
    }

  }

main.js进行挂载(修改后)

import Vue from 'vue'
import App from './App.vue'
//element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//引入router
import router from "@/router";
//引入store
import store from './store'
//生产模式
Vue.config.productionTip = false

//使用 element-ui 插件
Vue.use(ElementUI);

new Vue({
    render: h => h(App),
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    router,
    //挂载store
    store,
}).$mount('#app')

后进行方法的编写,实现点击头部按钮实现不同组件的数据的转化

首先方法在tab.js内定义完成

实现点击头部改变数据的按钮

...
<el-button icon="el-icon-menu" size="mini" @click="handleMenu"></el-button>
...
<script>
export default {
  name: "HeaderMenu",
  methods:{
    handleMenu(){
      this.$store.commit('collapseMenu')
    }
  }

}
</script>

进行方法的绑定,后再AsideMenu中进行数据的类型更改,把isCollapse改成计算属性,动态获取数据实现转化

computed:{
    //没有子菜单
    noChildren()
    {
      return this.menuData.filter(item => !item.children)
    },
    //拥有子菜单
    haveChildren()
    {
      return this.menuData.filter(item => item.children)
    },
    isCollapse()
    {
// store下的state里的tab模块下的isCollapse数据
      return this.$store.state.tab.isCollapse
    }
  }

实现完成,但左侧折叠后不填充,实现自适应

主要就是原布局中有定义好的Aside宽度,仅需改成自适应就可

<el-aside width="auto"><AsideMenu/></el-aside>

同时,将

.el-menu{
  border-right: 0;
}

加入去除边框1px的白线,以及判断折叠后h3的内容就可较为完美的实现

<h3>{{isCollapse ? '后台':'通用后台管理'}}</h3>

十:home页面的搭建

首先,利用element-ui的组件实现区域的分块和自适应

 <el-row>
    <el-col :span="8">
    </el-col>
    <el-col :span="16">
</el-col>
  </el-row>

采用1:2的分布方式搭建

后进行填充,填充内容卡片,利用以下代码

<el-card class="box-card">
  <div slot="header" class="clearfix">
    <span>卡片名称</span>
    <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>
  </div>
  <div v-for="o in 4" :key="o" class="text item">
    {{'列表内容 ' + o }}
  </div>
</el-card>

进行拆分:

<el-card class="box-card">
  
</el-card>

保留卡片格式,后进行上下两部分划分,上一部分在在拆分成左右两部分,定义div

<el-card class="box-card">
        <!--      上部分-->
        <div class="user">
          <img src="../assets/images/user.jpg" alt="">
        <!--      右侧内容-->
          <div class="userinfo">
            <p class="name">Admin</p>
            <p class="access">超级管理员</p>
          </div>
        </div>
        <!--      下部分-->
        <div class="login-info">
            <p>上次登陆时间:<span>2023-8-26</span></p>
            <p>上次登陆地点:<span>中国</span></p>
        </div>
</el-card>

进行style样式的编码以实现上下左右分块

<style lang="less" scoped>
.user{
  //内部距底部
  padding-bottom: 20px;
  //外部距底部
  margin-bottom: 20px;
  border-bottom: 1px solid ;
  /*左右布局*/
  display: flex;
  //纵轴垂直居中
  align-items: center;
  img{
  width: 150px;
  height: 150px;
  border-radius: 50%;
  margin-right: 40px;
}
.userinfo{
  .name{
  font-size: 32px;
  margin-bottom: 10px;
  }
  .access{
  color: gray;
  }
}

}
.login-info{
  p{
    line-height: 28px;
    font-size: 14px;
    color: #999999;
    span{
      color: #666666;
      margin-left: 60px;
   }
  }
}
</style>

需将p标签原属性清空,来调整p标签margin,padding

<style lang="less">
  html,body,h3,p{
    margin: 0;
    padding: 0;
  }
</style>

后进行table表格的展示

table表格在上面卡片之下,所以在同一个<el-col>内,植入此表格需一个card来承接,采用一个card组件

<el-card class="box-card">
</el-card>

进行内容填充:采用斑马线table表格进行填写

 <el-card class="box-card" style="margin-top: 20px;height:300px">
        <el-table
            :data="tableData"
            style="width: 100%"
            height="250">
          <el-table-column
              prop="name"
              label="品牌"
              >
          </el-table-column>
          <el-table-column
              prop="todayBuy"
              label="今日销量"
              >
          </el-table-column>
          <el-table-column
              prop="monthBuy"
              label="本月销量"
              >
          </el-table-column>
          <el-table-column
              prop="totalBug"
              label="总销量"
              >
          </el-table-column>
        </el-table>
      </el-card>

定义一个tableData数据,其中根据每个对象的属性来进行props内填写

tableData:[
        {
          name:'华为',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
        {
          name:'oppo',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
        {
          name:'vivo',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
        {
          name:'苹果',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
        {
          name:'小米',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
        {
          name:'三星',
          todayBuy:100,
          monthBuy:300,
          totalBug:800
        },
      ]

进行优化,动态生成<el-table>

定义一个tableData:

tableLabel:{
  name:'品牌',
  todayBuy:'今日销量',
  monthBuy:'本月销量',
  totalBug:'总销量'
}

遍历:

<el-card class="box-card" >
          <el-table
              :data="tableData"
              style="width: 100%"
              >
             <el-table-column v-for="(val,key) in tableLabel" :key="key" :prop="key" :label="val"/>
   </el-table>
 </el-card>

定义卡片样式与高度 style="margin-top: 20px;height:300px"

<el-card class="box-card" style="margin-top: 20px;height:300px">
          <el-table
              :data="tableData"
              style="width: 100%">
             <el-table-column v-for="(val,key) in tableLabel" :key="key" :prop="key" :label="val"/>
   </el-table>
 </el-card>

实现滚动展示全部数据 height="250"

<el-card class="box-card" style="margin-top: 20px;height:300px">
          <el-table
              :data="tableData"
              style="width: 100%"
              height="250">
             <el-table-column v-for="(val,key) in tableLabel" :key="key" :prop="key" :label="val"/>
   </el-table>
 </el-card>

后进行右侧的编写

<el-col :span="16"></el-col>

右侧之上而下分为三部分,由上至下进行编写

订单框的编写:

订单数据定义

 countData:[
        {
          name: "今日支付订单",
          value:1234,
          icon:"success",
          color:"#2ec7c9"
        },
        {
          name: "今日收藏订单",
          value:210,
          icon:"star-on",
          color:"#ffb980"
        },
        {
          name: "今日未支付订单",
          value:1234,
          icon:"s-goods",
          color:"#5ab1ef"
        },
        {
          name: "本月支付订单",
          value:1234,
          icon:"success",
          color:"#2ec7c9"
        },
        {
          name: "本月收藏订单",
          value:210,
          icon:"star-on",
          color:"#ffb980"
        },
        {
          name: "本月未支付账单",
          value:1234,
          icon:"success",
          color:"#2ec7c9"
        },
          
      ]

对于每个订单的载体是一个一个卡片

<div class="num">
        <el-card>
        </el-card>
</div>

后进行填写图标,数量,内容样式填写,进行v-for遍历(绑定动态icon)

<div class="num">
  <el-card v-for="item in countData" :key="item.name">
    <i class="icon" :class="`el-icon-${item.icon}`" :style="{background:item.color}"></i>
    <div class="detail">
      <p class="price">¥{{item.value}}</p>
      <p class="description">{{item.name}}</p>
    </div>
  </el-card>
</div>

后进行样式调整,首先是左右布局

利用card的属性,:body-style="{display:'flex'}变成左右布局

<div class="num">
  <el-card v-for="item in countData" :key="item.name" :body-style="{display:'flex'}">
    <i class="icon" :class="`el-icon-${item.icon}`" :style="{background:item.color}"></i>
    <div class="detail">
      <p class="price">¥{{item.value}}</p>
      <p class="description">{{item.name}}</p>
    </div>
  </el-card>
</div>

接下来,调整icon样式,width:80px;height:80px;font-size:30px;text-align=center;color:white;

.num
{ display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  .icon{
    width: 80px;
    height: 80px;
    font-size: 30px;
    text-align: center;
    line-height: 80px;
    color: white;
  }
}

对于每个card的图标进行动态渲染,利用:style

<i class="icon" :class="`el-icon-${item.icon}`" :style="{background:item.color}"></i>

后进行右侧的文件的编写

.detail{
  //向左15px
    margin-left: 15px;
    //弹性盒子
    display: flex;
    //主轴 纵向
    flex-direction: column;
    //垂直居中
    justify-content: center;
    .price{
      font-size: 30px;
      margin-bottom: 10px;
      line-height: 30px;
      height: 30px;
    }
    .description{
      font-size: 14px;
      color: #999;
      text-align: center;
    }

基本文件填写完成,要实现水平显示,在.num下加入

display: flex;

后实现换行

flex-wrap: wrap; //自动换行

加入card宽度,实现一行展示三个

.el-card{
  width: 32%;
  margin-bottom: 20px;
}

为了完美贴合,加入

 justify-content: space-between;

修改el-card样式,使内边距为0

 <el-card v-for="item in countData" :key="item.name" :body-style="{display:'flex',padding:0}">

右上订单功能完成

 
posted on 2023-09-02 11:17  实名吓我一跳  阅读(32)  评论(0)    收藏  举报