一.后台搭建

使用 vue-admin-template 来快速搭建后台管理,它包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。

Element是(饿了么团队)基于MVVM框架Vue开源出来的一套前端ui组件。官网: element-ui

1.快速搭建

若用vue官网提供的脚手架需要写跟多代码,比如登录界面、主界面菜单等。可以使用 vue-admin-template ,在此基础上开发,而且github上配有详细的模板说明,这样可以节省开发时间。

  1. 下载vue-admin-template(vue 2.0)进行解压
  2. 在命令提示符切换到该目录,输入命令安装所有依赖:

    cnpm install

  3. 运行

    npm run dev

2.工程结构
目录名称存储内容
build构建工程相关脚本
config配置相关
src工程源码
static静态资源
src/api访问后端API
src/utils工具类
src/views路由组件
src/router路由
3.项目初始化
  1. 关闭语法规范性检查
    修改config/index.js : useEslint = false

  2. 国际化设置
    修改main.js :
    import locale from ‘element‐ui/lib/locale/lang/en’ --> import locale from ‘elemen‐ui/lib/locale/lang/zh‐CN’

  3. 与easy-mock对接
    修改config下dev.env.js中BASE_API为easy-mock的Base URL,easy-mock最好部署到服务器上

    BASE_API: '"http://192.168.91.136:7300/mock/5af314a4c612520d0d7650c7"',
    

    easy-mock添加登录认证模拟数据
    地址: /user/login
    提交方式:post
    内容:

    {
    	"code": 20000,
    	"data": {
    		"token": "admin"
    	}
    }
    

    添加返回用户信息url模拟数据
    地址:/user/info
    提交方式:get
    内容:

    {
      	"code": 20000,
      	"data": {
        	"roles": ["admin"],
        	"role": ["admin"],
        	"name": "admin",
        	"avatar": "https://wpimg.wallstcn.com/f778738c‐e4f8‐4870‐b634‐56703b4acafe.gif"
     	 }
    }
    
4.更改标题与菜单
  1. 修改index.html的标题为“后台管理系统”,修改后浏览器自动刷新。
  2. 修改src/router下的index.js中constantRouterMap的内容
    export const constantRoutes = [
      {
        path: '/login',
        component: () => import('@/views/login/index'),
        hidden: true
      },
    
      {
        path: '/404',
        component: () => import('@/views/404'),
        hidden: true
      },
    
      {
        path: '/',
        component: Layout,
        // redirect: '/dashboard',
        redirect: '/hostmanager/server',   //登录后重定向到服务器信息页面
        children: [{
          path: 'dashboard',
          name: 'Dashboard',
          component: () => import('@/views/dashboard/index'),
          meta: { title: 'Dashboard', icon: 'dashboard' }
        }]
      },
    
      {
        path: '/hostmanager',
        component: Layout,
        redirect: '/hostmanager/list',
        name: 'hostmanager',
        meta: { title: '主机管理', icon: 'example' },
        children: [
          {
            path: 'server',
            name: 'Server',
            component: () => import('@/views/server/index'),
            meta: { title: '服务器信息', icon: 'form' }
          },
          {
            path: 'list',
            name: 'List',
            component: () => import('@/views/list/index'),
            meta: { title: '主机列表', icon: 'table' }
          },
          {
            path: 'task',
            name: 'Task',
            component: () => import('@/views/task/index'),
            meta: { title: '任务控制', icon: 'tree' }
          }
        ]
      },
    
      {
        path: '/testqueue',
        component: Layout,
        children: [
          {
            path: 'index',
            name: 'testQueue',
            component: () => import('@/views/queue/index'),
            meta: { title: '测试队列', icon: 'form' }
          }
        ]
      },
      {
        path: '/taskmanager',
        component: Layout,
        meta: { title: '任务管理', icon: 'example' },
        children: [
          {
            path: 'list',
            name: 'taskList',
            component: () => import('@/views/taskList/index'),
            meta: { title: '任务列表', icon: 'form' }
          },
          {
            path: 'detail',
            name: 'taskDetail',
            component: () => import('@/views/taskDetail/index'),
            meta: { title: '任务清单', icon: 'form' }
          },
          {
            path: 'create',
            name: 'taskCreate',
            component: () => import('@/views/taskCreate/index'),
            meta: { title: '新建任务', icon: 'form' }
          },
        ]
      },
    	
      // 404 page must be placed at the end !!!
      { path: '*', redirect: '/404', hidden: true }
    ]
    

二.element-ui使用

