工作常用的样式和方法(正则表达)

1,249 阅读8分钟

一、 css样式

1、划线价格

. 利用text-decoration来实现

text-decoration: line-through red; /*红色中划线*/

属性释义
none默认。定义标准的文本。
underline定义文本下的一条线。 ͟h͟e͟l͟l͟o͟
overline定义文本上的一条线。
line-through定义穿过文本的一条线(划线价格使用这个) ̶h̶e̶l̶l̶o̶
blink定义闪烁的文本
inherit规定应该从父元素继承 text-decoration 属性的值

2.less、sass、stylus 区别和变量使用

他们都是css的预处理语言,将css赋予了动态语言的特性,如:变量、继承、运算、函数。但是被浏览器直接识别不了,所以要用工具来编译(命令行工具、gulp、webpack、考拉less现在不用了的)

3、小程序背景和uniapp背景

小程序背景写在page,不影响滚动。

uniapp写在最外面的盒子给了背景不给高度,在一些留白很多的页面就无法全部展示,如果写了100vh就无法滚动

小程序

page{
 background:#ccc;
}

uniapp

page{
background:#ccc;
width100vw;
height:100vh;
position:fixed;
z-index:-1;
}

4、小程序radio、checkbox、input、textarea默认样式修改。

checkbox 圆形,不点击是灰色的框,填充是亮红色。#FE2C55


/*checkbox 选项框大小 */
checkbox .wx-checkbox-input {
 width: 34rpx;
 height: 34rpx;
 border-radius: 50%;
 border: none;
 border: 1rpx solid #ccc;
}

/*checkbox选中后样式 */
checkbox .wx-checkbox-input.wx-checkbox-input-checked {
 background: #FE2C55;
}

/*checkbox选中后图标样式 */
checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
 width: 28rpx;
 height: 28rpx;
 line-height: 28rpx;
 text-align: center;
 font-size: 22rpx;
 color: #fff;
 background: transparent;
 transform: translate(-50%, -50%) scale(1);
 -webkit-transform: translate(-50%, -50%) scale(1);
}

radio 圆形,不点击是灰色的框,填充是亮红色。#FE2C55


radio .wx-radio-input { 
 border-radius: 50%; 
 width: 20px;
 height: 20px; 
}

radio .wx-radio-input.wx-radio-input-checked { 
 border-color: #F0302F !important; 
 background: #F0302F !important; 
}

radio .wx-radio-input.wx-radio-input-checked::before { 
 border-radius: 50%; 
 width: 20px; 
 height: 20px; 
 line-height: 20px; 
 text-align: center; 
 font-size: 15px; 
 color: #fff; 
 background: transparent; 
 transform: translate(-50%, -50%) scale(1); 
 -webkit-transform: translate(-50%, -50%) scale(1);

}

input 修改placeholder的样式

placeholder-style="color:#AAAAAA;"

或者

 input::-webkit-input-placeholder {
     /* placeholder颜色  */
     color: #ff0000;
     /* placeholder字号  */
     font-size: 0.14rem;
   }
   input::-moz-placeholder {
     /* Mozilla Firefox 19+ */
     color: #ff0000;
     font-size: 0.14rem;
   }
   input:-moz-placeholder {
     /* Mozilla Firefox 4 to 18 */
     color: #ff0000;
     font-size: 0.14rem;
   }
   input:-ms-input-placeholder {
     /* Internet Explorer 10-11 */
     color: #ff0000;
     font-size: 0.14rem;
   }

textarea 修改placeholder的样式

textarea::-webkit-input-placeholder {
 /* WebKit browsers */
 /* placeholder颜色  */
 color: #ff0000;
 /* placeholder字号  */
 font-size: 0.14rem;
}
textarea:-moz-placeholder {
 /* Mozilla Firefox 4 to 18 */
 color: #ff0000;
 font-size: 0.14rem;
}
textarea::-moz-placeholder {
 /* Mozilla Firefox 19+ */
 color: #ff0000;
 font-size: 0.14rem;
}
textarea::-ms-input-placeholder {
 /* Internet Explorer 10+ */
 color: #ff0000;
 font-size: 0.14rem;
} 

5、小程序多行省略

小程序直接在css就可以设置。

 word-break: break-all;
 text-overflow: ellipsis;
 display: -webkit-box;
 -webkit-box-orient: vertical;
 -webkit-line-clamp: 2;//这个就是行数
 overflow: hidden;

6、flex和grid详解

7、px,repx单位区别

8、命名方式

(1)大驼峰 SingleLady 两个单词第一个字母都大写 类名用这个

(2)小驼峰 singleLady 第一个单词的首字母小写 方法名、参数名、成员变量、局部变量

(3)蛇形命名 single_lady 用 “_” 连接 测试方法名、常量、枚举名称

(4)串式命名 single-lady 用 “—” 连接 文件名字

二、方法

1.正则表达式校验

正则表达生成器 www.w3cschool.cn/tools/index…

教程:www.runoob.com/regexp/rege…

使用:正则表达式.test(检测值)

a、 校验非0正整数(价格单位为分的校验)

可以输入0

/(^[1-9]\d*$)/   

不能输入0

/^0*/g    

b、 校验非0数包括小数(适合价格校验,小数不超过两位)

/^(([1-9][0-9]*)|(([0].\d{1,2}|[1-9][0-9]*.\d{1,2})))$/

c、替换输入的emoji(小程序输入商品名字替换表情)

replace(/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi , "")

c、手机号校验

这个校验不包含11 、12、16、开头的需要自己加。

/^((13[0-9])|(14[0-9])|(15([0-9]))|(18[0-9])|(17[0-9])|(19[0-9]))\d{8}$/

2、vue2-input直接校验是否输入正整数、前后去除空格

input直接校验是否输入正整数。

 @input="(val)=>{establishData.stockNum = val.replace(/[^\d]/g,'')}" 

input前后去除空格 v-model.trim

<el-input v-model.trim="establishData.stockNum "  @input="(val)=>{establishData.stockNum = val.replace(/[^\d]/g,'')}"  type="number" autocomplete="off"
          placeholder="请输入库存总数"
          style="width: 80px">
</el-input>份

vue2里面v-model有内置修饰符

修饰符释义
.trim去除前后空格
.number将值处理成number类型,并不影响你输入汉字
.lazy让值在change时更新而不是input
自定义v2.cn.vuejs.org/v2/guide/co…

装饰器是将vue2的一些方法改写,method等,为了配合使用ts。

3、时间获取

创建date对象new Date()

