他人项目js和css技巧借鉴

145 阅读7分钟

一 日期补0和格式处理

function getDateStr(e, t = "-") {
	e = e || new Date;
	const n = [];
	return n.push(e.getFullYear()), n.push(("00" + (e.getMonth() + 1)).substr(-2)), n.push(("00" + e.getDate()).substr(-
		2)), n.join(t)
}

二 时间补0和 格式处理

function getTimeStr(e, t = ":") {
	e = e || new Date;
	const n = [];
	return n.push(("00" + e.getHours()).substr(-2)), n.push(("00" + e.getMinutes()).substr(-2)), n.push(("00" + e
		.getSeconds()).substr(-2)), n.join(t)
}

三 日期时间格式 处理

function getFullTimeStr(e) {
	return getDateStr(e = e || new Date) + " " + getTimeStr(e)
}

四 uniApp 条件编译

写页面样式应该改变原来的想法,一个样式写了全部,而应改写多个。先通用的,再特殊的。

1 样式判断

	/* #ifdef h5 */
			margin-top: 0;
	/* #endif */

样式计算写法

	.menu{
		position: fixed;
		left: 0;
		width: calc(100% - 60rpx);
		z-index: 99;
		background-color: #FFFFFF;
	}

样式动画写法

.no_active_{
		background-image: linear-gradient(100deg, #fc9999 , #fe7777);
		border: none;
		color: #3a1800;
		// box-shadow: 0px 4px 10px #fcb6b6;
		animation: tiaobig 0.8s ease-in-out alternate infinite;
		animation-iteration-count:1;
	}
	@keyframes tiaobig {
		0% {
			transform: scale(0.98);//缩小
		}
		25% {
			transform: scale(1.08);//放大
		}
		50% {
			transform: scale(0.94);//缩小
		}
		75% {
			transform: scale(1.06);
		}
		100% {
			transform: scale(1);
		}
	}

样式动态效果

	.hover-class{
		transform:scale(0.92);
		transition: all 0.2s;
	}

页面引入样式

@import 'index.scss';

2.页面里面判断

	<!-- #ifdef MP-QQ -->
					<button open-type="getUserInfo" @click="getUserProfile" style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;"></button>
					<!-- #endif -->
					<!-- #ifdef MP-WEIXIN -->
					<button open-type="getUserProfile" @click="getUserProfile" style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;"></button>
					<!-- #endif -->

3. js里面判断

	// 加载激励视频广告
				// #ifdef MP-QQ
				videoAd = wx.createRewardedVideoAd({
					adUnitId: "{{ qqexcitation }}"
				});
				// #endif
				// #ifdef MP-WEIXIN
				videoAd = wx.createRewardedVideoAd({
					adUnitId: "adunit-8b7aecba30b3f324"
				});
				// #endif
 //多个判断
  // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/index/default/default' || val == '/pages/category/index/index' || val == '/pages/index/cart/cart' || val == '/pages/index/member/member') {
                            this.$u.route({ type: 'switchTab', url: val });
                            return;
                        } else if (val.indexOf('/pages/coupon/coupon') > -1) {
                            var id = val.replace('/pages/coupon/coupon?id=', "");
                            this.receiveCoupon(id)
                        } else {
                            this.$u.route(val);
                            return;
                        }
                        // #endif

4. json里面判断

	// #ifdef MP-TOUTIAO
		{
			"path": "pages/washCoupon/myCoupon",
			"style": {
				"navigationBarTitleText": "我的洗车券",
				"enablePullDownRefresh": false,
				"navigationStyle": "default"
			}

		},
		// #endif
		// #ifndef MP-TOUTIAO
		{
			"path": "pages/washCoupon/myCoupon",

			"style": {
				"navigationBarTitleText": "我的洗车券",
				"enablePullDownRefresh": false,
				"navigationStyle": "custom"
			}
		},
		// #endif

五 按钮透明处理

<button open-type="share" style="position: absolute;top: 20rpx;left: 20rpx;width: 50rpx;height: 50rpx;opacity: 0;"></button>

