vue详细用法,ajax异步请求,案例分析 Element-ui组件使用,表单提交更新,下载,超详细

Vue 用法及部分Element-UI

标签及属性的使用

1.1 <template 标签
<!-- 该标签可以理解为页面布局,display默认为none,存放dom树下的元素-->
<template>
	<div>...
        <div>..
            <el-form>
                <el-row>
                    <el-col>
</template>
1.2 form表单
 <!--  ElementUI 提供的form表单 -->
 <el-form  ....     /formel>
1.2.1 ref属性
<!-- Dom元素的获取(el-form表单对象),Vue为简化DOM获取方法提出了ref 属性和$refs 对象.一般的操作流程是:  ref绑定控件,$refs 获取控件。--> 
1.2.2 :model属性
<!-- 指定表单使用的数据的,注意的是:如果要用 rules 进行表单校验,
那么 el-input 绑定的元素必须是 el-form 的 model 的直接属性,
否则会导致校验失败。  -->    不太明白的可以对着下面的案例看
1.2.3 :rules属性
<!-- :rules:提供表单验证规则,并通过 el-form-item 的 prop 属性绑定校验规则,
在data中定义rules:{并添加prop属性里具体校验的值},
el-from-item 的 prop 属性必须与 el-input 中需要校验的表单属性一致。-->
1.2.4 label-width属性
<!-- 可以在form表单中设置label-width宽度(
作为 Form 直接子元素的 form-item 会继承该值)-->
1.2.5 el-row标签
<!-- 分栏布局-->
1.2.5 <el-col 标签 :span="12"属性
<!-- el-col 配合el-row布局进行使用,属于row子类 :span,定义单个栏的长度 -->
1.2.5 <el-form-item 标签
<!-- 表示单个表单域,表单域中可以放置各种类型的表单控件,
包括 Input、Select、Checkbox、Radio、Switch、DatePicker、TimePicker -->
1.2.6 label 属性
<!-- 这是一个标签的文本 文本框前的提示字体  -->
1.2.7 prop属性 required
<!-- 设置需要校验的字段名 表单验证时,
就会验证el-input元素绑定的变量planForm.title的值是否符合验证规则
 后面加上required时,需要自定义rules规则  -->
1.2.9 v-model属性
<!-- 表单数据对象 数据的双向绑定  -->
1.2.8 placeholder属性
 <!-- input内占位符,隐形提示  -->
<template>   
		<el-form ref="planForm" :model="planForm" :rules="rules" label-width="130px">
              <el-row>
                <el-col :span="12">
                  <el-form-item label="申请主题" prop="title" required>
                    <el-input v-model="planForm.title" placeholder="请填写申请主题"></el-input>
                  </el-form-item>
                </el-col>
                ...部分重复代码省略
