前端模拟面试练习提升题

一.后台搭建

使用 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.  

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 组件布局 string sizes,prev,pager,next,jumper,->,total,slot prev,pager,next,jumper, ->, total
pages-sizes 每页显示个数选择器的选项设置 number[] - [10,20,30,40,50,100]

pagination的常用事件:

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

官网链接: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.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'
      }
    );
  }
}

 
-------------------------------------------------------------