六 js图片命名

		if(that.designId == '-1' || (imgs.length > 0 && imgs[0].url != that.imgList[0].url)){
					var path = imgs[0].url
					var extension = path.substring(path.lastIndexOf('.') + 1)
					var random = String(Math.random()*100000).split('.')[0]
					var now = new Date()
					var year = now.getFullYear()
					var month = (now.getMonth() + 1) < 10?'0'+(now.getMonth() + 1):(now.getMonth() + 1)
					var day = now.getDate() < 10?'0'+now.getDate():now.getDate()
					var hours = now.getHours() < 10?'0'+now.getHours():now.getHours()
					var minutes = now.getMinutes() < 10?'0'+now.getMinutes():now.getMinutes()
					var seconds = now.getSeconds() < 10?'0'+now.getSeconds():now.getSeconds()
					
					var cloudPath = 'design_'+year+month+day+hours+minutes+seconds+'_'+random+'.'+extension
					
					await uniCloud.uploadFile({
						filePath: path,
						cloudPath: cloudPath
					}).then(async res => {
						await uniCloud.getTempFileURL({
							fileList: [res.fileID]
						}).then(res => {
							if(res.fileList.length > 0){
								that.design.image = res.fileList[0].tempFileURL
							}else{
								that.$u.toast("图片上传失败");
								return;
							}
						});
					})
				}

七 js 大小写转换

 if (String(code).toUpperCase() === 'SUCCESS') {
        const { popularWords = [] } = data;
        this.setData({
          popularWords,
        });
      }

let code="aaa"; 
let b=String(code).toUpperCase();
b
'AAA

八 js封转替换

export function replaceAll (text,stringToFind,stringToReplace) {
	   if ( stringToFind == stringToReplace) return this;
	          var temp = text;
	          var index = temp.indexOf(stringToFind);
	          while (index != -1) {
	              temp = temp.replace(stringToFind, stringToReplace);
	              index = temp.indexOf(stringToFind);
	          }
	return temp;
}

九api接口集中处理方法

	// 组织机构查询
		office: {
			treeData: (params = {}) => vm.$u.get(config.adminPath+'/sys/office/treeData', params),
		},
    // 增删改查例子
		testData: {
			form: (params = {}) => vm.$u.post(config.adminPath+'/test/testData/form', params),
			list: (params = {}) => vm.$u.post(config.adminPath+'/test/testData/listData', params),
			save: (params = {}) => vm.$u.postJson(config.adminPath+'/test/testData/save', params),
			disable: (params = {}) => vm.$u.post(config.adminPath+'/test/testData/disable', params),
			enable: (params = {}) => vm.$u.post(config.adminPath+'/test/testData/enable', params),
			delete: (params = {}) => vm.$u.post(config.adminPath+'/test/testData/delete', params),
		},
		//帮助理解
		testDemo:{
			getDemoUser:function(params){
				return vm.$u.post(config.adminPath+'/test/testData/form', params);
			}
		}

十 js 常用判断

/**
 * 用户输入内容验证类
 */

// 是否为空
export const isEmpty = (str) => {
  return !str || str.trim() == ''
}

/**
 * 匹配phone
 */
export const isPhone = (str) => {
  const reg = /^((0\d{2,3}-\d{7,8})|(1[3456789]\d{9}))$/
  return reg.test(str)
}

/**
 * 匹配phone
 */
export const isMobile = (str) => {
  const reg = /^(1[3456789]\d{9})$/
  return reg.test(str)
}

/**
 * 匹配Email地址
 */
export const isEmail = (str) => {
  if (str == null || str == "") return false
  var result = str.match(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/)
  if (result == null) return false
  return true
}

/**
 * 判断数值类型,包括整数和浮点数
 */
export const isNumber = (str) => {
  if (isDouble(str) || isInteger(str)) return true
  return false
}

/**
 * 判断是否为正整数(只能输入数字[0-9])
 */
export const isPositiveInteger = (str) => {
  return /(^[0-9]\d*$)/.test(str)
}

/**
 * 匹配integer
 */
export const isInteger = (str) => {
  if (str == null || str == "") return false
  var result = str.match(/^[-\+]?\d+$/)
  if (result == null) return false
  return true
}

/**
 * 匹配double或float
 */