方法释义
getDay()
getFullYear()
getMonth()月,要加一,少一个月
getDate()
getHours()
getMinutes()
getSeconds()
getMilliseconds()毫秒
getTime()把时间格式转换成毫秒
toLocaleDateString()把date对象日期部分转成2025/5/27
toLocaleTimeString()把date对象时间部分转成 15:14:55
toLocaleString()把date对象转成 2025/5/27 15:16:09
toString()Tue May 27 2025 15:16:54 GMT+0800 (中国标准时间)
toTimeString()15:17:23 GMT+0800 (中国标准时间)
toDateString()Tue May 27 2025
toJSON()2025-05-27T07:17:57.481Z

获取上个月的第一天和最后一天

function getFirstDay() {
   //当前月第一天
    var y = new Date().getFullYear(); //获取年份
    var m = new Date().getMonth() + 1; //获取月份
    var d = "01";
    m = m < 10 ? "0" + m : m; //月份补 0
    return [y, m, d].join("-");
	}
 
	function getLastDay() {
		//当前月最后一天
		var y = new Date().getFullYear(); //获取年份
		var m = new Date().getMonth() + 1; //获取月份
		var d = new Date(y, m, 0).getDate(); //获取当月最后一日
		m = m < 10 ? "0" + m : m; //月份补 0
		d = d < 10 ? "0" + d : d; //日数补 0
 
		return [y, m, d].join("-");
	}
 
	function getLastMonthFirstDay() {
    date = new Date();
    date.setDate(0);
    var y = date.getFullYear(); //获取年份
    var m = date.getMonth() + 1; //获取月份
	m = m < 10 ? "0" + m : m; //月份补 0
    return [y, m, '01'].join("-");
	}
 
	function getLastMonthLastDay() {
		date = new Date();
		date.setDate(0);
		var y = date.getFullYear(); //获取年份
		var m = date.getMonth() + 1; //获取月份
		var d = new Date(y, m, 0).getDate(); //获取当月最后一日
		m = m < 10 ? "0" + m : m; //月份补 0
		d = d < 10 ? "0" + d : d; //日数补 0
		return [y, m, d].join("-");
	} 
        

获取本周、上周的第一天和最后一天。

本周

export function getThisWeekData() {//获得本周周一~周日的年月日  
  var thisweek = {};
  var date = new Date();
  // 本周一的日期
  date.setDate(date.getDate() - date.getDay() + 1);
  thisweek.start_day = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() ;

  // 本周日的日期
  date.setDate(date.getDate() + 6);
  thisweek.end_day = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
  return thisweek
} 

上周

export function getLastWeekData() {//获得上周周一~周日的年月日  
  var lastweek = {};
  var date = new Date();
  // 上周一的日期
  date.setDate(date.getDate()-7 - date.getDay() + 1);
  lastweek.start_day = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() ;

  // 上周日的日期
  date.setDate(date.getDate() +6);
  lastweek.end_day = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
  return lastweek
}  

4.防抖节流

/*函数节流*/
 throttle(fn, interval) {
  var enterTime = 0;//触发的时间
  var gapTime = interval || 300 ;//间隔时间,如果interval不传,则默认300ms
  return function() {
    var context = this;
    var backTime = new Date();//第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(context,arguments);
      enterTime = backTime;//赋值给第一次触发的时间,这样就保存了第二次触发的时间
    }
  };
}, 
/*函数防抖*/
 debounce(fn, interval) {
  var timer;
  var gapTime = interval || 1000;//间隔时间,如果interval不传,则默认1000ms
  return function() {
    clearTimeout(timer);
    var context = this;
    var args = arguments;//保存此处的arguments,因为setTimeout是全局的,arguments不是防抖函数需要的。
    timer = setTimeout(function() {
      fn.call(context,args);
    }, gapTime);
  }
}


//用法

 breakUp: util.throttle(function(msg){
    函数内容
  },10000),   

5、vue2 el-date-picker 时间限制

<el-form-item label="活动时间" prop="time1">
  <el-date-picker v-model="establishData.time1" type="daterange" :clearable="false" align="right"
                  range-separator="至" start-placeholder="活动开始时间" end-placeholder="活动结束时间"
                  :picker-options="pickerOptions"
                  value-format="yyyy-MM-dd"
                  format="yyyy-MM-dd">
  </el-date-picker>
</el-form-item>
pickerOptions: {
  disabledDate(time) {
    return time.getTime() < Date.now()- 1 * 24 * 60 * 60 * 1000
  }
},

三、 功能实现

1、小程序地图

1.使用地图和利用地图做过像链家一样得聚合和分开得效果,配合后端一起。

developers.weixin.qq.com/miniprogram…

我在项目进件助手里面使用到得

页面

  <!--  这一块才是地图  show-location-->
  <map class="class-map" id="myMap" latitude="{{latitude}}" longitude="{{longitude}}" bindmarkertap="markertap"
    bindcallouttap="calloutTap" bindregionchange="regionChange" markers="{{markers}}" scale="{{scale}}">
    <view slot="callout">
      <block wx:for="{{bubble}}" wx:key="*this">
        <cover-view class="customCallout" marker-id="{{item.mapid}}">
          <cover-view class="map-content">
          </cover-view>
        </cover-view>
      </block>
    </view>
  </map>
  
  
  
   

