guns常用功能整理

guns常用功能整理

guns常用功能整理

一、ajax接口请求(常用)

1.1:引入插件库
import axios from 'axios';
1.2:调用即可
axios({

​    url: 接口路径,

​    method: 请求方式,

   }).then(回调方法)

> 或者

 fetch(路径, {

​    method: 请求方法

   })

​ .then(回调)

二、es6模块调用

import { 方法名 } from 调用路径;

2.1:当前文件下使用
function debounce(){

// axios

}

export default{

debounce,

}
2.2:封装的代码暴露出去

三、创建template模板

3.1:html节点创建模板
<template #examine="{record }">

​      <a-space>

​              <a @click="examine(record.fileName)">查看</a>

​      </a-space>

​     </template>
3.2:常用于表格元素增加slots

slots: { customRender: ‘examine’ }

四、封装文件上传代码

4.1:利用es6导入导出原理,新建一个js文件
>static async blobDownload(url, params,filename) {

  if (params === undefined) {

   params = {};

  }

  if(filename === undefined){

   filename = '导出文件.xlsx'

  }

  const form = params

  axios({ // 用axios发送post请求

   method: 'post',

   url: url,

   data: form,

   responseType: 'blob' // 表明返回服务器返回的数据类型

  }).then((res) => { // 处理返回的文件流

​    const content = res.data

​    const blob = new Blob([content])

​    if ('download' in document.createElement('a')) { // 非IE下载

​     const elink = document.createElement('a')

​     elink.download = filename

​     elink.style.display = 'none'

​     elink.href = URL.createObjectURL(blob)

​     document.body.appendChild(elink)

​     elink.click()

​     URL.revokeObjectURL(elink.href) // 释放URL 对象

​     document.body.removeChild(elink)

​    } else { // IE10+下载

​     navigator.msSaveBlob(blob, filename)

​    }

​    return true

   })

 }
4.2:可以再次将接口调用代码进行封装,这样代码会更加简洁清晰
>static export(params,obj,name) {

  return Request.blobDownload('/ai-plus/bank/flow/task/result/excel?taskId='+params,obj,name);

 }
4.3:调用方法
export(record.jobId, record.jobName)

记住方法一定要导出才能够调用

五、图片的放大缩小以及移动切换

5.1:实现拖拽,主要是获取它当前的位置
let oImg = e.target;
      let disX = e.clientX - oImg.offsetLeft;
      let disY = e.clientY - oImg.offsetTop;
      document.onmousemove = e => {
        e.preventDefault();
        let left = e.clientX - disX;
        let top = e.clientY - disY;
        document.querySelector('.moveImage').style.left = left + 'px';
        document.querySelector('.moveImage').style.top = top + 'px';
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
5.2:图片放大也是通过当前位置以及它的长宽来进行处理
let nowScrollTop = document.getElementById('masks').scrollTop;
      let nowScrollLeft = document.getElementById('masks').scrollLeft;
      if (nowScrollTop - (offsetY - pdfObj.imgOffsetY) >= 0) {
        document.getElementById('masks').scrollTop = nowScrollTop - (offsetY - pdfObj.imgOffsetY);
      }
      if (nowScrollLeft - (offsetX - pdfObj.imgOffsetX) >= 0) {
        document.getElementById('masks').scrollLeft = nowScrollLeft - (offsetX - pdfObj.imgOffsetX);
      }
5.3:图片的切换主要通过获取数组对应的下标以及其他信息
if (this.mainImgUrl.indexOf(imgUrl) !== -1) {
        let index = this.mainImgUrl.indexOf(imgUrl);
        this.mianImage(this.showMainImgUrl[index - 1], index - 1);
      } else {
        let index = this.detailImgUrl.indexOf(imgUrl);
        this.detailImage(this.showDetailImgUrl[index - 1], index - 1);
      }

具体可参照ai+后台管理系统sku文件

六、websocket长连接

6.1:获取长连接地址并继承
 websocket = new WebSocket('ws://172.168.30.5:8089/biSocket/1513721148340064257');
6.2:接着在websocket自带的方法体里面进行数据的回调以及错误判断
websocket.onopen = function () {
        console.log('连接已经建立');
      };
      websocket.onmessage = function (e) {
        getMessage(e);
      };
      websocket.onerror = function () {
        netWorkOutAge.value = true;
        console.log('发生错误');
        console.log('onerror发送成功');
        heartCheck.start();
      };
      websocket.onclose = function (e) {
        console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean);
        netWorkOutAge.value = true;
        document.querySelector('.main').setAttribute('style', 'opacity:0.4');
        console.log('onclose发送成功');
        //断开网络后连接网络刷新请求
        console.log('断开连接后发送成功');
        //连接关闭启动定时任务 五秒后在创建
        heartCheck.start();
      };