export const isDouble = (str) => {
  if (str == null || str == "") return false
  var result = str.match(/^[-\+]?\d+(\.\d+)?$/)
  if (result == null) return false
  return true
}

十一 缓存设置时间

/**  
 * 缓存数据优化  
 * const storage = require('@/utils/storage');  
 * import storage from '@/utils/storage'  
 * 使用方法 【  
 *     一、设置缓存  
 *         string    storage.set('k', 'string你好啊');  
 *         json      storage.set('k', { "b": "3" }, 2);  
 *         array     storage.set('k', [1, 2, 3]);  
 *         boolean   storage.set('k', true);  
 *     二、读取缓存  
 *         默认值    storage.get('k')  
 *         string    storage.get('k', '你好')  
 *         json      storage.get('k', { "a": "1" })  
 *     三、移除/清理    
 *         移除: storage.remove('k');  
 *         清理:storage.clear();   
 * 】  
 * @type {String}  
 */

const postfix = '_expiry' // 缓存有效期后缀   

module.exports = {

  /**  
   * 设置缓存   
   * @param  {[type]} k [键名]  
   * @param  {[type]} v [键值]  
   * @param  {[type]} t [时间、单位秒]  
   */
  set(k, v, t) {
    uni.setStorageSync(k, v)
    const seconds = parseInt(t)
    if (seconds > 0) {
      let timestamp = Date.parse(new Date())
      timestamp = timestamp / 1000 + seconds
      uni.setStorageSync(k + postfix, timestamp + '')
    } else {
      uni.removeStorageSync(k + postfix)
    }
  },

  /**  
   * 获取缓存   
   * @param  {[type]} k   [键名]  
   * @param  {[type]} def [获取为空时默认]  
   */
  get(k, def) {
    const deadtime = parseInt(uni.getStorageSync(k + postfix))
    if (deadtime) {
      if (parseInt(deadtime) < Date.parse(new Date()) / 1000) {
        if (def) {
          return def
        } else {
          return false
        }
      }
    }
    const res = uni.getStorageSync(k)
    if (res) {
      return res
    }
    if (def == undefined || def == "") {
      def = false
    }
    return def
  },

  /**
   * 删除指定缓存
   * @param {Object} k
   */
  remove(k) {
    uni.removeStorageSync(k)
    uni.removeStorageSync(k + postfix)
  },

  /**  
   * 清理所有缓存  
   * @return {[type]} [description]  
   */
  clear() {
    uni.clearStorageSync()
  }
}

十二 图片验证码

getCaptcha() {
			const app = this
			CaptchaApi.image().then(result => {
				app.captcha = 'data:image/gif;base64,' + result.img
				app.uuid = result.uuid
			})
	},

十三 请求帮助类

const http = uni.$u.http;

/**
 * 混入默认个性化配置
 * @param {*} config 
 * @returns 
 */
function mixinCustom (config) {
  config.custom = Object.assign({
    auth: true,
    toast: true,
    catch: true,
    loading: true
  }, config.custom || {});
  return config;
}

/**
 * 格式化get请求url参数,将对象解析为字符串
 * @param {*} url 
 * @param {*} params 
 * @returns 
 */
function urlFormater (url, params) {
  if (params) {
    let paramList = [];
    for (let key in params) {
      paramList.push(key + '=' + params[key])
    }
    return url.indexOf('?') > -1 ? (url + '&' + paramList.join('&')) : (url + '?' + paramList.join('&'))
  }
  return url;
}

const request = {
  // post提交
  post (url, params, config = {}) {
    config = mixinCustom(config)
    return http.post(url, params, config);
  },
  // get提交
  get (url, params, config = {}) {
    config = mixinCustom(config)
    let path = urlFormater(url, params)
    return http.get(path, config);
  },

};

export default request;

十四 时间差转倒计时数据

//时间差转倒计时数据
function timeToDateObj(micro_second) {
    var time = {}
    // 总秒数
    var second = Math.floor(micro_second)
    // 天数
    time.day = Math.floor(second / 3600 / 24)
    // 小时
    time.hour = Math.floor((second / 3600) % 24)
    // 分钟
    time.minute = Math.floor((second / 60) % 60)
    // 秒
    time.second = Math.floor(second % 60)
    return time
};

十五 金额相加和相减