逻辑

 
Page({

  
  data: {
    // 地图
    mapbubble: false,
    longitude: '',
    latitude: '',
    scale: 16,
    bubble: [],
    mapCtx: null,
    markers: [],
    // 筛选地区
    address: '',
    newVisit: '',
    ajaxAddress: null,
    chooseSignedTips: false,
    closeAlert: false, 
    allLits: [], //最初的数据
    notSigned: false, //未签约
    signed: false, //已签约
    signedBD: false, //bd
    listInfo: [], //签约的店铺
    noList: [], //没签约的
    phone: null, //电话号码
    visit: null, //visit
    yan: true,
    level: 4,
    initlat: null,
    initlong: null,
    city: null
  },
  // 用省市区筛选信息
  areaFiltering() {
    request.authRequest({
      url: config.api.host + config.sever.MERCHANT_STANDALONE + config.api.aMap + config.api.districtQuery + '/' + this.data.city,
      method: 'GET'
    }).then(res => {
      let coordinate = res.districts[0].center.split(',')
      setTimeout(() => {
        this.setData({
          latitude: coordinate[1],
          longitude: coordinate[0],
          scale: 15
        })
      })

    })
    request.authRequest({
      url: config.api.host + config.sever.MERCHANT_STANDALONE + config.api.businessVisit + config.api.listInAreaByKeyWord + '/' + this.data.ajaxAddress,
      method: 'GET',
    }).then(res => {
      if (res.length == 0) {
        wx.showToast({
          title: '没有数据',
          icon: 'error'
        })
      } else {
        this.setData({
          allLits: res
        })
        // 数据格式
        let arr = []
        res.forEach((item, index) => {
          // 蓝色
          if (item.type == 0) {
            arr.push({
              id: index,
              latitude: item.latitude,
              longitude: item.longitude,
              iconPath: '/image/la-blue.png',
              alpha: 1,
              width: 10,
              height: 10,
              callout: {
                content: item.name,
                color: '#FFFFFF',
                fontSize: 12,
                bgColor: '#2F5AFF',
                padding: 6,
                borderRadius: 8,
                display: 'ALWAYS',
                textAlign: 'center'
              },
            })
            return
          } else {
            // 橙色
            arr.push({
              id: index,
              latitude: item.latitude,
              longitude: item.longitude,
              iconPath: '/image/la-blue.png',
              alpha: 1,
              width: 10,
              height: 10,
              callout: {
                content: item.name,
                color: '#FFFFFF',
                fontSize: 12,
                bgColor: '#F27326',
                padding: 6,
                borderRadius: 8,
                display: 'ALWAYS',
                textAlign: 'center'
              },
            })
          }

        })
        arr.push({
          id: 9999999,
          latitude: this.data.initlat,
          longitude: this.data.initlong,
          iconPath: '/image/zbzzz.png',
          zIndex: 9999,
          alpha: 1,
          width: 28,
          height: 28,
        })
        this.setData({
          markers: arr
        })
      }
    })
  },
  // 根据范围查询  
  coordinateQuery(e) {
    let longitude = e.detail.centerLocation.longitude
    let latitude = e.detail.centerLocation.latitude
    let _this = this
    let _level  = _this.getLevel(e)
    request.authRequest({
      url: config.api.host + config.sever.ELASTIC_STANDALONE + config.api.esBusinessVisitMerge + config.api.listByLevel,
      method: 'POST',
      data: {
        southwest: e.detail.region.southwest,
        northeast: e.detail.region.northeast,
        center: {
          longitude,
          latitude
        },
        level: _level
      }
    }).then(res => {
      if(res){
        let arr = []
        res.forEach((item, index) => {
          let _maker = {
            id: null,
            latitude: null,
            longitude: null,
            iconPath: '/image/la-blue.png',
            alpha: 1,
            width: 10,
            height: 10,
            callout: {
              content: '',
              color: '#FFFFFF',
              fontSize: 12,
              bgColor: '#2F5AFF',
              borderRadius: 8,
              padding: 6,
              display: 'ALWAYS',
              textAlign: 'center',
            },
          }
          _maker.id = index
          _maker.callout.content = item.name
          _maker.latitude = item.latitude
          _maker.longitude = item.longitude
          _maker.storeId = item.id
          if(_level==4){
            // 蓝色
            if(item.type==1){
              _maker.type = 1
            }else {
              // 橙色已签约
              _maker.iconPath = '/image/la-organe.png'
              _maker.callout.bgColor = '#F27326'
              _maker.type = 0
             
            }
          }else {
            // 粉色
            _maker.iconPath = '/image/la-organe.png'
            _maker.callout.bgColor = '#FF7971'
            _maker.type = 3
          }
          arr.push(_maker)
        })
        // 自己位置
        arr.push({
          id: 9999999,
          latitude: this.data.initlat,
          longitude: this.data.initlong,
          iconPath: '/image/zbzzz.png',
          zIndex: 9999,
          alpha: 1,
          width: 28,
          height: 28,
        })
        _this.setData({
          markers: arr,
          yan: true,
          allLits:res
        })
      }
    })
  },
  // 上面的地区筛选器
  pickerValue(e) {
    this.setData({
      address: e.detail.value[0] + e.detail.value[1] + e.detail.value[2],
      ajaxAddress: e.detail.value[1] + '&' + e.detail.value[2],
      city: e.detail.value[1]
    })
    this.areaFiltering()
  },
  // 获取当前经纬度
  getAddress() {
    let _this = this
    wx.getLocation({
      type: 'gcj02',
      success(res) {
        _this.setData({
          latitude: res.latitude,
          longitude: res.longitude,
          initlat: res.latitude,
          initlong: res.longitude
        })
      }
    })
  },
  // 缩放获取坐标
  regionChange(e) {
    let _this = this
    if(e.type=='end'){
      this.setData({
        yan: false
      })
      this.coordinateQuery(e)
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  getLevel(e){
    let _level = 4
    let _scale = e.detail.scale
    if (_scale > 14) {
      // 店
      _level = 4
    }
    // 街道
    if (_scale > 11 && _scale <= 14) {
      _level = 3
    }
    // 区
    if (_scale > 7 && _scale <= 11) {
      _level = 2
    }
    // 市
    if (_scale > 5 && _scale <= 7) {
      _level = 1
    }
    // 省
    if (_scale <= 5) {
      _level = 0
    }
    return _level
  },
  // getRegion() {
  //   let _this = this
  //   return new Promise((resolve, rejects) => {
  //     _this.mapCtx.getRegion({
  //       success(res) {
  //         let _level = 4
  //         _this.mapCtx.getScale({
  //           success(res2) {
  //             if (res2.scale > 14) {
  //               // 店
  //               _level = 4
  //               _this.setData({
  //                 level: 4
  //               })
  //             }
  //             // 街道
  //             if (res2.scale > 11 && res2.scale <= 14) {
  //               _level = 3
  //               _this.setData({
  //                 level: 3
  //               })
  //             }
  //             // 区
  //             if (res2.scale > 7 && res2.scale <= 11) {
  //               _level = 2
  //               _this.setData({
  //                 level: 2
  //               })
  //             }
  //             // 市
  //             if (res2.scale > 5 && res2.scale <= 7) {
  //               _level = 1
  //               _this.setData({
  //                 level: 1
  //               })
  //             }
  //             // 省
  //             if (res2.scale <= 5) {
  //               _level = 0
  //               _this.setData({
  //                 level: 0
  //               })
  //             }
  //             resolve({
  //               northeast: res.northeast,
  //               southwest: res.southwest,
  //               level: _level
  //             })
  //           }
  //         })
  //
  //       }
  //     })
  //   })
  // },
  onLoad: function (options) {
    let _this = this
    this.getAddress()
    this.data.markers.push({
      id: 9999999,
      latitude: this.data.initlat,
      longitude: this.data.initlong,
      iconPath: '/image/zbzzz.png',
      zIndex: 9999,
      alpha: 1,
      width: 40,
      height: 40,
    })
    this.setData({
      markers: this.data.markers
    })
    // 获取map创建对象
    this.mapCtx = wx.createMapContext('myMap')
  },

  // 点聚合
  // pointAggregation() {
  //   this.mapCtx.initMarkerCluster({
  //     // initMarkerCluster: 1000
  //   })
  //   this.mapCtx.addMarkers({
  //     markers: this.data.markers,
  //     clear: true,
  //     complete(res) {
  //     }
  //   })
  // },
  // 缩放倍率
  // getScale() {
  //   let _this = this
  //   _this.mapCtx.getScale({
  //     complete(res) {
  //       if (res.scale > 14) {
  //         // 店
  //         _this.setData({
  //           level: 4
  //         })
  //         return
  //       }
  //       // 街道
  //       if (res.scale > 11 && res.scale <= 14) {
  //         _this.setData({
  //           level: 3
  //         })
  //         return
  //       }
  //       // 区
  //       if (res.scale > 7 && res.scale <= 11) {
  //         _this.setData({
  //           level: 2
  //         })
  //         return
  //       }
  //       // 市
  //       if (res.scale > 5 && res.scale <= 7) {
  //         _this.setData({
  //           level: 1
  //         })
  //         return
  //       }
  //       // 省
  //       if (res.scale <= 5) {
  //         _this.setData({
  //           level: 0
  //         })
  //         return
  //       }
  //       _this.setData({
  //         scale: res.scale
  //       })
  //     }
  //   });
  // },
 
  
})

样式




/* 地图 */
.map {
  overflow: hidden;
  position: relative;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: 0;
}

.class-map {
  height: 100%;
  width: 100%;
}

/* 地图上面的气泡 */
.customCallout {
  width: 154rpx;
  height: 53rpx;
}

.map-content {
  font-size: 24rpx;
  font-family: Source Han Sans CN;
  font-weight: 400;
  text-align: center;
  color: #FFFFFF;
  line-height: 53rpx;
}


.mask-close>image {
  width: 32rpx;
  height: 32rpx;
}


2、小程序合成海报

a、 合成海报 利用canvas画图合成。用的组件合成返回

在主页面 主页面得canvas最好不要显示出来,画到视图之外。


<share-goods-poster id="goods-share" bind:changeCar="changeCar" open="{{open}}"></share-goods-poster>

<view class="right-item-a" bind:tap="shareStore">

逻辑

因为我们得项目不只一种分享得方式,所以有不同得type

 // 联系商家分享按钮
 
  shareStore() { 
      let type = 1
       const storeShare = this.selectComponent('#goods-share')
    storeShare.composeStoreShareImage(this, type, '商家分享') 
  },

组件得页面

<!-- 第一个绘制海报的遮罩层+canvas图片 -->
<block>
    <view id="shared-graph2" class="shared-graph2" wx:if="{{showModalStatus}}" bindtap="_toggle"></view>
    <view class="poster-share-box" bindtap="_toggle" wx:if="{{showModalStatus}}" catchtouchmove='true'>
        <view class="image-box">
            <image class="posterImage" wx:if="{{ posterImage && posterImage !== '' }}" mode="aspectFit"
                src="{{ posterImage }}"></image>
            <!-- <view wx:if="{{ posterImage && posterImage !== '' }}" class="iconfont icon-guanbi" bind:tap="hideModal"></view>-->
            <view style="margin-top:20rpx;">
                <image wx:if="{{ posterImage && posterImage !== '' }}" mode='aspectFit' bindtap="downloadPoster"
                    class="share-icon" src="https://thirdpartimg.51ishare.com/download.png"></image>
            </view>
        </view>
    </view>
</block>

组件逻辑

// 门店分享 按钮
        composeStoreShareImage(from, type,str) {
            this.setData({
                type: type,
                str:str
            })
            let _this = this
            this.setData({
                from: from
            }, () => {
                let storeInfo = wx.getStorageSync('storeInfo')
                _this._composeImage(storeInfo, params => {
                    if (_this.data.from) {
                        _this.data.from.setData({
                            shareBody: null
                        }, () => _this.data.from = null)
                    }
                    _this._toggle()
                    _this._cleanGoods()
                    _this._composeStoreSharePoster(storeInfo, from,str)
                })
            })
        },
        _composeImage(params, composeImage) {
            composeImage(params)
        },
        // 绘制店铺海报图片
        _composeStoreSharePoster(storeInfo, from,str) { 
            const self = this
            const wxGetImageInfo = Poster.promisify(wx.getImageInfo)
            const {
                id
            } = storeInfo
            wx.showToast({
                title: "正在合成海报中",
                icon: "loading",
                duration: 30000,
                mask: true
            })
           // 这边得poster是一个方法
            Poster.baseMap("https://thirdpartimg.51ishare.com/dituofstore.png", "shareCanvas", 1, self, from,str, () => {
                // 合成店铺信息
                Poster.drawStore(wxGetImageInfo, storeInfo, () => {
                    // 合成店铺商品二维码信息
                    Poster.drawBarCode(wxGetImageInfo, id, 0, "pages/index/index", () => {
                        // 开始绘制
                        Poster.draw(ctx => {
                            wx.hideToast()
                            wx.canvasToTempFilePath({
                                canvasId: 'shareCanvas',
                                success(res) {
                                    self.setData({
                                        posterImage: res.tempFilePath
                                    }, () => {
                                        ctx.draw()
                                    })
                                },
                                fail(res) {
                                    ctx.draw()
                                    console.error(res)
                                }
                            })
                        })
                    })
                })
            })
        },

封装得整个poster 只用一个就可以,按照自己得话,我们项目用到得情况比较多

import config from "./config";

const Poster = {
    context: null,
    promisify: api => {
        return (options, ...params) => {
            return new Promise((resolve, reject) => {
                const extras = {
                    success: resolve,
                    fail: reject
                }
                api({
                    ...options,
                    ...extras
                }, ...params)
            })
        }
    },

    //分享特价商品
    drawEvent: function (baseMapPic, goods, canvasId) {
        const wxGetImageInfo = Poster.promisify(wx.getImageInfo)
        return new Promise((resolve, reject) => {
            wxGetImageInfo({
                src: goods.coverImage
            }).then(resp => {
                const ctx = wx.createCanvasContext(canvasId)
                ctx.drawImage(resp.path, 15, 50, 80, 80)
                ctx.drawImage(baseMapPic, 0, 0, 200, 160)
                // 画价格
                const price = goods.name
                ctx.font = ' bold 20px Source Han Sans CN';
                ctx.setFontSize(24)
                ctx.setFillStyle("#FFEBAC");
                ctx.fillText(price, 130, 70, 40)
                // 画划线价
                // var str = "¥" + goods.deductionAmount
                // ctx.setFontSize(12)
                // ctx.setFillStyle("#999999");
                // ctx.fillText(str, 142, 90, 40)
                // ctx.moveTo(140, 86)
                // ctx.lineTo(163, 86)
                // ctx.setStrokeStyle('#999999');
                // ctx.stroke()
                ctx.draw(false, () => {
                    wx.canvasToTempFilePath({
                        canvasId: canvasId,
                        success: function success(res1) {

                            wx.saveFile({
                                tempFilePath: res1.tempFilePath,
                                success: function success(res) {
                                    resolve(res.savedFilePath)
                                }
                            });
                        }
                    });
                })
            })

        })
    },
    // 绘制分享商品的图片
    drawBase: function (baseMapPic, goods, canvasId) {
        const wxGetImageInfo = Poster.promisify(wx.getImageInfo)
        return new Promise((resolve, reject) => {
            wxGetImageInfo({
                src: goods.goodsImage
            }).then(resp => {
                const ctx = wx.createCanvasContext(canvasId)
                ctx.drawImage(resp.path, 15, 50, 80, 80)
                ctx.drawImage(baseMapPic, 0, 0, 200, 160)
                // 画价格
                const price = "¥" + goods.goodsPrice
                ctx.font = 'normal bold 20px sans-serif';
                ctx.setFontSize(24)
                ctx.setFillStyle("#E21500");
                ctx.fillText(price, 120, 70, 60)
                // 画价格
                ctx.draw(false, () => {
                    wx.canvasToTempFilePath({
                        canvasId: canvasId,
                        success: function success(res1) {
                            wx.saveFile({
                                tempFilePath: res1.tempFilePath,
                                success: function success(res) {
                                    resolve(res.savedFilePath)
                                }
                            });
                        }
                    });
                })
            })

        })
    },
    // 绘制分享的特价商品的图片(specOffer)
    drawspec: function (baseMapPic, goods, canvasId) {
        const wxGetImageInfo = Poster.promisify(wx.getImageInfo)
        return new Promise((resolve, reject) => {
            wxGetImageInfo({
                src: goods.goodsImage
            }).then(resp => {
                const ctx = wx.createCanvasContext(canvasId)
                ctx.drawImage(resp.path, 15, 50, 80, 80)
                ctx.drawImage(baseMapPic, 0, 0, 200, 160)
                // 画活动价格
                const price = "¥" + goods.goodsPromotionPrice
                ctx.font = 'normal bold 20px sans-serif';
                ctx.setFontSize(14)
                ctx.setFillStyle("#E21500");
                ctx.fillText(price, 126, 86, 60)
                // 画原价划线价格
                var str = "¥" + goods.goodsPrice
                ctx.setFontSize(10)
                ctx.setFillStyle("#999999");
                ctx.fillText(str, 130, 105, 60)
                ctx.moveTo(128, 102)
                ctx.lineTo(170, 102)
                ctx.setStrokeStyle('#999999');
                ctx.stroke()
                ctx.draw(false, () => {
                    wx.canvasToTempFilePath({
                        canvasId: canvasId,
                        success: function success(res1) {
                            wx.saveFile({
                                tempFilePath: res1.tempFilePath,
                                success: function success(res) {
                                    resolve(res.savedFilePath)
                                }
                            });
                        }
                    });
                })
            })

        })
    },
    baseMap: (baseMapPic, canvasId, scale, self, from, str,callback) => {
        const wxGetImageInfo = Poster.promisify(wx.getImageInfo)
        wxGetImageInfo({
            src: baseMapPic
        }).then(resp => { 
            const ctx = wx.createCanvasContext(canvasId)
            Poster.context = ctx
            // 画布缩放
            if(str){
                resp.height=resp.height-130
            }
            if (from) {
                from.setData({
                    style: 'zoom: ' + scale + '; height: ' + resp.height + 'px;'
                }, () => {
                    self.setData({
                        baseMapWidth: resp.width,
                        baseMapHeight: resp.height
                    }, () => {
                        // 绘制底图
                        ctx.drawImage(resp.path, 0, 0, resp.width, resp.height)
                        ctx.save()
                        callback()
                    })
                })
            } else {
                self.setData({
                    baseMapWidth: resp.width,
                    baseMapHeight: resp.height
                }, () => {
                    // 绘制底图
                    ctx.drawImage(resp.path, 0, 0, resp.width, resp.height)
                    ctx.save()
                    callback()
                })
            }
        }, error => {
            console.error(error)
        })
    },
    drawGoods: (wxGetImageInfo, goods, self, callback) => {
        const ctx = Poster.context
        wxGetImageInfo({
            src: goods.goodsImage
        }).then(resp => {
            let left = (self.data.baseMapWidth - 400) / 2
            // 商品活动
            ctx.drawImage(resp.path, left, 175, 400, 400)
            ctx.save()
            let charArr = goods.goodsName.split('')
            let temp = ""
            let row = []
            ctx.setFontSize(48)
            ctx.setFillStyle("#333333")
            for (let i = 0; i < charArr.length; i++) {
                if (ctx.measureText(temp).width < 590) {
                    temp += charArr[i]
                } else {
                    i--;
                    row.push(temp)
                    temp = ""
                }
            }
            row.push(temp)
            if (row.length > 2) {
                let rowCut = row.slice(0, 2);
                let rowPart = rowCut[1];
                let test = "";
                let empty = [];
                for (let a = 0; a < rowPart.length; a++) {
                    if (ctx.measureText(test).width < 590) {
                        test += rowPart[a];
                    } else {
                        break;
                    }
                }
                empty.push(test);
                //这里只显示两行,超出的用...表示
                let group = empty[0] + "..."
                rowCut.splice(1, 1, group);
                row = rowCut;
            }
            for (let b = 0; b < row.length; b++) {
                ctx.font = 'normal bold 48px Arial'
                // 黑色的商品标题name
                ctx.fillText(row[b], 80, 650 + b * 72, 590)
            }
            ctx.setFillStyle("#EA524A")
            ctx.font = 'normal bold 32px sans-serif'
            // 这个是红色¥
            ctx.fillText('¥', 80, 650 + row.length * 72 + 22)
            let unitWidth = ctx.measureText("¥").width;
            ctx.font = 'normal bold 56px sans-serif'
            var _goodsPromotionPrice = goods.goodsPrice
            if (goods.goodsPromotionPrice) {
                _goodsPromotionPrice = goods.goodsPromotionPrice
            }
            // 红色的价格
            ctx.fillText(_goodsPromotionPrice, 80 + unitWidth, 650 + row.length * 72 + 22)
            let memberPriceWidth = ctx.measureText("26.00").width
            ctx.setFontSize(26)
            ctx.setFillStyle("#999999")
            // 灰色的价格
            ctx.fillText("¥" + goods.goodsPrice, 96 + unitWidth + memberPriceWidth, 650 + row.length * 72 + 22)
            let originPriceWidth = ctx.measureText('¥' + goods.goodsPrice).width
            // 划线
            ctx.setStrokeStyle('#999999')
            ctx.beginPath()
            // 灰色的划线价格的划线
            ctx.moveTo(96 + unitWidth + memberPriceWidth, 650 + row.length * 72 + 13)
            ctx.lineTo(96 + unitWidth + memberPriceWidth + originPriceWidth, 650 + row.length * 72 + 13)
            ctx.stroke()
            ctx.save()
            callback()
        })
    },
    drawBarCode: (wxGetImageInfo, storeId, goodsId, page, callback) => {
        const ctx = Poster.context
        const appId = wx.getAccountInfoSync().miniProgram.appId
        const scene = storeId + (goodsId === 0 ? '' : '$' + goodsId)
        let src = config.api.host + config.api.store + config.api.qrImage + config.api.fix + '?scene=' + scene + '&appId=' + appId + '&page=' + page
        wxGetImageInfo({
            src: src,
        }, () => {
            callback()
        }).then(resp => {
            if (goodsId === 0) {
                // 这个是联系上商家分享的二维码图片
                ctx.drawImage(resp.path, 566, 1020, 135, 135)
            } else {
                // 这个是商品详情分享的二维码图片
                ctx.drawImage(resp.path, 566, 985, 135, 135)
            }
            ctx.save()
            callback()
        })
    },
    draw: (callback) => {
        const ctx = Poster.context
        ctx.draw(false, () => {
            callback(ctx)
            Poster.context = null
        })
    },
    drawStore(wxGetImageInfo, storeInfo, callback) {
        let _this = this
        const {
            name,
            workBeginTime,
            workEndTime,
            logo,
            orderNotifyTelephone
        } = storeInfo
        wxGetImageInfo({
            src: logo
        }).then(resp => {
            const {
                path,
                width,
                height
            } = resp
            const containerWidth = 670
            const containerHeight = 377
            const ctx = Poster.context
            _this.drawImage(ctx, containerWidth, containerHeight, path, width, height, 40, 320)
            ctx.save()
            // 店铺名称
            ctx.setFillStyle("#333333")
            ctx.font = 'normal bold 36px sans-serif'
            ctx.fillText(name, 80, 750)
            // 营业时间
            ctx.setFillStyle("#333333")
            ctx.font = 'normal bold 28px sans-serif'
            ctx.fillText(workBeginTime + '-' + workEndTime, 80, 860)
            ctx.fillText(orderNotifyTelephone, 375, 860)
            ctx.save()
            callback()
        })
    },
    drawImage(ctx, bg_w, bg_h, imgPath, imgWidth, imgHeight, x, y) {
        let dWidth = bg_w / imgWidth; // canvas与图片的宽度比例
        let dHeight = bg_h / imgHeight; // canvas与图片的高度比例
        if (imgWidth > bg_w && imgHeight > bg_h || imgWidth < bg_w && imgHeight < bg_h) {
            if (dWidth > dHeight) {
                ctx.drawImage(imgPath, 0, (imgHeight - bg_h / dWidth) / 2, imgWidth, bg_h / dWidth, x, y, bg_w, bg_h)
            } else {
                ctx.drawImage(imgPath, (imgWidth - bg_w / dHeight) / 2, 0, bg_w / dHeight, imgHeight, x, y, bg_w, bg_h)
            }
        } else {
            if (imgWidth < bg_w) {
                ctx.drawImage(imgPath, 0, (imgHeight - bg_h / dWidth) / 2, imgWidth, bg_h / dWidth, x, y, bg_w, bg_h)
            } else {
                ctx.drawImage(imgPath, (imgWidth - bg_w / dHeight) / 2, 0, bg_w / dHeight, imgHeight, x, y, bg_w, bg_h)
            }
        }
    }
};

export {
    Poster
}

b、利用微信自带方法右上角点击分享,按照格式分享出去。 onShareAppMessage

developers.weixin.qq.com/miniprogram…

 /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function (e) {
    if (e && e.from == 'button' && e.from === 'button' && this.data.shareBody) {
      this.hideModal()
      return this.data.shareBody 
    } else {
      var _shareBody = app.globalData.shareBodyp
      _shareBody.path = '/pages/index/index?storeId=' + wx.getStorageSync("storeId")
      return _shareBody
    }
  },

c、利用button 按钮设置type 分享图片出去。


//利用button得open-type来打开分享 

 <button  open-type="share">分享</button> 

3.vue2-elm-下拉选择带远程模糊搜索

<el-select v-model="establishData.promotionPersonId"
       filterable
       remote
       :remote-method="brandMethod"
       :loading="brandLoading"
       placeholder="请选择活动商户">
  <el-option
    v-for="item in select"
    :key="item.promotionPersonId"
    :label="item.personName"
    :value="item.promotionPersonId">
  </el-option>
</el-select>

query就是输入的模糊查询的关键字。不等于空的时候调接口,里面使用到的值自己在data声明一下。

brandMethod(query) {
if (query !== '') {
  this.brandLoading = true
  setTimeout(() => {
    this.brandLoading = false
    this.promotionMerchantList({
      accountName: query,
      pageIndex: 1,
      pageSize: 1000,
    }).then(res => {
      this.loadingStore = false
      const {
        list
      } = res
      this.select = list
    })
  }, 200)
} else {
  this.select = []
}
},

4.vue2-elm-时间选择

选择开始-结束时间

type daterange(不带时分秒的筛选) datetimerange(带时分秒的筛选) picker-options 设置快捷选项,近一个月,一周等等。 value-format设置值的格式 format展示格式

 <el-date-picker 
   v-model="time"
   type="daterange"
   :clearable="false" align="right"   
   @change="showTime"
   unlink-panels
   range-separator="至" start-placeholder="订单开始日期"
   end-placeholder="订单结束日期"
   value-format="yyyy-MM-dd"
   format="yyyy-MM-dd">
</el-date-picker>

5.vue2-elm-上传单张图片

页面:

<el-upload
  class="avatar-uploader"
  :action="upLoadUrl"
  :show-file-list="false"
  :headers="token"
  :on-success="handleAvatarSuccess"
>
  <img v-if="ruleForm.url" :src="ruleForm.url" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

引入依赖

import { upLoadUrl } from '@/common/js/util'
import { getToken } from '@/utils/auth'

依赖导出地址

export const upLoadUrl =  'http://xxx.168.2.3:8080/v1/resource/upload'

记得把token带上

export function getToken() {
  return Cookies.get(TokenKey)
}

数据

upLoadUrl: upLoadUrl,
token: {
  Authorization: 'Bearer ' + getToken()
},

change事件的时候拿到数据,等submit提交。

handleAvatarSuccess(res) {
  this.ruleForm.url = res.url
},

6.vue2-elm-table表格里面的图片可以放大查看的

preview-src-list主要是这个属性

<el-table-column
  label="背景图"
>
  <template slot-scope="scope">
    <el-image
      style="width: 100px; height: 100px"
      :src="scope.row.url"//当前图片
      :preview-src-list="[scope.row.url,scope.row.url]"//接受数组
    >
    </el-image>
  </template>
</el-table-column>

7. 穿梭框使用带搜索的。

a、这个是vue,elm自带的

html:弹窗里面使用的

  <el-dialog
    title="场次人员"
    :visible.sync="isShowConfig"
    width="40%"
    :close-on-click-modal="false"
  >
    <el-transfer
      filterable
      :filter-method="filterMethod"
      filter-placeholder="请输入名字"
      v-model="chooseUserList"
      :data="userList">
    </el-transfer>
    <span slot="footer" class="dialog-footer">
  <el-button @click="close">取消</el-button>
  <el-button type="primary" @click="submitFormUser()">确 定</el-button>
</span>
  </el-dialog>

js

//data
userListInitial: [],
isShowConfig: false,
userList: [],
chooseUserList: [],
filterMethod(query, item) {
  return item.label.indexOf(query) > -1;
}


请求数据
mounted() {
  this.loadingBrand = true
  this.getList()
  user({
    current: 1,
    size: 100
  }).then(res => {
    if (res) {
      res.content.map(item => {
        this.userListInitial.push({
          key: item.id,
          label: item.username
        })
      })
    }
  })
  
  // 注释这一条 自己造数据测试 
  this.userListInitial=[{
    key:1,
    label:'zsd'
  },{
    key:2,
    label:'admin'
  },{
    key:3,
    label:'阿什顿'
  },{
    key:4,
    label:'iwej'
  },{
    key:5,
    label:'是多么'
  },{
    key:6,
    label:'ask你'
  }]
  this.userListInitial.map(item=>{
    this.userList.push(item)
  })
},

// 配置人员
personnelConfiguration() {
  this.isShowConfig = true
},
//提交
submitFormUser() {
  console.log(this.chooseUserList)
},

不知道为啥第一次高德就是不出现数据。但是第二次又好了,可能是哪里写错字了,下次发现再说。

b、vue2自制穿梭框,用两个table伪造。自己做模糊匹配。

数据操作会遇到问题,回显选中左侧数据会触发 @selection-change="handleSelectionChangeLeft"方法,只能加锁来控制数据不刷新。因为左边和右边选中的数据来自不同的表。 父组件

<el-button type="primary" @click="addChoseGoods">点击选择</el-button> 
<!--    选择商品-->
<AddGoodsActivity ref="choseGoods" @choseChildGoods="choseChildGoods"/>
 
//选择商品
addChoseGoods() {
  this.$refs.choseGoods.open()
}, 

子组件

<template>
  <div>
    <el-dialog
      title="商品"
      :visible.sync="isShowAddGoods"
      @opened="initTable"
      width="1200px"
      :before-close="handleClose"
      :close-on-click-modal="false">
      <div style="display: flex;justify-content: space-between">

        <div style="width: 45%;height: 100%">
          <h3>查看商品</h3>
          <span style="display: flex;align-items: center;margin-bottom: 16px;">
                        <el-input
                          style="width: 150px;"
                          v-model="pageInfo.goodsName"
                          size="mini"
                          clearable
                          placeholder="输入商品名字搜索"/>
                  <el-input
                    style="width: 150px;margin-left: 10px"
                    v-model="pageInfo.goodsId"
                    size="mini"
                    clearable
                    placeholder="输入商品条码搜索"/>
                <el-button style="margin-left: 10px" type="primary" size="mini" @click="searchGoods">查询</el-button>
                <el-button style="margin-left: 10px" type="primary" size="mini" @click="restGoods">重置</el-button>
               </span>
          <el-table
            :data="bindShopListParam"
            stripe
            border
            height="500"
            ref="multipleTable"
            @selection-change="handleSelectionChangeLeft"
            style="width: 100%;">
            <el-table-column
              type="selection"
              width="55">
            </el-table-column>
            <el-table-column
              label="商品名字"
              prop="goodsName">
            </el-table-column>
            <el-table-column
              label="商品条码"
              prop="goodsId">
            </el-table-column>
          </el-table>
          <div>
            <el-pagination
              @size-change="handleSizeChangeGoods" @current-change="handleCurrentChangeGoods"
              :current-page="pageIndexGoods"
              background
              :page-sizes="[10, 20, 30, 40]"
              :pager-count="5"
              layout=" prev, pager, next,sizes"
              :total="bindShopTotal"
              style="margin-top:24px">
            </el-pagination>
          </div>
        </div>
        <div>
          <div style="display: flex;align-items: center;margin-left: 50px ">
            <h3>参与商品</h3>
          </div>
          <div style="height:500px;width:100%;overflow-y: auto;overflow-x: hidden" class="scrollClass">
            <div  style="display: flex;align-items: center">
                <el-button style="margin-right: 12px" type="primary" size="mini" @click="goRight"> 向右边 </el-button>
              <div style="width: 100%">
                <div style="display: flex;justify-content: space-between;align-items: center">
                  <span style="display: flex;align-items: center;">
                  <el-input
                    style="margin: 12px 12px 12px 0"
                    v-model="goodsName"
                    size="mini"
                    clearable
                    placeholder="输入商品条码名称"/>
                     <el-input
                       style="margin: 12px 12px 12px 0"
                       v-model="goodsId"
                       size="mini"
                       clearable
                       placeholder="输入商品条码搜索"/>
                    <el-button style="margin-left: 10px" type="primary" size="mini"
                               @click="searchGoods1">查询</el-button>
                   <el-button style="margin-left: 10px" type="primary" size="mini" @click="restGoods1">重置</el-button>
               </span>
                </div>
                <el-table
                  :data="choseLeftList"
                  stripe
                  border
                  height="440px"
                  style="width:500px;">
                  <el-table-column
                    label="商品名字" prop="goodsName">
                  </el-table-column>
                  <el-table-column
                    label="商品条码"
                    prop="goodsId">
                  </el-table-column>
                  <el-table-column label="金额/元" width="180">
                    <template slot-scope="scope">
                      <div style="display: flex;align-items: center;">
                        <span style="color:#be0c0c;margin-right: 5px;">*</span>
                        <el-input v-model.trim="scope.row.goodsPrice"
                                  @input="(val)=>{scope.row.goodsPrice= val.replace(/[^\d]/g,'')}"
                                  type="number" autocomplete="off"
                                  placeholder="请输入"
                                  maxlength="9"
                                  style="width: 100px"/></div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="操作"
                    width="80px"
                    fixed="right">
                    <template slot-scope="scope">
                      <el-button style="margin-right: 10px" type="danger" size="mini"
                                 @click="deleteNewGoods(scope.row)">删除
                      </el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div style="text-align: right;padding-top:10px">
          <span slot="footer" class="dialog-footer">
     <el-button type="primary" @click="sureClick">确 定</el-button>
    </span>
      </div>
    </el-dialog>
  </div>

</template>

<script>
import {placeGoodsList} from '@/api'
import {mixins} from '@/layout/mixin/commonExport'

export default {
  name: 'addGoods',
  mixins: [mixins],
  data() {
    return {
      pageInfo: {
        goodsId: '',
        pageSize: 10,
        pageIndex: 1,
        goodsName: ''
      },
      goodsName: '',
      goodsId: '',
      choseLeftList: [],
      choseLeftListAll: [],
      isShowAddGoods: false,
      rowSelectFlag: false,
      total: 0,
      pageSizeGoods: 10,
      pageIndexGoods: 1,
      bindShopTotal: 0,
      bindShopListParam: [],
      arr: [],
    }
  },
  mounted() {
    this.bindGoodsInfo()
  },
  methods: {
    deleteNewGoods(row) {
      let _this = this
      this.$nextTick(() => {
        this.$refs.multipleTable.selection.forEach((select, index) => {
          if (select.goodsId === row.goodsId) {
            _this.$refs.multipleTable.toggleRowSelection(select, false);
          }
        })
      })
      this.choseLeftList = this.choseLeftListAll.filter((item) => {
        return item.goodsId !== row.goodsId
      })
      this.choseLeftListAll = this.choseLeftListAll.filter((item) => {
        return item.goodsId !== row.goodsId
      })
    },
    newBindGoodsInfo(arr) {
      arr.forEach(item=>{
        item.goodsPrice = Number(item.goodsPrice)
      })
      this.choseLeftListAll = arr
      this.choseLeftList = arr
    },
    initTable(){
      this.$nextTick(() => {
        this.rowSelectFlag = true
        this.bindShopListParam.forEach(item => {
          this.choseLeftList.forEach(items=>{
            if (items.goodsId === item.goodsId) {
              this.$refs.multipleTable.toggleRowSelection(item, true);
            }
          })
        })
        this.rowSelectFlag = false
      })
    },
    open() {
      this.isShowAddGoods = true
    },
    goRight() {
      this.choseLeftList.forEach(item=>{
        this.choseLeftListAll.forEach(items=>{
          if(item.goodsId === items.goodsId){
            items.goodsPrice =  item.goodsPrice
          }
        })
      })
      this.choseLeftList = this.choseLeftListAll
    },
    searchGoods() {
      this.pageInfo.pageIndex = 1
      this.bindGoodsInfo()
    },
    restGoods() {
      this.pageInfo.pageIndex = 1
      this.pageInfo = {
        goodsName: '',
        goodsId: ''
      }
      this.bindGoodsInfo()
    },
    searchGoods1() {
      if (this.goodsName !== '') {
        this.choseLeftList = this.choseLeftList.filter(item => {
          return item.goodsName.indexOf(this.goodsName) !== -1
        })
      }
      if (this.goodsId !== '') {
        this.choseLeftList = this.choseLeftList.filter(item => {
          return item.goodsId.indexOf(this.goodsId) !== -1
        })
      }
    },
    restGoods1() {
      this.goodsName = ''
      this.goodsId = ''
      this.choseLeftList = this.choseLeftListAll
    },
    handleSizeChangeGoods(val) {
      this.pageSizeGoods = val
      this.bindGoodsInfo()
    },
    handleCurrentChangeGoods(val) {
      this.pageIndexGoods = val
      this.bindGoodsInfo()
    },

    bindGoodsInfo() {
      placeGoodsList(this.pageInfo).then(res => {
        const {
          list,
          count
        } = res
        this.bindShopListParam = list
        this.bindShopTotal = count
      })
    },
    handleSelectionChangeLeft(list) {
      if (this.rowSelectFlag) return
      this.choseLeftListAll = list
    },
    sureClick() {
      if (this.choseLeftListAll.length === 0) {
        this.$message.error('请选择商品')
        return
      }
      var arr = this.choseLeftListAll.filter(item => {
        if (item.goodsPrice && item.goodsPrice !== '' && item.goodsPrice !== null && item.goodsPrice !== ' ') {
        } else {
          return item
        }
      })
      if (arr.length !== 0) {
        this.$message.error('请输入金额')
      } else {
        this.choseLeftListAll.forEach(item => {
          this.arr.push({
            goodsId: item.goodsId,
            goodsPrice: item.goodsPrice ? item.goodsPrice : null
          })
        })
        this.$emit('choseChildGoods', this.arr)
        setTimeout(() => {
          this.isShowAddGoods = false
        }, 100)
      }
    },
    handleClose() {
      this.pageInfo = {
        goodsId: '',
        goodsName: ''
      }
      this.goodsName =''
      this.goodsId =''
      this.isShowAddGoods = false
      this.choseLeftList = []
      this.choseLeftListAll = []
      this.$refs.multipleTable.clearSelection()
    },

  }

}
</script>

<style scoped>
/deep/ .el-transfer-panel {
  width: 400px;
}


</style>

image.png

8.vue2-elm-富文本

参考:blog.csdn.net/code_nutter…


<el-card style="height: 610px;">
  <quill-editor v-model="ruleForm.description" ref="myQuillEditor" style="height: 500px;"
                class="bottom-jianxi" :options="editorOption">
  </quill-editor>
</el-card>

import {
  quillEditor
} from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
components: {
  quillEditor
},

在components文件夹创建ue.vue组件,如下

<!-- 组件代码如下 -->
<template>
  <div>
    <script id="editor" type="text/plain"></script>
  </div>
</template>
<script>
export default {
  name: 'UE',
  data () {
    return {
      editor: null
    }
  },
  props: {
    defaultMsg: {
      type: String
    },
    config: {
      type: Object
    }
  },
  mounted () {
    const _this = this
    // eslint-disable-next-line no-undef
    this.editor = UE.getEditor('editor', this.config) // 初始化UE
    this.editor.addListener('ready', function () {
      _this.editor.setContent(_this.defaultMsg) // 确保UE加载完成后,放入内容。
    })
  },
  methods: {
    getUEContent () { // 获取内容方法
      return this.editor.getContent()
    }
  },
  destroyed () {
    this.editor.destroy()
  }
}

</script>

image.png