vue2+element ui

本文档展示了后端人员如何使用vue2、vueRouter、vueX和element UI构建一个包含登录、路由、状态管理、报表和导出功能的后台管理框架。提供了项目结构、关键组件介绍及代码修改说明,包括Home、Head、Main、Menu、Table等组件的使用。源码可在GitHub和CSDN下载。
摘要由CSDN通过智能技术生成

后端人员开发前端vue。

git地址:https://github.com/1065744299/vue-elment-ui
演示地址:https://1065744299.github.io/
csdn下载源码地址:https://download.csdn.net/download/qq_25451199/11256228
这个demo主要用到vue、vueRouter、vueX、element UI、echarts等技术。主要以展示怎么使用为主。主要的功能有登录、路由、store、报表、导出等。
这里用vue的多页面功能,为了组件的重复使用。
开始介绍代码:
为了打包的时候直打包一个页面,这里对vue.config.js做了修改;代码如下:

var projectname = process.argv[5]
var glob = require('glob')

function getEntry () {
  var entries = {}
  if (process.env.NODE_ENV === 'production') {
    entries = {
      index: {
        // page的入口
        entry: 'src/modules/' + projectname + '/main.js',
        // 模板来源
        template: 'public/index.html',
        // 在 dist/index.html 的输出
        filename: 'index.html',
        title: projectname,
        chunks: ['chunk-vendors', 'chunk-common', 'index']
      }
    }
  } else {
     var items = glob.sync('./src/modules/*/*.js')
     for (var i in items) {
       var filepath = items[i]
       var fileList = filepath.split('/')
       var fileName = fileList[fileList.length - 2]
       entries[fileName] = {
         entry: `src/modules/${fileName}/main.js`,
         // 模板来源
         template: `public/index.html`,
         // 在 dist/index.html 的输出
         filename: `${fileName}.html`,
         // 提取出来的通用 chunk 和 vendor chunk。
         chunks: ['chunk-vendors', 'chunk-common', fileName]
       }
     }
   }
  return entries
}

var pages = getEntry()
// vue.config.js
module.exports = {
  // 基本路径
  publicPath: '/',
  // 输出文件目录
  // outputDir: 'dist',
  // webpack-dev-server 相关配置
  devServer: {
    port: 8888
  },
  // 生产禁止显示源代码
  productionSourceMap: false,
  // 输出文件目录
  outputDir: 'dist/' + projectname,
  pages: pages
}

下面开始搭建一个简单的demo。

主要有几个基础的组件。
先了解下项目结构:
在这里插入图片描述
了解vue的应该知道初始化以后就会有这些目录
这里主要说组件的内容。

  • Home.vue
    主页组件
<template>
  <el-container>
    <el-header>
      <Head :isCollapse='isCollapse' @changeCollapse="changeCollapsed" :sysName='sysName' :userInfo='homeUserInfo' @logoutHandle='logoutHandle'></Head>
    </el-header>
    <el-container>
      <el-aside :class="isCollapse?'menu-collapsed':'menu-expanded'">
        <Menu :isCollapse='isCollapse' :defaultActive="defaultActive" :menuJson='menuJson' @selectedTab="selectedTab(arguments)"/>
      </el-aside>
      <el-main>
        <div class="my-main">
          <Main :editableTabsValue="editableTabsValue" ref="myMain" @selectedTab="mainSelectedTab(arguments)"/>
        </div>
      </el-main>
    </el-container>
  </el-container>