/**
 * 金额相加
 * @param {Object} value1
 * @param {Object} value2
 */
function moneySum(value1, value2) {
    return (parseFloat(value1) + parseFloat(value2)).toFixed(2);
}
/**
 * 金额相减
 * @param {Object} value1
 * @param {Object} value2
 */
function moneySub(value1, value2) {
    let res = (parseFloat(value1) - parseFloat(value2)).toFixed(2);
    return res > 0 ? res : 0;
}

十六 图片海报保存

  // 保存海报到本地
            savePoster() {
                let _this = this;
                // #ifdef H5
                _this.downloadIamge(_this.poster, 'image');
                // #endif

                // #ifdef MP || MP-ALIPAY || APP-PLUS || APP-PLUS-NVUE
                _this.downloadImageOfMp(_this.poster)
                // #endif
            },
            //下载图片地址和图片名
            downloadIamge(imgsrc, name) {
                var image = new Image();
                // 解决跨域 Canvas 污染问题
                image.setAttribute('crossorigin', 'anonymous');
                image.onload = () => {
                    var canvas = document.createElement('canvas');
                    canvas.width = image.width;
                    canvas.height = image.height;
                    var context = canvas.getContext('2d');
                    context.drawImage(image, 0, 0, image.width, image.height);
                    var url = canvas.toDataURL('image/png'); //得到图片的base64编码数据
                    var a = document.createElement('a'); // 生成一个a元素
                    var event = new MouseEvent('click'); // 创建一个单击事件
                    a.download = name || 'photo'; // 设置图片名称
                    a.href = url; // 将生成的URL设置为a.href属性
                    a.dispatchEvent(event); // 触发a的单击事件
                };
                image.src = imgsrc;
            },
            downloadImageOfMp(image) {
                let _this = this

                // #ifdef APP-PLUS || APP-PLUS-NVUE
                uni.downloadFile({
                    url: image,
                    success(res) {
                        uni.saveImageToPhotosAlbum({
                            filePath: res.tempFilePath,
                            success() {
                                _this.$refs.uToast.show({ title: '操作成功', type: 'success' })
                            },
                            fail() {
                                _this.$u.toast('图片保存失败')
                            }
                        });
                    },
                    fail() {
                        _this.$u.toast('下载失败')
                    }
                })
                // #endif

                // #ifdef MP
                uni.authorize({
                    scope: 'scope.writePhotosAlbum',
                    success() {
                        // 先下载到本地
                        uni.downloadFile({
                            url: image,
                            success(res) {
                                uni.saveImageToPhotosAlbum({
                                    filePath: res.tempFilePath,
                                    success() {
                                        _this.$refs.uToast.show({ title: '保存成功', type: 'success' })
                                    },
                                    fail() {
                                        _this.$u.toast('图片保存失败')
                                    }
                                });
                            },
                            fail() {
                                _this.$u.toast('下载失败')
                            }
                        })
                    },
                    fail() {
                        //console.log('授权失败')
                    }
                })
                // #endif
            }

十七 js通用验证方法正则表达式

可以去www.uviewui.com/components/… 这里获取 ,它的libs/function下

/**
 * 验证电子邮箱格式
 */
function email(value) {
    return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)
}

/**
 * 验证手机格式
 */
function mobile(value) {
    return /^1[23456789]\d{9}$/.test(value)
}

/**
 * 验证URL格式
 */
function url(value) {
    return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
        .test(value)
}

/**
 * 验证日期格式
 */
function date(value) {
    if (!value) return false
    // 判断是否数值或者字符串数值(意味着为时间戳),转为数值,否则new Date无法识别字符串时间戳
    if (number(value)) value = +value
    return !/Invalid|NaN/.test(new Date(value).toString())
}

/**
 * 验证ISO类型的日期格式
 */
function dateISO(value) {
    return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
}

/**
 * 验证十进制数字
 */
function number(value) {
    return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
}

/**
 * 验证字符串
 */
function string(value) {
    return typeof value === 'string'
}

/**
 * 验证整数
 */
function digits(value) {
    return /^\d+$/.test(value)
}

/**
 * 验证身份证号码
 */
function idCard(value) {
    return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
        value
    )
}