1.表格组件
<el-table :data="list" border style="width: 100%;">
  <el-table-column prop="id" label="活动ID" min-width="1"></el-table-column>
  <el-table-column prop="name" label="活动名称" min-width="1"></el-table-column>
  <el-table-column prop="address" label="活动地址" min-width="1"></el-table-column>
  <el-table-column prop="starttime" label="开始日期" min-width="1"></el-table-column>
  <el-table-column label="操作" min-width="1">
    <template slot-scope="scope">
      <el-button type="text" size="small" @click="handleEdit(scope.row.id)">修改</el-button>
      <el-button type="text" size="small" @click="handleDelete(scope.row.id)">删除</el-button>
    </template>
  </el-table-column>
</el-table>

<script>
import gatheringApi from '@/api/gathering'
export default {
    data(){
      return {
          list:[]
      } 
    },
    created(){
        this.fetchData();
    },
    methods:{
        fetchData(){
           gatheringApi.getList().then(response => {
                this.list=response.data
           });
        }
    }
}
</script>

当没有使用template模板页时,一般加上prop属性,若有template时,可以为:

<el-table-column label="主机名" min-width="2">
  <template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column label="操作" min-width="3">
  <template slot-scope="scope">
    <el-button type="primary" size="small" @click="findTask(scope.$index,scope.row)">查看</el-button>
    <el-button type="info" size="small" :disabled="scope.row.status !== '空闲'" @click="createTask(scope.$index,scope.row)">新建</el-button>
  </template>
</el-table-column>

slot-scope用于指定当前行的上下文。使用scope.row可以获取行对象。

table组件的属性:

参数说明类型
data显示的数据array

table-column组件的属性:

参数说明类型
label显示的标题string
prop对应列内容的字段名string
width对应列的宽度number
min-width按比例显示宽度number

官方文档:table组件

2.分页组件
<el‐table :data="list" border style="width: 100%"></el-table>
<el-pagination
  @size-change="fetchDate"
  @current-change="fetchDate"
  :current-page="currentPage"
  :page-sizes="[10,20,30,50]"
  :page-size="pageSize"
  layout="sizes, prev, pager, next, jumper, ->, total, slot"
  :total="total">
</el-pagination>

<script>
import gatheringApi from '@/api/gathering'
export default {
    data(){
      return {
         list:[],
         total:0,//总记录数
         currentPage:1,//当前页
         pageSize:10,//每页大小
         searchMap: {}//查询表单绑定变量
      } 
    },
    created(){
        this.fetchData();
    },
    methods:{
        fetchData(){
           gatheringApi.search(this.currentPage,this.pageSize,this.searchMap).then(response =>{
               this.list=response.data.rows
               this.total=response.data.total
           });
        }
    }
}
</script>

上面的分页方式是数据量比较大是传currentPage, pageSize给后端,由后端来实现分页;
数据量比较小时由前端实现分页,如下:

<el-table border :data="list.slice((currentPage-1)*pageSize, currentPage*pageSize)" style="width: 100%;margin-top: 20px;"></el-table>
<el-pagination
  background
  @size-change="handleSizeChange"
  @current-change="handleCurrentChange"
  :current-page="currentPage"
  :page-size="pageSize"
  layout="sizes, prev, pager, next, jumper, ->, total"
  :total="list.length">
</el-pagination>

<script>
export default {
	data() {
		return {
			list: [],
			currentPage: 1,
			pageSize: 10,
		}
	},
	methods: {
			// 分页相关函数
	      handleSizeChange(val){
	        console.log(`每页${val}条`)
	        this.pageSize = val
	      },
	      handleCurrentChange(val){
	        console.log(`当前页:${val}`)
	        this.currentPage = val
	      },
	}
}
</script>

pagination的常用属性:

参数说明类型可选值默认值
page-size每页显示条目个数number-10
total总条目数number--
current-page当前页数,支持.sync修饰符number-1
layout组件布局stringsizes,prev,pager,next,jumper,->,total,slotprev,pager,next,jumper, ->, total
pages-sizes每页显示个数选择器的选项设置number[]-[10,20,30,40,50,100]

pagination的常用事件:

事件名称说明回调参数·
size-changerpageSize改变时会触发每页条数
current-changecurrentPage改变时会触发当前页

官网链接:pagination组件

3.表单组件

在分页列表的基础上实现条件查询功能

<!-- 行内表单:用于查询条件 -->
<el-form :inline="true">
  <el-form-item label="活动名称">
    <el-input v-model="searchMap.name" placeholder="活动名称"></el-input>
  </el-form-item>
  <el-form-item label="活动日期">
    <el-date-picker
      type="date"
      v-model="searchMap.startdate"
      placeholder="选择开始日期"
      ></el-date-picker>
    <el-date-picker
      type="date"
      v-model="searchMap.enddate"
      placeholder="选择结束日期"
      ></el-date-picker>
  </el-form-item>
  <el-button type="primary" @click="fetchDate">查询</el-button>
  <el-button type="primary" @click="handleEdit('')">新增</el-button>