</template>
<script>
import Menu from '@/components/Menu.vue'
import Head from '@/components/Head.vue'
import Main from '@/components/Main.vue'
export default {
  name: 'app',
  props: ['sysName', 'userInfo', 'menuJson'],
  components: {
    Menu,
    Head,
    Main
  },
  data () {
    return {
      // 菜单是否折叠
      'isCollapse': false,
      // 主展示区默认选项卡
      'editableTabsValue': '首页',
      // 菜单默认选中
      'defaultActive': '/main/home'
    }
  },
  computed: {
    'homeUserInfo': function () {
      return this.userInfo
    }
  },
  methods: {
    changeCollapsed: function () {
      this.isCollapse = !this.isCollapse
    },
    selectedTab: function (args) {
      this.editableTabsValue = args[0]
      this.defaultActive = args[1]
      this.$refs.myMain.addTab(this.editableTabsValue, this.defaultActive)
    },
    mainSelectedTab: function (args) {
      this.editableTabsValue = args[0]
      this.defaultActive = args[1]
    },
    myRoute: function (index) {
      this.$router.push({ 'path': index })
    },
    logoutHandle: function () {
      this.$emit('logoutHandle')
    }
  },
  created: function () {
    this.myRoute(this.defaultActive)
  }
}
</script>
<style>
  html,body,#app,.el-container {
    height: 100%;
  }
  .el-header {
    color: #333;
    line-height: 60px;
    padding: 0 0px;
  }
  .el-aside {
    background-color: #eef1f6;
    color: #333;
    line-height: 200px;
  }
  .el-main {
    color: #333;
    padding: 0 0 0 0px;
    width: 100%;
  }
  .menu-collapsed{
    flex:0 0 65px;
    width: 65px;
  }
  .menu-expanded{
    flex:0 0 201px;
    width: 201px;
  }
  body{
    margin: 0px;
  }
  main {
    height:  100%;
    overflow-y: auto;
  }
</style>

  • Head.vue
    头部组件
<template>
  <el-col :span="24" class="header">
    <el-col :span="10" class="logo " :class="isCollapse?'logo-collapse-width':'logo-width'">
      {
  {isCollapse?'':sysName}}
      <img src="../assets/w.jpg" width="66px" height="100%" v-show="isCollapse"/>
    </el-col>
    <el-col :span="10">
      <div class="tools">
        <i :class="isCollapse?'el-icon-s-unfold':'el-icon-s-fold'" @click="pchangeCollapse"></i>
      </div>
    </el-col>
    <el-col :span="4" class="userinfo">
      <el-dropdown trigger="hover">
        <span class="el-dropdown-link userinfo-inner"><img :src="img"/>{
  {name}}</span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item>我的消息</el-dropdown-item>
          <el-dropdown-item>设置</el-dropdown-item>
          <el-dropdown-item @click.native="logoutHandle">退出登录</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </el-col>
  </el-col>
</template>
<script>
let userInfo = {
  name: '苏三杰',
  img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'
}
export default {
  props: {
    'isCollapse': {
      type: Boolean,
      default: true
    },
    'userInfo': {
      type: Object,
      default: () => userInfo
    },
    'sysName': {
      type: String,
      default: 'WEBDEMO'
    }
  },
  data () {
    return {}
  },
  computed: {
    'name': function () {
      return this.userInfo.name
    },
    'img': function () {
      return this.userInfo.img
    }
  },
  methods: {
    pchangeCollapse: function () {
      this.$emit('changeCollapse')
    },
    logoutHandle: function () {
      this.$confirm('确定要退出吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // this.$message({
        //   type: 'success',
        //   message: '删除成功!'
        // })
        this.$emit('logoutHandle')
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消退出'
        })
      })
    }
  }
}
</script>
<style scoped>
.header {
  height: 60px;
  line-height: 60px;
  background: #67C23A;
  color:#fff
}

.userinfo {
  height: 60px;
  line-height: 60px;
  text-align: right;
  padding-right: 35px;
  float: right;
}
  .userinfo-inner {
    height: 60px;
    line-height: 60px;
    cursor: pointer;
    color:#fff;
  }
  .userinfo-inner>img {
    cursor: pointer;
    color:#fff;
    width: 40px;
    height: 40px;
    border-radius: 20px;
    margin: 10px 0px 10px 10px;
    float: right;
  }
  .logo {
    height:60px;
    font-size: 22px;
    border-color: rgba(238,241,146,0.3);
    border-right-width: 1px;
    border-right-style: solid;
  }
  .txt {
    color:#fff;
  }

  .logo-width{
    width:202px;
    padding-left:20px;
    padding-right:20px;
  }
  .logo-collapse-width{
    width:65px;
    padding-left:0px;
    padding-right:0px;
  }
  .tools{
    padding: 0px 23px;
    width:14px;
    height: 60px;
    line-height: 60px;
    cursor: pointer;
  }
</style>

  • Main.vue
    主展示区组件
<template>
  <el-tabs v-model="myEditableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="goRoute">
    <el-tab-pane
      v-for="(item) in editableTabs"
      :key="item.name"
      :label="item.title"
      :name="item.name"
      :myindex="item.index"
    >
      <div class="mymain">
        <router-view/>
      </div>
    </el-tab-pane>
  </el-tabs>