/**
 * 是否车牌号
 */
function carNo(value) {
    // 新能源车牌
    const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
    // 旧车牌
    const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
    if (value.length === 7) {
        return creg.test(value)
    } if (value.length === 8) {
        return xreg.test(value)
    }
    return false
}

/**
 * 金额,只允许2位小数
 */
function amount(value) {
    // 金额,只允许保留两位小数
    return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
}

/**
 * 中文
 */
function chinese(value) {
    const reg = /^[\u4e00-\u9fa5]+$/gi
    return reg.test(value)
}

/**
 * 只能输入字母
 */
function letter(value) {
    return /^[a-zA-Z]*$/.test(value)
}

/**
 * 只能是字母或者数字
 */
function enOrNum(value) {
    // 英文或者数字
    const reg = /^[0-9a-zA-Z]*$/g
    return reg.test(value)
}

/**
 * 验证是否包含某个值
 */
function contains(value, param) {
    return value.indexOf(param) >= 0
}

/**
 * 验证一个值范围[min, max]
 */
function range(value, param) {
    return value >= param[0] && value <= param[1]
}

/**
 * 验证一个长度范围[min, max]
 */
function rangeLength(value, param) {
    return value.length >= param[0] && value.length <= param[1]
}

/**
 * 是否固定电话
 */
function landline(value) {
    const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
    return reg.test(value)
}

/**
 * 判断是否为空
 */
function empty(value) {
    switch (typeof value) {
    case 'undefined':
        return true
    case 'string':
        if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
        break
    case 'boolean':
        if (!value) return true
        break
    case 'number':
        if (value === 0 || isNaN(value)) return true
        break
    case 'object':
        if (value === null || value.length === 0) return true
        for (const i in value) {
            return false
        }
        return true
    }
    return false
}

/**
 * 是否json字符串
 */
function jsonString(value) {
    if (typeof value === 'string') {
        try {
            const obj = JSON.parse(value)
            if (typeof obj === 'object' && obj) {
                return true
            }
            return false
        } catch (e) {
            return false
        }
    }
    return false
}

/**
 * 是否数组
 */
function array(value) {
    if (typeof Array.isArray === 'function') {
        return Array.isArray(value)
    }
    return Object.prototype.toString.call(value) === '[object Array]'
}

/**
 * 是否对象
 */
function object(value) {
    return Object.prototype.toString.call(value) === '[object Object]'
}

/**
 * 是否短信验证码
 */
function code(value, len = 6) {
    return new RegExp(`^\\d{${len}}$`).test(value)
}

/**
 * 是否函数方法
 * @param {Object} value
 */
function func(value) {
    return typeof value === 'function'
}

/**
 * 是否promise对象
 * @param {Object} value
 */
function promise(value) {
    return object(value) && func(value.then) && func(value.catch)
}

/** 是否图片格式
 * @param {Object} value
 */
function image(value) {
    const newValue = value.split('?')[0]
    const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i
    return IMAGE_REGEXP.test(newValue)
}

/**
 * 是否视频格式
 * @param {Object} value
 */
function video(value) {
    const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i
    return VIDEO_REGEXP.test(value)
}

/**
 * 是否为正则对象
 * @param {Object}
 * @return {Boolean}
 */
function regExp(o) {
    return o && Object.prototype.toString.call(o) === '[object RegExp]'
}

export default {
    email,
    mobile,
    url,
    date,
    dateISO,
    number,
    digits,
    idCard,
    carNo,
    amount,
    chinese,
    letter,
    enOrNum,
    contains,
    range,
    rangeLength,
    empty,
    isEmpty: empty,
    jsonString,
    landline,
    object,
    array,
    code,
    func,
    promise,
    video,
    image,
    regExp,
    string
}

十八 防抖函数

let timeout = null