</el-form>

<!-- 对话框表单  -->
<el-dialog title="活动编辑" :visible.sync="addDialogVisible">
	<el-form label-width="80px">
	  <el-form-item label="活动名称">
	    <el-input v-model="pojo.name" placeholder="活动名称"></el-input>
	  </el-form-item>
	  <el-form-item label="开始日期">
	    <el-date-picker type="date" v-model="pojo.starttime" placeholder="开始日期"></el-date-picker>
	  </el-form-item>
	  <el-form-item label="活动详情">
	    <el-input type="textarea" v-model="pojo.detail" :rows="2" placeholder="活动详情"></el-input>
	  </el-form-item>
	  <el-form-item label="是否可见">
	    <el-switch v-model="pojo.state" active-color="#13ce66" inactive-color="#ff4949"
	      active-value="1" inactive-value="0"></el-switch>
	  </el-form-item>
	  <el-form-item>
	    <el-button type="primary" @click="handerSave">保存</el-button>
	    <el-button @click="addDialogVisible=false">关闭</el-button>
	  </el-form-item>
	</el-form>
</el-dialog>

form(表单)组件官方文档:form组件
input(文本框)组件官方文档:input组件
date-picker(日期框)组件官方文档:DatePicker组件
switch(开关)组件官方文档:switch组件

注意:input组件中多行文本框设置

4.对话框组件
<el-dialog title="新建任务" :visible.sync="addDialogVisible" width="37%">
</el-dialog>

<script>
	data(){
		......
		addDialogVisible: false	// 对话框是否显示
	}
</script>

属性title为对话框标题,visible为是否显示。变量addDialogVisible用于控制对话框的显示,点击按钮将dialogFormVisible = true即可打开对话框。

dialog(对话框)组件官方文档:dialog组件

5.下拉选组件
<el‐form‐item label="城市">
  <el‐select v‐model="pojo.city" placeholder="请选择">
    <el‐option
      v‐for="item in cityList"
      :key="item.id"
      :label="item.name"
      :value="item.id">
    </el‐option>
  </el‐select>
</el‐form‐item>

<script>
	import cityApi from '@/api/city'
	export default {
		data(){
			return {
				cityList: []
			}
		},
		created() {
	      cityApi.getList().then(response =>{
	        this.cityList = response.data
	      })
	    }
    }
</script>

select(下拉选)组件官方文档:select组件

6.消息提示组件
this.$message({
    message: response.message,
    type: (response.flag?'success':'error')
});
// 或者
this.$message.success('请求成功!');

message(消息提示)组件官方文档:message组件

7.关于尺寸介绍

默认尺寸是最大的,其次中等、小、超小
button按钮
size:medium / small / mini
input输入框
size:medium / small / mini
select选择器
size:medium / small / mini
form表单
label-width:表单域标签的宽度
size:medium / small / mini (用于控制该表单域下组件的尺寸)
table表格
size:medium / small / mini

三.vue中使用element-ui示例

对活动管理的查询、分页、条件查询,增加,修改,删除等。采用的easy-mock的模拟接口。

gathering.vue
<template>
  <div>
    <br/>
    <el-form :inline="true">
      <el-form-item label="活动名称">
        <el-input v-model="searchMap.name" placeholder="活动名称"></el-input>
      </el-form-item>
      <el-form-item label="活动日期">
        <el-date-picker
          type="date"
          v-model="searchMap.startdate"
          placeholder="选择开始日期"
          ></el-date-picker>
        <el-date-picker
          type="date"
          v-model="searchMap.enddate"
          placeholder="选择结束日期"
          ></el-date-picker>
      </el-form-item>
      <el-button type="primary" @click="fetchDate">查询</el-button>
      <el-button type="primary" @click="handleEdit('')">新增</el-button>
    </el-form>

    <el-table :data="list" border style="width: 100%;">
      <el-table-column prop="id" label="活动ID" min-width="1"></el-table-column>
      <el-table-column prop="name" label="活动名称" min-width="1"></el-table-column>
      <el-table-column prop="address" label="活动地址" min-width="1"></el-table-column>
      <el-table-column prop="starttime" label="开始日期" min-width="1"></el-table-column>
      <el-table-column label="操作" min-width="1">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="handleEdit(scope.row.id)">修改</el-button>
          <el-button type="text" size="small" @click="handleDelete(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      @size-change="fetchDate"
      @current-change="fetchDate"
      :current-page="currentPage"
      :page-sizes="[10,20,30,50]"
      :page-size="pageSize"
      layout="sizes, prev, pager, next, jumper, ->, total, slot"
      :total="total">
    </el-pagination>

    <el-dialog title="活动编辑" :visible.sync="addDialogVisible">
      <el-form label-width="80px">
        <el-form-item label="活动名称">
          <el-input v-model="pojo.name" placeholder="活动名称"></el-input>
        </el-form-item>
        <el-form-item label="开始日期">
          <el-date-picker type="date" v-model="pojo.starttime" placeholder="开始日期"></el-date-picker>
        </el-form-item>
        <el-form-item label="活动详情">
          <el-input type="textarea" v-model="pojo.detail" :rows="2" placeholder="活动详情"></el-input>
        </el-form-item>
        <el-form-item label="选择城市">
          <el-select v-model="pojo.city" placeholder="请选择">
            <el-option
              v-for="item in cityList"
              :key="item.id"
              :value="item.id"
              :label="item.name"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="是否可见">
          <el-switch v-model="pojo.state" active-color="#13ce66" inactive-color="#ff4949"
            active-value="1" inactive-value="0"></el-switch>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handerSave">保存</el-button>
          <el-button @click="addDialogVisible=false">关闭</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

  </div>