6.3:值得注意的点是,长连接需要保持一直通信,所以前端要不断发请求,类似于心跳机制,保证前后端连接不断开
//定时器 只执行一次的那种 只是为了限制重连频率 = =
    let heartCheck = {
      timeout: 5000, //重连时间
      timeoutObj: null,
      start: function () {
        this.timeoutObj = setTimeout(function () {
          websocket.send("{'messageType': 'ROBOT_CURRENT_JOB_ACK'}");
          getSocket(); //重新创建 websocket 对象并赋值
        }, this.timeout);
      }
    };

保证不断开的原理就是设置定时器,具体可看mro-bi-fronted这个项目代码

七、右侧固定导航栏

7.1:下载tocbot插件并且引用
import * as tocbot from 'tocbot';
7.2:直接初始化
tocbot.init({
                tocSelector: '.allTitles',
                contentSelector: '.content_left',
                ignoreSelector: 'js-toc-ignore',
                headingSelector: 'h1',
                scrollSmooth: true,
                hasInnerContainers: false,
                headingsOffset: 80,
                scrollSmoothOffset: true,
                fixedSidebarOffset: 'auto',
                scrollEndCallback: function() {
                  window.tocPhase = null;
                },
                onclick: function() {
                  window.tocPhase = true;
                }
              });

注意一定要注意它的执行栈的执行顺序,在异步中使用该方法

https://blog.csdn.net/cune1359/article/details/106844182

官方文档

八、文字高亮

文字高亮不仅后端可以处理,前端也可以处理

8.1:es6封装高亮代码
export function highLightTableMsg(msg, highLightStr) {
    if (msg == null) {
        msg = ''
    }
    if (highLightStr == null) {
      highLightStr = ''
    }
    if (msg instanceof Object) {
      msg = JSON.stringify(msg)
    }
    if (highLightStr instanceof Object) {
      highLightStr = JSON.stringify(highLightStr)
    }
    if (!(msg instanceof String)) {
      msg = msg.toString()
    }
    if (!(highLightStr instanceof String)) {
      highLightStr = highLightStr.toString()
    }
    var htmlStr = ''
    if (highLightStr.length > 0) {
      if (msg.indexOf(highLightStr) !== -1) {
        assemblyStr(msg, highLightStr)
      } else {
        htmlStr = '<span>' + msg + '</span>'
      }
    } else {
      htmlStr = '<span>' + msg + '</span>'
    }
    function assemblyStr(msgAssembly, highLightAssembly) {
      if (msgAssembly.indexOf(highLightAssembly) !== -1) {
        var length = highLightAssembly.length
        var start = msgAssembly.indexOf(highLightAssembly)
        htmlStr = htmlStr + '<span>' + msgAssembly.substring(0, start) + '</span>' + '<span class="log-hight-light" style="color:#C92B2F">' + highLightAssembly + '</span>'
        msgAssembly = msgAssembly.substring(start + length, msgAssembly.length)
        assemblyStr(msgAssembly, highLightAssembly)
      } else {
        htmlStr = htmlStr + '<span>' + msgAssembly + '</span>'
      }
    }
    return htmlStr
  }
8.2:调用执行即可
import { highLightTableMsg } from '../../utils/highLight';
highLightTableMsg(val, searchValue); //查询结果标红

两个参数分别对应标题和文本

九、输入框防抖

9.1:下载lodash-es插件

import { debounce } from ‘lodash-es’;

9.2:以下为防抖代码
//防抖防止多次调用
    const filterOption = debounce(async value => {
      let allDataValue = await axios.get(`store/mall/list?storeName=${value}`);
      if (allDataValue.data.code === '00000') {
        if (allDataValue.data.data.length > 0) {
          allDataValue.data.data.forEach(() => {
            dataValue.value = allDataValue.data.data.map(element => ({
              value: element.storeName,
              storeId: element.storeId
            }));
          });
          storeArr.push(...allDataValue.data.data)
          fetch.value = true;
        } else {
          fetch.value = false;
        }
      }
    }, 300);