/**
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function debounce(func, wait = 500, immediate = false) {
    // 清除定时器
    if (timeout !== null) clearTimeout(timeout)
    // 立即执行,此类情况一般用不到
    if (immediate) {
        const callNow = !timeout
        timeout = setTimeout(() => {
            timeout = null
        }, wait)
        if (callNow) typeof func === 'function' && func()
    } else {
        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
        timeout = setTimeout(() => {
            typeof func === 'function' && func()
        }, wait)
    }
}

export default debounce

十九 节流函数

let timer; let
    flag
/**
 * 节流原理:在一定时间内,只能触发一次
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function throttle(func, wait = 500, immediate = true) {
    if (immediate) {
        if (!flag) {
            flag = true
            // 如果是立即执行,则在wait毫秒内开始时执行
            typeof func === 'function' && func()
            timer = setTimeout(() => {
                flag = false
            }, wait)
        }
    } else if (!flag) {
        flag = true
        // 如果是非立即执行,则在wait毫秒内的结束处执行
        timer = setTimeout(() => {
            flag = false
            typeof func === 'function' && func()
        }, wait)
    }
}
export default throttle

二十 样式写法

button[disabled].bg-white {
    background-color: #fdfdfd !important;
    color: #ccc !important;
}
button[disabled].bg-green {
    background-color: #94de94 !important;
    color: #d5f5d5 !important;
}
button[disabled].bg-red {
    background-color: #ffbaba !important;
    color: #ffdfdf !important;
}
button[disabled].bg-yellow {
    background-color: #fff1cb !important;
    color: #fbd777 !important;
}
button[disabled].bg-gray {
    background-color: #ececec !important;
    color: #ababab !important;
}
/**
 * 公共操作栏按钮样式
 */
.item-operation button:not(:first-child) {
    margin-left: 20rpx;
}
.share-popup-content .share-items:not(:first-child) {
    border-top: 1px solid #f0f0f0;
}
.goods-comment-item .base-content .images image:not(:last-child) {
    margin-right: 10rpx;
}
.panel-item .panel-content .item:last-child {
    border: 0 !important;
    padding-bottom: 0 !important;
}

二十一 默认值

在页面上设置默认值,可以避免出现空值

 <view v-if="(propStatus || false)" class="data-bottom-line">
            <view class="left"></view>
            <view class="msg">{{propMsg || '我是有底线的'}}</view>
            <view class="right"></view>
        </view>
<block v-if="(propData || null) != null && propData.length > 0"></block>

二十二 点击其他区域关闭弹窗

注意遮罩层比弹窗层层级小

有关遮罩层相关代码

<view class="test-popup-mask" @click="onMaskTap" :style="showQueryDown?'':'display:none'">
		</view>

onMaskTap(e) {
				//console.log("hello,test",e);
				//alert("aaa")
				this.showQueryDown = !this.showQueryDown;
			},
.test-popup-mask {
		position: fixed;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		background-color: rgba(0, 0, 0, 0.6);
		opacity: 0.31;
		z-index: 9999;
	}

自定义弹窗代码

<template>
    <view>
        <view :class="'popup ' + (propClassname || '') + ' ' + ((propShow || false) ? 'popup-show' : '') + ' ' + ((propAnimation || true) ? 'animation': '' )" :disable-scroll="propDisablescroll">
            <view class="popup-mask" v-if="propMask || true" @tap="onMaskTap"></view>
            <view :class="'popup-content popup-' + (propPosition || 'bottom')+ ' '+(propIsBar ? 'popup-bar' : '')">
                <slot></slot>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {};
        },
        components: {},
        props: {
            propClassname: {
            	type: String,
            	default: ''
            },
            propShow: {
            	type: Boolean,
            	default: false
            },
            propPosition: {
            	type: String,
            	default: 'bottom'
            },
            propMask: {
            	type: Boolean,
            	default: true
            },
            propAnimation: {
            	type: Boolean,
            	default: true
            },
            propDisablescroll: {
            	type: Boolean,
            	default: false
            },
            propIsBar: {
            	type: Boolean,
            	default: false
            }
        },
        methods: {
            onMaskTap: function onMaskTap() {
                this.$emit('onclose', {
                    detail: {}
                }, {});
            }
        }
    };