</template>

<script>
  import gatheringApi from '@/api/gathering'
  import cityApi from '@/api/city'

  export default {
    data(){
      return {
        list: [], // 当前活动列表
        // 分页初始化
        currentPage: 1, // 当前页
        pageSize: 20, // 每页条数,默认是10
        searchMap: {}, //查询条件
        total: 0, // 总条数
        // 对话框
        addDialogVisible: false,
        pojo: {},  // 对话框表单数据对象
        // 城市下拉选列表
        cityList: [],  //城市列表
        id: '', // 当前编辑的id
      }
    },
    created() {
      this.fetchDate();
      cityApi.getList().then(res => {
        this.cityList = res.data;
        console.log(res.data)
      })

    },
    methods: {
      // 分页根据条件获取列表数据
      fetchDate(){
        gatheringApi.search(this.currentPage, this.pageSize, this.searchMap).then(res => {
          this.list = res.data.rows;    // 当前页面列表
          this.total = res.data.total;  // 总条数
          console.log(res.data.rows)
        }).catch(err => {
          alert('请求失败!')
        })
      },
      // 新增或修改
      handleEdit(id){
        this.id = id; // 标准是新增还是修改
        this.addDialogVisible = true; // 打开窗口
        if (id){  // 修改
          // 调用查询
          gatheringApi.findById(id).then(response => {
            this.pojo = response.data;
          })
        } else {  // 新增
          this.pojo = {}  // 清空表单
        }
      },
      // 保存
      handerSave(){
        gatheringApi.updateById(this.id,this.pojo).then(res => {
          this.$message({
            message: res.message,
            type: (res.flag? 'success':'error'),
          });
          if (res.flag){  //添加成功
            this.fetchDate();
          }
        });
        this.addDialogVisible = false;  //关闭对话框
      },
      handleDelete(id){
        this.$confirm('确定要删除此条记录吗','提示',{
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          gatheringApi.deleteById(id).then(res => {
            this.$message({
              message: res.message,
              type: (res.flag? 'success':'error')
            });
            if (res.flag){
              this.fetchDate(); // 刷新数据
            }
          });
        }).catch(() => {});
      }

    },

  }
</script>

<style>

</style>
gathering.js
import request from '@/utils/request'
const group_name = 'gathering'
const api_name = 'gathering'

export default {
  getList() { // 获取所有
    return request(
      {
        url: `/${group_name}/${api_name}`,
        method: 'get'
      }
    );
  },
  search(page, size, searchMap){  // 分页
    return request(
      {
        url: `/${group_name}/${api_name}/search/${page}/${size}`,
        method: 'post',
        data: searchMap
      }
    );
  },
  save(pojo){   // 新增对话框保存
    return request(
      {
        url: `/${group_name}/${api_name}`,
        method: 'post',
        data: pojo
      }
    )
  },
  findById(id){ // 根据id查询
    return request({
      url: `/${group_name}/${api_name}/${id}`,
      method: 'get'
    });
  },
  updateById(id,pojo){
    if (id == null || id == ''){
      return this.save();
    };
    return request({
      url: `/${group_name}/${api_name}/${id}`,
      method: 'put',
      data: pojo
    });
  },
  deleteById(id){
    return request({
      url: `/${group_name}/${api_name}/${id}`,
      method: 'delete'
    });
  }
}

city.js
import request from "@/utils/request"
export default {
  getList(){
    return request(
      {
        url:'/base/city',
        method:'get'
      }
    );
  }
}

Logo

前往低代码交流专区

更多推荐