9.3:运用到当前的输入框组件当中
<a-select
          show-search
          placeholder="请输入店铺名称"
          style="width: 300px"
          :default-active-first-option="false"
          :show-arrow="false"
          :not-found-content="fetch ? undefined : '搜索内容不存在'"
          @search="filterOption"
          :getPopupContainer="
            triggerNode => {
              return triggerNode.parentNode || document.body;
            }
          "
          :options="dataValue"
          @change="handleChange"
        >
          <template v-if="fetch" #notFoundContent>
            <a-spin size="small"></a-spin>
          </template>
        </a-select>

10、table组件常用

10.1:数据表格table https://www.antdv.com/components/table/#Table官方文档
10.2:组件常用
<ele-pro-table
          ref="table"
          row-key="brandId"
          :datasource="url"
          :columns="columns"
          :where="where"
          @change="tablaChange"
          v-model:selection="selection"
          :scroll="{ x: 'max-content' }"
        >
        </ele-pro-table>

组件自带的有分页,请求地址,还有页码点击的事件

比如说@change事件就代表获取当前页数
tablaChange(pagination) {
      this.pageNo = pagination.current;
    }
10.3:表头设置
const columns = [
      {
        title: '商城订单编号',
        dataIndex: 'ordersSn'
      },
      {
        title: 'orderId',
        dataIndex: 'omsSn'
      },
      {
        title: 'OMS推送状态',
        dataIndex: 'omsCreateStatus',
        customRender: record => {
          return record.record.omsCreateStatus == 1 ? '推送成功' : '推送失败';
        }
      },
      {
        title: '下单企业名称',
        dataIndex: 'companyName'
      },
      {
        title: '下单用户名称',
        dataIndex: 'memberName'
      },
      {
        title: '用户联系电话',
        dataIndex: 'memberMobile'
      },
      {
        title: '商城订单状态',
        dataIndex: 'ordersStateName'
      },
      {
        title: '订单金额',
        dataIndex: 'ordersAmount'
      },
      
      {
        title: '支付方式',
        dataIndex: 'payment',
        customRender: record => {
          return record.text == 0 ? '在线支付' : record.text == 1 ? '线下支付' : '账期支付';
        }
      },
      {
        title: '下单时间',
        dataIndex: 'createTime',
        // customRender: ({ item }) => moment(item).format('YYYY-MM-DD:HH:MM:SS')
      },
      {
        title: '操作',
        key: 'action',
        width: 150,
        align: 'center',
        slots: { customRender: 'action' }
      }
    ];
10.4:表格内容体里面要设置动态的数据或者是是否可操作可以使用插槽的方式
在当前表头设置
customRender: record => {
          return record.text == 0 ? '在线支付' : record.text == 1 ? '线下支付' : '账期支付';
        }
其次就可以生成模板在文本当中
<!-- table操作栏按钮 -->
          <template #action="{ record }">
            <a-space>
              <a @click="openEdit(record)">详情</a>
              <a-divider type="vertical" />
              <a-popconfirm
                v-if="record.omsCreateStatus !== 1"
                title="是否确定要重新推送"
                ok-text="是"
                cancel-text="否"
                @confirm="confirm(record.ordersId)"
                @cancel="cancel"
              >
                <a href="#">重新推送</a>
              </a-popconfirm>
            </a-space>
          </template>

提示:局部刷新表格可以通过ajax请求的原理,增加一个loading框让用户以为是在刷新界面

11、弹出层

弹出层主要是父与子之间的通信,利用父传子的原理

11.1:将需要设为弹窗的组件置于父组件当中
调用子组件
import { BrandApi } from '@/api/BrandApi';
生成模板即可
<!-- 编辑弹窗 -->
  <brand-edit v-model:visible="showEdit" :data="current" @done="reload" />

可以看出,‘ :’是父组件传给子组件的值;‘@’是传递的一种方法回调

11.2:子组件接收参数
emits: ['done', 'update:visible'],
  inject: ['reload'],
  props: {
    // 弹窗是否打开
    visible: Boolean,
    // 修改回显的数据
    data: Object
  },

不了解的小伙伴可以看看这篇博客

http://events.jianshu.io/p/be840cc0fa6a

11.3:子组件当中多为输入框回显以及下拉框的形式

一般来说,会先都是通过v-model双向绑定来实现的

其次,回显得注意那些为必填非必填的情况

// 表单验证规则
     const rules = {
        showImage: [{ required: true, message: '请输入品牌图片', type: 'string', trigger: 'blur' }],
        brandName: [{ required: true, message: '请输入品牌名称', type: 'string', trigger: 'blur' }],
        registerNumber: [{ required: true, message: '请输入商标注册号', type: 'string', trigger: 'blur' }]
      },

常见的坑

一、下拉框脱离文本