</script>
<style>
    .popup-content {
        position: fixed;
        background: #fff;
        z-index: 101;
        overflow: hidden;
    }
    .popup-mask {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0, 0, 0, 0.6);
        opacity: 0;
        pointer-events: none;
        z-index: 100;
    }
    .popup-left {
        transform: translateX(-100%);
        left: 0;
        top: 0;
        bottom: 0;
    }
    .popup-right {
        transform: translateX(100%);
        right: 0;
        top: 0;
        bottom: 0;
    }
    .popup-top {
        top: 0;
        width: 100vw;
        transform: translateY(-100%);
    }
    .popup-bottom {
        bottom: 0;
        width: 100vw;
        transform: translateY(100%);
    }
    .popup-show .popup-content {
        transform: none;
    }
    .popup-show .popup-mask {
        opacity: 1;
        pointer-events: auto;
    }
    .popup.animation .popup-content {
        transition: all 0.25s linear;
    }
    .popup.animation .popup-mask {
        transition: all 0.25s linear;
    }
    .popup-top {
        border-bottom-right-radius: 20rpx;
        border-bottom-left-radius: 20rpx;
    }
    .popup-bottom {
        border-top-right-radius: 20rpx;
        border-top-left-radius: 20rpx;
    }
    .popup-left {
        border-top-right-radius: 20rpx;
        border-bottom-right-radius: 20rpx;
    }
    .popup-right {
        border-top-left-radius: 20rpx;
        border-bottom-left-radius: 20rpx;
    }
    .popup-bar {
        /* #ifdef H5 || APP */
        bottom: var(--window-bottom) !important;
        /* #endif */
    }
</style>

这里有一个关键点需要了解:blog.csdn.net/qq_37600506…

二十三 小程序

全局的东西写 在app.js里 或者uniApp中的App.vue里

需要登录的页面可以参考这个ShopXO开源商城uniapp端项目中的方法【get_user_info】

二十四 URL 转json对象

    /**
             * url参数转json对象
             */
            url_params_to_json(url_params) {
                var json = new Object();
                if ((url_params || null) != null) {
                    var arr = url_params.split('&');
                    for (var i = 0; i < arr.length; i++) {
                        var temp = arr[i].split('=');
                        json[temp[0]] = temp[1];
                    }
                }
                return json;
            },

二十五 点击跳转和链接事件

  /**
             * 事件操作
             */
            operation_event(e) {
                var value = e.currentTarget.dataset.value || null;
                var type = parseInt(e.currentTarget.dataset.type);
                if (value != null) {
                    switch (type) {
                        // web
                        case 0:
                            this.open_web_view(value);
                            break;
                        // 内部页面
                        case 1:
                            if (this.is_tabbar_pages(value)) {
                                uni.switchTab({
                                    url: value
                                });
                            } else {
                                uni.navigateTo({
                                    url: value
                                });
                            }
                            break;
                        // 跳转到外部小程序
                        case 2:
                            uni.navigateToMiniProgram({
                                appId: value
                            });
                            break;
                        // 跳转到地图查看位置
                        case 3:
                            var values = value.split('|');
                            if (values.length != 4) {
                                this.showToast('事件值格式有误');
                                return false;
                            }
                            this.open_location(values[2], values[3], values[0], values[1]);
                            break;
                        // 拨打电话
                        case 4:
                            this.call_tel(value);
                            break;
                    }
                }
            },

            /**
             * 打开 webview页面
             * value    [string]  url地址
             */
            open_web_view(value) {
                uni.navigateTo({
                    url: "/pages/web-view/web-view?url=" + encodeURIComponent(value)
                });
            },
                
                 /**
             * 当前地址是否存在tabbar中
             */
            is_tabbar_pages(url) {
                var value = this.url_value_handle(url);
                if ((value || null) == null) {
                    return false;
                }
                var temp_tabbar_pages = this.data.tabbar_pages;
                for (var i in temp_tabbar_pages) {
                    if (temp_tabbar_pages[i] == value) {
                        return true;
                    }
                }
                return false;
            },
        // 链接地址事件
            url_event(e) {
                var value = e.currentTarget.dataset.value || null;
                if (value != null) {
                    var temp = value.substr(0, 6);
                    if (temp == 'http:/' || temp == 'https:') {
                        this.open_web_view(value);
                    } else {
                        if (this.is_tabbar_pages(value)) {
                            uni.switchTab({
                                url: value
                            });
                        } else {
                            uni.navigateTo({
                                url: value
                            });
                        }
                    }
                }
            },