</template>
<script>
export default {
  props: ['editableTabsValue'],
  data () {
    return {
      editableTabs: [{
        title: '首页',
        name: '首页',
        index: '/main/home'
      }],
      myEditableTabsValue: this.editableTabsValue
    }
  },
  methods: {
    addTab (name, index) {
      for (var t in this.editableTabs) {
        if (this.editableTabs[t].name === name) {
          this.myEditableTabsValue = name
          return
        }
      }
      this.editableTabs.push({
        title: name,
        name: name,
        index: index
      })
      this.myEditableTabsValue = name
    },
    removeTab (targetName) {
      let tabs = this.editableTabs
      let activeName = this.myEditableTabsValue
      // let activeName = ''
      let _index = ''
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
              _index = nextTab.index
            }
          }
        })
      }
      this.$router.push({ 'path': _index })
      this.$emit('selectedTab', activeName, _index)
      this.myEditableTabsValue = activeName
      this.editableTabs = tabs.filter(tab => tab.name !== targetName)
    },
    goRoute (args) {
      let tabs = this.editableTabs
      let _thisTab = tabs.filter(tab => tab.name === args.name)[0]
      this.$router.push({ 'path': _thisTab.index })
      this.$emit('selectedTab', _thisTab.name, _thisTab.index)
      // this.$emit('myRoute', _thisTab.index)
    }
  }
}
</script>
<style scoped>
.mymain {
  padding: 0 5px
}
</style>

  • Menu.vue
    菜单组件
<template>
  <div>
    <el-menu
      :default-active="defaultActive"
      class="el-menu-vertical-demo"
      @open="handleOpen"
      @close="handleClose"
      :collapse="isCollapse"
      background-color="#eef1f6"
      active-text-color="#20a0ff"
      :collapse-transition="false"
      text-color="#48576a"
      :router="true"
      >
      <template v-for="m in menus">
        <el-submenu v-if="m.type=='subMenu'" :index="m.id" :key="m.id">
          <template slot="title">
            <i :class="m.icon"></i>
            <span slot="title">{
  {m.name}}</span>
          </template>
          <el-menu-item v-for="mi in m.submenus" :key="mi.id" :index="mi.url" :route="{path: mi.url}" @click.native="selected(mi.name, mi.url)">
            {
  {mi.name}}
          </el-menu-item>
        </el-submenu>
        <el-menu-item v-if="m.type=='menu-item'" :index="m.url" :key="m.id" :route="{path: m.url}" @click.native="selected(m.name, m.url)">
          <i :class="m.icon"></i>
          <span slot="title">
            {
  {m.name}}
          </span>
        </el-menu-item>
      </template>
  </el-menu>
</div>
</template>
<script>
let menuJson = [
  {
    id: '1',
    name: '首页',
    type: 'menu-item',
    url: '/',
    icon: 'el-icon-star-off',
    submenus: []
  },
  {
    id: '2',
    name: 'TableS',
    type: 'subMenu',
    url: '',
    icon: 'el-icon-s-grid',
    submenus: [
      {
        id: '3',
        name: '动态table',
        type: 'subMenu',
        url: '/about',
        icon: ''
      },
      {
        id: '4',
        name: '拖拽table',
        type: 'subMenu',
        url: '/about1',
        icon: ''
      },
      {
        id: '5',
        name: '综合table',
        type: 'subMenu',
        url: '/about2',
        icon: ''
      }
    ]
  },
  {
    id: '6',
    name: '列表demo',
    type: 'subMenu',
    url: '',
    icon: 'el-icon-user',
    submenus: [
      {
        id: '7',
        name: '用户列表',
        type: 'subMenu',
        url: '/user',
        icon: ''
      }
    ]
  }
]
export default {
  // props: ['isCollapse', 'defaultActive', 'menuJson'],
  props: {
    'isCollapse': {
      type: Boolean,
      default: true
    },
    'defaultActive': {
      type: String,
      default: '首页'
    },
    'menuJson': {
      type: Array,
      default: () => menuJson
    }
  },
  data () {
    return {
      menus: this.menuJson
    }
  },
  methods: {
    handleOpen (key, keyPath) {
      console.log(key, keyPath)
    },
    handleClose (key, keyPath) {
      console.log(key, keyPath)
    },
    selected (name, index) {
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值