在根节点添加这个方法即可
:getPopupContainer="
                (triggerNode) => {
                return triggerNode.parentNode || document.body
                }"

二、在guns系统当中路由跳转数据不更新,watch和computed都不管用?

直接使用unUpdated生命周期即可

三、在使用长连接或者其他需要使用到setInterval或者setTimeout时处理完毕时一定要终止它,否则长时间不处理会导致内存溢出,界面卡死

说明

我们系统主要是用vue3.x加上ant-design插件库为了方便代码维护

vue3.x

https://cn.vuejs.org/

ant-design

https://www.antdv.com/components/overview

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
具体详情 https://gitee.com/wuburen/guns #Guns V2.1 新版Guns基于SpringBoot全面升级,完美整合springmvc + shiro + mybatis-plus + beetl! 在不用写xml配置(V1.0)的基础上进一步简化项目配置,让您更专注于业务开发!抛弃传统spring xml的配置方式,利用springboot + javabean方式配置spring,极大简化了pom.xml配置和spring配置. Guns项目代码简洁,注释丰富,上手容易,同时Guns包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块),可以直接作为一个后台管理系统的脚手架. 如果您不喜欢用SpringBoot,或者您是一个spring初学者,您可以切换到Guns V1.0(点击这里)分支, Guns V1.0基于spring的java bean方式配置项目,同样简洁易上手. 注:SpringBoot强大的Auto Config和统一的依赖管理极大的简化了spring配置和maven依赖,在不了解其都配置了哪些东西的基础上可能会对初学者有一定困扰,所以建议初学者先看Guns V1.0 ##功能 简介 用户管理 角色管理 部门管理 菜单管理 字典管理 业务日志 登录日志 监控管理 通知管理 代码生成 ##使用说明 导入sql/guns.sql文件到mysql数据库 以maven方式导入项目到ide 修改application.yml中的数据库相关的配置,改为您本机的数据库配置 启动项目,管理员账号admin/密码111111 ###如何启动项目 Guns目前支持三种启动方式: 在IDE里运行GunsApplication类中的main方法启动 执行如下maven命令 clean package -Dmaven.test.skip=true 并从target目录中找到guns-1.0.0-SNAPSHOT.jar,并在jar包的目录下执行如下java命令 java -jar guns-1.0.0-SNAPSHOT.jar 修改pom.xml中如下片段 <packaging>jar</packaging> 改为 <packaging>war</packaging> 并打包放入到tomcat中执行 ##所用框架 ###前端 Bootstrap v3.3.6 jQuery v2.1.4 bootstrap-table v1.9.0 layer v2.1 zTree core v3.5.28 WebUploader 0.1.5 ###后端 SpringBoot 1.5.3.RELEASE MyBatis-Plus 2.0.8 MyBatis 3.4.4 Spring 4.3.8.RELEASE Beetl 2.7.15 hibernate-validator 5.3.5.Final Ehcache 3.3.1 Kaptcha 2.3.2 Fastjson 1.2.31 Shiro 1.4.0 Druid 1.0.31 ##项目包结构说明 ├─main │ │ │ ├─java │ │ │ │ │ ├─com.stylefeng.guns----------------项目主代码 │ │ │ │ │ │ │ ├─common----------------项目公用的部分(业务中经常调用的类,例如常量,异常,实体,注解,分页类,节点类) │ │ │ │ │ │ │ ├─config----------------项目配置代码(例如mybtais-plus配置,ehcache配置等) │ │ │ │ │ │ │ ├─core----------------项目运行的核心依靠(例如aop日志记录,拦截器,监听器,guns模板引擎,shiro权限检查等) │ │ │ │ │ │ │ ├─modular----------------项目业务代码 │ │ │ │ │ │ │ ├─GunsApplication类----------------以main方法启动springboot的类 │ │ │ │ │ │ │ └─GunsServletInitializer类----------------用servlet容器启动springboot的核心类 │ │ │ │ │ └─generator----------------mybatis-plus Entity生成器 │ │ │ ├─resources----------------项目资源文件 │ │ │ │ │ ├─gunsTemplate----------------guns代码生成模板 │ │ │ │ │ ├─application.yml----------------springboot项目配置 │ │ │ │ │ ├─ehcache.xml----------------ehcache缓存配置 │ │ │ └─webapp----------------web页面和静态资源存放的目录 │ 注:SpringBoot项目默认不支持将静态资源和模板(web页面)放到webapp目录,但是个人感觉resources目录只放项目的配置更加简洁,所以就将web页面继续放到webapp目录了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值