</template>               
<script>
data(){
    return { 
         planForm: {
        title: '', // 工单标题
        soOrderCode: '', // 工单编码
        createPerson: '', // 发起人账号
        createPersonName: '', // 发起人
        createDep: '', // 发起部门
        planEndTime: '', // 计划完成时间
        major: [], // 专业
        planType: '', // 计划类型
        checkMan: [], // 审核人
        executeMan: [], // 执行人
        copyMan: [], // 抄送人
        businessFiles: [] // 附件信息
    },
	rules: {
        title: [
          { required: true, message: '请输入工单标题', trigger: 'blur' },
 		  { min: 3, max: 20,message: '长度在 3 到 20 个字符', trigger: 'blur'}
        ],
        planEndTime: [
          { required: true, message: '请输入计划完成时间', trigger: 'blur' }
        ],
        major: [
          { required: true, message: '请选择专业', trigger: 'blur' }
        ],
        planType: [
          { required: true, message: '请选择计划类型', trigger: 'blur' }
        ],
        executeMan: [
          { validator: validateExecuteMan, trigger: 'blur' }
        ],
        influenceCoverage: [
          { validator: validateInfluenceCoverage, trigger: 'blur' }
        ]
		}
      },
</script>
效果图:

在这里插入图片描述

1.3 Select 选择器

当选项过多时,使用下拉菜单展示并选择内容。

1.3.1 multiple 属性
 <!-- 是否多选 boolean 默认false -->
1.3.2 v-for=“item in majorOptions”
  <!-- majorOptions 为要遍历的数据 -->
1.3.3 :value=“item.value”
  <!-- value为选项的值 -->
1.3.4 :label=“item.showName”
 <!-- 选项的标签,若不设置则默认与 value 相同,这里设置为遍历显示showName -->

代码:

			</el-col>
                <el-col :span="12">
                  <el-form-item label="专业" prop="major" required>
                    <el-select v-model="planForm.major" multiple placeholder="请选择">
                      <el-option
                        v-for="item in majorOptions"
                        :key="item.value"
                        :label="item.showName"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
<script>
import { getDictByCode, delFile } from '@/api/setting/sysSetting'
	
	data(){
		return{
		      majorOptions: [],  // 此下拉框的专业枚举值
              planOptions: [],	//... 其他枚举值
		}	
	}
    
    methods: {
           /* 加载配置*/
    configInit() {
      this.queryConfig('majorOptions').then(res => {
        res.data.datas.filter(major => {
          this.majorOptions.push({
            showName: major.valName,
            value: major.valCode
          })
        })
      }),
     /*
    *获取字典值
    */
    async queryConfig(condition) {
      const configResult = await getDictByCode({ typeCode: condition })
      return configResult
    }   
    }
</script>

以下为api/setting/sysSetting’中读取到的值:

// 根据业务字典编码查询业务字典信息
export function getDictByCode (params) {
  return http({
    url: http.adornUrl('/serviceDictionary/queryBdValByTypeCode'),
    method: 'post',
    params
  })
}

代码太乱看不懂? 我带你捋一遍:

  1. 首先我们用< el -select 标签 进行下拉, 使用V-for 属性进行遍历 majorOptions

在这里插入图片描述

  1. 然后我们根据要遍历的内容,找到了data中的对应数据, majorOptions已经封装成枚举值,类似于对象
  2. 我们根据返回的对象,找到需要加载对象的配置类,看到queryconfig,需要获取的又一层封装对象,
  3. 第四部就是我们遍历枚举值,从中获取他的属性值
  4. 我们找到了queryconfig进行后台数据遍历,但是我们业务中可能有很多重复的下拉,每个都写一个url太费劲,并且为了让其解耦,我们将url的定义到一个单独的js中
  5. 通过impor…form…将其引用到该文件中
  6. 第7部就是我们编写url地址,从后端读取操作啦

在这里插入图片描述

在这里插入图片描述

1.4 提交
1.4.1 type指定按钮类型

primary为主要按钮 @click

1.4.2 @click

绑定鉴定事件

              <el-form-item label="">
                <el-button type="primary" @click="submitForm('planForm')">立即创建</el-button>
                <el-button @click="resetForm('planForm')">重 置</el-button>
              </el-form-item>
1.4.3 绑定事件

以下为对提交的内容信息进行判断,除了表单信息校验以外,如果上传文件,也需要对文件进行校验,并且读取文件信息

<script> 
    methods: {
        // 绑定按钮判断事件
submitForm(formName) {
    // validate是对整个表单进行校验的方法,参数为一个回调函数,该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise
      this.$refs[formName].validate((valid) => {
        if (valid) {
            // 判断附件文件内容是否为空	
          if (this.attachmentData && this.attachmentData.length > 0) {
              // 将附件文件传入
            this.attachmentData.filter(res => {
              if (res.fileName) {
                this.planForm.businessFiles.push({
                    // 读取附件的id以及name
                  fileId: res.fileId,
                  fileName: res.fileName
                })
              }
            })
          }
            //  将传过来的字符串抄送人等信息,用','进行拆分
          if (this.planForm.checkMan) {
            this.planForm['checkMan'] = this.planForm.checkMan.join(',')
          }
          if (this.planForm.copyMan) {
            this.planForm['copyMan'] = this.planForm.copyMan.join(',')
          }
          if (this.planForm.executeMan) {
            this.planForm['executeMan'] = this.planForm.executeMan.join(',')
          }
          this.planForm.major = this.planForm.major.join(',')
          this.saveOrder(this.planForm)
        } else {
          return false
        }
      })
    },
        //校验完成后.将数据传入后台 发http请求
  saveOrder(planForm) {
      //	$loading加载数据时显示动效。  
      //  参数:	lock:同 v-loading 指令中的 lock 修饰符
   	  // 		 text:显示在加载图标下方的加载文案  spinner:自定义加载图标类名  
      const loadingObj = this.$loading({
        lock: true,
        text: '提交中...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      //  发起url请求
      this.$http({
        url: this.$http.recUrl('/commonPlan/saveCommon'),
        method: 'post',
        data: planForm
      }).then(res => {
          //  res为返回的参数值
        if (res.data.code === 0) {
          this.$message.success('工单创建成功')
          this.resetForm('planForm')
        } else {
          this.$message.error(res.data.msg)
        }
          //  关闭加载数据时显示动效
        loadingObj.close()
      }).catch(() => {
        loadingObj.close()
      })
    },
    }
</script>
1.4.4 重置事件
<script> 
    methods: {
resetForm(formName) {
      this.$refs[formName].resetFields()
      this.planForm = {
        title: '', // 工单标题
        soOrderCode: '', // 工单编码
        createPerson: '', // 发起人账号
        createPersonName: '', // 发起人
        createDep: '', // 发起部门
        planEndTime: '', // 计划完成时间
        major: [], // 专业
        planType: '', // 计划类型
        checkMan: [], // 审核人
        executeMan: [], // 执行人
        copyMan: [], // 抄送人
        planDesc: '', // 任务内容描述
        matterSystem: '', // 问题系统
        findTime: '', // 问题出现时间
        influenceCoverage: '', // 影响使用范围
        unit: '', // 单元
        changeReason: '', // 调整原因
        changeOption: '', // 调整说明
        comment: '' // 备注
      }
      this.planForm.soOrderCode = 'TYLC' + moment(new Date()).format('YYYYMMDDHHmmssSSS')
      this.planForm.createPerson = sessionStorage.getItem('loginId')
      this.planForm.createPersonName = sessionStorage.getItem('userName')
      if (this.planForm.createPerson === null || this.planForm.createPerson === '' ||
        this.planForm.createPersonName === null || this.planForm.createPersonName === '') {
        this.getUserInfo()
      }
      this.getUserDeptInfo()
      this.param.userId = this.planForm.createPerson
      this.attachmentData = [{
        businessId: '',
        businessName: '',
        fileName: '',
        fileId: null,
        fileList: []
      }]
    },
    }
    </script> 

来看看我们学习以后想要的效果图把…

…后端代码省略…外加css代码省略…

在这里插入图片描述

以上为新增前端vue代码,下面在进行分页查询vue代码案例分析,

2 分页查询

2.1 表格属性
2.1.1 el-table 标签

我们查询到的后端数据,通常要用表格进行显示, 因此用 <el-table

2.2.2 :data属性

:data=“tableData” 要显示的数据,及我们一会要从数据库查找过后显示的数据接收值

2.2.3 border属性

​ 是否带有纵向边框 默认false

2.2.4 tooltip-effect属性

​ 省略的内容显示的形式

2.2.5 <el-table-column标签

​ 每个表中字段的定义

2.2.6 label, align, 属性

​ label,表中字段名字 align, 位置

<template>
	<div class=".."> 
        <div class="..">
            <el-form ref="form" :model="form">
                .....表头...工单主题/工单编号等...
    		</el-form>
	<el-table
            :data="tableData"
            border
            tooltip-effect="dark"
            style="width: 100%" v-if="form.sheetType=='1' ">
            <el-table-column
              label="工单编号"
              align="center"
              show-overflow-tooltip
              width="200">
              <template slot-scope="scope" v-if="form.sheetType=='1'">
                <a @click="tableDetail(scope.row)"><span class="table-detail">{{scope.row.soOrderCode}}									</span></a>
              </template>
            </el-table-column>
            <el-table-column
              prop="title"
              label="工单主题"
              align="center"
              show-overflow-tooltip>
            </el-table-column>
2.2 slot-scope=scope 属性
slot-scope的出现实现了父组件调用子组件内部的数据,
子组件的数据通过slot-scope属性传递到了父组件
  • 插槽(slot)就是要将父组件中的内容渲染到子组件中。
  • 就好像是在子组件中留了一个空的位置(就像小霸王上的插卡口),
  • 然后把父组件中的内容插进去(你的游戏卡盘)。
2.2 v-if属性

提到v-if不得不说v-show, 我们先讲一下具体在什么场景下用到这两个属性:

例如,我们要有一个下拉标签,然后两个标签对应不同的数据,点哪个按钮显示哪个后端数据,这时就要用到v-if 和v-show,具体来看

在这里插入图片描述

在这里插入图片描述

具体案例:

1.我们在定义select下拉标签中,用v-model进行数据的双向绑定,并赋值value=1位已申请,2为草稿

在这里插入图片描述

2.我们在定义表格属性时,添加上 v-if="form.sheetType==‘1’ 对其进行默认展示已申请的内容

3.我们在展示草稿的时候表格格式可能回合已申请的表格格式不一致,因为我们如果在另定义又一个表格的时候需要加上

v-if="form.sheetType=='2’

4.我们在select标签中 加上@change改变事件,就可以进行随意切换啦

在这里插入图片描述

这样我们就可以做到点击不同的下拉选项然后进行不同的数据显示啦

总结:(重点): v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

2.3 .分页查询
<template>
......		//  表格
		<el-table
            :data="tableData"
             .........>
        </el-table>
		 <el-table
            :data="draftTableData"
             .........>
		  </el-table>
		//分页对象      el-pagination  分页组件
          <el-pagination
            @size-change="sizeChangeHandle"
            @current-change="handleCurrentChange"
            background
            layout="total, sizes, prev, pager, next, jumper"
            :current-page.sync="pageIndex"
            :page-sizes="[10, 20, 50, 100]"
            :page-size="pageSize"
            :total="totalPage"
          >
          </el-pagination>

</template>

<script>

//  多组件时会用到 export default 
export default {
    data(){
    return{
      tableData: [],
      draftTableData[],
        // 分页当前页
      pageIndex: 1,
      // 每页的条数
      pageSize: 10,
      // 分页总条目数
      totalPage: 0,
        ......
	}
   },
    // 定义个函数,返回要查询的json
created: function () {
    this.getDataList()
  }, 

  methods: {
    getDataList() {
      this.$http({
        url: 					// 因为有不用的点击访问不同的数据库,因此使用三目运算符,进行不同的url请求	this.$http.orderUrl(this.form.sheetType=='1'?"/audit/workOrderPool/getIndividualApplicationPoolList":"/audit/workOrderPool/getDraftPoolList"),
        method: "post",
        params: {
          page: this.pageIndex,
          rows: this.pageSize,
          title: this.form.title
        }
      }).then(({ data }) => {
        console.log(data)
          //  当状态码为0的话,正常显示页面,显示分页
          if (data.code === 0) {
              // v-if属性 sheettype=1时,显示已申请的数据
          if(this.form.sheetType=='1'){
            this.tableData = data.data.list;
            }else{		//  否则  则显示草稿的内容
              this.draftTableData = data.data.list;
            }		// 返回分页
            this.totalPage = data.data.total;
        }else if(this.form.sheetType=='2'){
          this.$message.error(data.msg)
        }
      });
    },
        // 点击分页页码
    handleCurrentChange(val){
      this.pageIndex = val;
      this.getDataList()
    },
    // 翻页
    sizeChangeHandle(val) {
      this.pageSize = val;
      this.pageIndex = 1;
      this.getDataList()
    }
        // table 点击详情	这个是我们刚才讲到的插槽插进来的内容,然后跳转的功能 与<template>标签中@clik绑定
    tableDetail(row){
      window.open("/idc/orderManagement/auditDetail?participantConfId="+row.participantConfId);
    }
</script>

分页查询主要代码就是这些,然后我们在学习一个vue的导出功能

2.4 导出
<template>
	<div class=".."> 
        <div class="..">
            <el-form ref="form" :model="form">
                .....表头...工单主题/工单编号等...
                //  1. 定义一个按钮,添加绑定事件
          <el-button type="info" @click="exportExcel" icon="el-icon-download">导出</el-button>
    		</el-form>
	<el-table>
         .....省略
    <el-table>
</template>      
<script>
    //  从文件中导入
import FileSaver from "file-saver";
import XLSX from "xlsx";

export default {
     data () {
    return {	
    		.....
   		 }
     }
    methods{
    .....上面其他方法省略
    //导出文件的方法
      exportExcel() {
       if(this.form.sheetType=='1'){
          var name = "个人申请-已申请列表" ;
           var aoa = [
             [
              "工单编号",
              "工单主题",
              "当前环节",
              "当前环节处理人",
              "申请人",
              "申请时间",
              "上一环节处理时间",
              "上一环节处理人"
             ]
           ];
           // 格式化json对象属性顺序
           var temp = [];
           this.tableData.forEach(item => {
              temp = [];
              temp[0] = item.soOrderCode;
              temp[1] = item.title;
              temp[2] = item.activityName;
              temp[3] = item.participantName;
              temp[4] = item.applyUserName;
              temp[5] = item.auditStartTime;
              temp[6] = item.lastActivityDealTime;
              temp[7] = item.lastParticipantNames;
             aoa.push(temp);
           });
           //将二维数组封装成sheet并转换成workbook对象
           var sheet = XLSX.utils.aoa_to_sheet(aoa);
           sheet["!cols"] = [
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
              { wch: 30 },
            ];
       }else{
         var name = "个人申请-草稿列表" ;
          var aoa = [
            [
             "工单编号",
             "工单主题",
             "任务描述"
            ]
          ];
          // 格式化json对象属性顺序
          var temp = [];
          this.draftTableData.forEach(item => {
             temp = [];
             temp[0] = item.soOrderCode;
             temp[1] = item.title;
             temp[2] = item.remark;
             aoa.push(temp);
          });
          //将二维数组封装成sheet并转换成workbook对象
          var sheet = XLSX.utils.aoa_to_sheet(aoa);
          sheet["!cols"] = [
             { wch: 30 },
             { wch: 30 },
             { wch: 30 },
           ];
       }

        var wb = {
          SheetNames: [name],
          Sheets: {}
        };
        wb.Sheets[name] = sheet;
        // 生成excel的配置项
        var wbout = XLSX.write(wb, {
          bookType: "xlsx", // 要生成的文件类型
          bookSST: true, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
          type: "array"
        });
        try {
          //  name+'.xlsx'表示导出的excel表格名字
          FileSaver.saveAs(new Blob([wbout], { type: "application/octet-stream" }),name + ".xlsx");
        } catch (e) {
          if (typeof console !== "undefined") {
            console.log(e, wbout);
            return false;
          }
        }
     
}
</script>

来看一看我们今天学习完分页查询以后想要的效果图把

在这里插入图片描述

3 async/awite

async/ await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await 已经被标准化,是时候学习一下了。

我们直接用案例来进行看

<template>
			// 给我们的form表单加上ref用来获取dom树   :model  rules 用于验证表单规则
		<el-form  ref="addUserRuleForm"   :model="addUserForm" :rules="rules"  ....>           
            <el-form-item label="用户名" prop="username">
                		//将用户名检验双向绑定至form表单验证上
                <el-input v-model="addUserForm.username">
    			</el-input>
        	</el-form-item>
            		......省略重复代码
 		</form>
		    //  我们给按钮添加绑定事件
	<el-button type="primary" @click="addUserBtn">确 定</el-button>
</template>
<script>
     export default {
         data(){
             ..
             return{
              	rules:{
                     ...这里添加表单验证规则
                 }
                 .....其他代码省略
             }
         }
          methods: {
         	//  根据绑定事件编写具体添加的代码
              addUserBtn(){
        // 对整个表单进行重新校验  $refs用来操作dom树 	 validate方法:表单校验方法,此方法返回的调用函数callback(valid),可以使用箭头函数获取valid值并且使用
        this.$refs.addUserRuleForm.validate(async  valid =>{
          if(!valid) return this.$message.error("请正确填写")

          // 发起ajax请求实现用户增加操作   {data: result} 用于缓存await接收到的数据,与asyns形成异步操作
      const  {data: result} = await  this.$http.post('/user/addUser',this.addUserForm)
          if(result.status !== 200) return this.$message.error("新增用户失败")
          this.$message.success("新增用户成功")
          // 关闭对话框
          this.addUserdialogVisible=false
          // 重新刷新页面
          this.getUserList()
        })
        }
          }         
     }  
</script>

在这里插入图片描述

在这里插入图片描述

小总结, 我们如果异步请求的话,使用sonst 进行接收后端传入的数据,然后进行判断比较

如果不使用await异步的话,那可以使用 .then((data)=>{ })里的data是指接口成功返回的数据,包含请求头,请求体,等信息;

这里的then()方法有两个参数,第一个是成功时的回调方法,默认给这个方法传递了成功的数据,另一个是失败的方法,以及失败的数据,第二个可选,(在.then里面我们会进行一些业务逻辑的判断,例如code判断,在.catch我们可能会进行一些已取消等的操作)

<script>
new Promise((resolve, reject) =>{
    setTimeout(() =>{
        //成功的时候调用resolve
        resolve('成功data')
        //失败的时候调用reject
        reject('error message')
    }, 1000)
}).then((data) =>{
    //处理成功后的逻辑
    console.log(data);//这个data 是接收的resolve参数--
}).catch((err) =>{
    console.log(err);
})
</script>

4.学会vue,走遍天下都不怕

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值