vue 全局动态修改title、keywords、description;vue常用挂载的方法,自定义指令;

17 篇文章 1 订阅
4 篇文章 0 订阅

 vue 全局动态修改title、keywords、description

路由:
 

{
   path: "xxx",
   name: "xxx",
   component: () =>import('..xxx'),
   meta: {
      title: 'xxx',
      keywords:'xxx',
      description:'xxx'
   },
},

 实现

router.beforeEach((to,from,next)=>{
  /*********动态修改keywords和description*************/
  if(Object.keys(to.meta).length>0 && to.matched.length>0){
    let this_meta=to.matched[to.matched.length-1].meta
    console.log(this_meta,'---this_meta---')
    if(this_meta.title)document.title=this_meta.title
    let head = document.getElementsByTagName('head');
    let meta_keyword=document.createElement('meta');
    if(document.querySelector('meta[name="keywords"]')){
      document.querySelector('meta[name="keywords"]').setAttribute('content',this_meta.keywords)
    }else{
      meta_keyword.setAttribute('name','keywords')
      meta_keyword.setAttribute('content',this_meta.keywords)
      head[0].appendChild(meta_keyword)
    }
    let meta_description=document.createElement('meta');
    if(document.querySelector('meta[name="description"]')){
      document.querySelector('meta[name="description"]').setAttribute('content',this_meta.description)
    }else{
      meta_description.setAttribute('name','description')
      meta_description.setAttribute('content',this_meta.description)
      head[0].appendChild(meta_description)
    }
  }
  /**********************************************/
  next()
})

其他方法:

filters.js:
 

export function formatNumber(num, type) {
	if (num) {
		num = num.toString().replace(/[,]/g, '')
	}
	if (num === '' || num === null || num === undefined || num === 'inf' || num == '-') {
		return '--'
	}
	num = parseFloat(num)
	if (!type) {
		/* 大于100 保留2位小数 否则显示4位小数  */
		let _num = parseFloat((num * 1000) / 1000).toFixed(2)
		return formatCurrency(_num)
	}
	if (type === '%') {
		// let _num = parseFloat((num * 1000) / 1000).toFixed(2) * 100
		return maxDecimal(num, 4)
	}
	if (type === 'int') {
		let _num = parseFloat((num * 1000) / 1000).toFixed(0)
		return _num
	}
}

/**
 * 
 * 金额加,分隔符(正则)
 * **/
export function formatCurrency(value) {
         if (!value) return 0
        const valueArray = value.toString().split('.')
        const valueNum = Number(valueArray[0].toString().replace(/,/g, ''))
        valueArray[0] = Math.abs(valueNum).toString().split('').reverse().join('').replace(/(\d{3})/g, function(word) {
          return word + ','
        }).replace(/^(\s|,)+|(\s|,)+$/g, '').split('').reverse().join('')
        return valueNum >= 0 ? valueArray.join('.') : ('-' + valueArray.join('.'))
}

/**
 * 
 * 金额加,分隔符
 * **/
export function formatCurrency1(num) {
	//将num中的$,去掉,将num变成一个纯粹的数据格式字符串
	num = num.toString().replace(/\$|\,/g, '');
	//如果num不是数字,则将num置0,并返回
	if ('' == num || isNaN(num)) {
		return '0';
	}
	//如果num是负数,则获取她的符号
	var sign = num.indexOf("-") >= 0 ? '-' : '';
	if (num.indexOf("-") >= 0) {
		num = num.substring(1)
	}
	//如果存在小数点,则获取数字的小数部分
	var cents = num.indexOf(".") > 0 ? num.substr(num.indexOf(".")) : '';
	cents = cents.length > 1 ? cents : ''; //注意:这里如果是使用change方法不断的调用,小数是输入不了的
	//获取数字的整数数部分
	num = num.indexOf(".") > 0 ? num.substring(0, (num.indexOf("."))) : num;
	//如果没有小数点,整数部分不能以0开头
	if ('' == cents) {
		if (num.length > 1 && '0' == num.substr(0, 1)) {
			return '0! ';
		}
	}
	//如果有小数点,且整数的部分的长度大于1,则整数部分不能以0开头
	else {
		if (num.length > 1 && '0' == num.substr(0, 1)) {
			return '0! ';
		}
	}
	//针对整数部分进行格式化处理,这是此方法的核心,也是稍难理解的一个地方,逆向的来思考或者采用简单的事例来实现就容易多了
	/*
	  也可以这样想象,现在有一串数字字符串在你面前,如果让你给他家千分位的逗号的话,你是怎么来思考和操作的?
	  字符串长度为0/1/2/3时都不用添加
	  字符串长度大于3的时候,从右往左数,有三位字符就加一个逗号,然后继续往前数,直到不到往前数少于三位字符为止
	 */
	for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
		num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3));
	}
	//将数据(符号、整数部分、小数部分)整体组合返回
	return (sign + num + cents);
}

function maxDecimal(number, num) {
	let regExp = new RegExp("^(.\*\\..{" + num + "}).*$")
	return String(number).replace(regExp, "$1")
}

数字处理方法tools.js:

 // 字符串true、false转布尔true、false
    String.prototype.toBool = function(){
        return (/^true$/i).test(this);
    }

    //清除字符串首尾空格
    String.prototype.trim=function(){
        return this.replace(/^(\s|`)+|(\s|`)+$/g, '')
    }
     // 格式数字千分
   String.prototype.kB=Number.prototype.kB=function(){
         
          const valueArray = this.toString().split('.')
          const valueNum = Number(valueArray[0].toString().replace(/,/g, ''))
           valueArray[0] = Math.abs(valueNum).toString().split('').reverse().join('').replace(/(\d{3})/g, function(word) {
            return word + ','
          }).replace(/^(\s|,)+|(\s|,)+$/g, '').split('').reverse().join('')
         return valueNum >= 0 ? valueArray.join('.') : ('-' + valueArray.join('.'))
   }

const tools={
   // 加、减、乘、除浮点计算
  priceFigure(value1, value2, type = '-') {
    value1 = value1 || 0
    value2 = value2 || 0
    const decimals1 = value1.toString().indexOf('.') != -1 ? value1.toString().split('.').at(-1) : null
    const decimals2 = value2.toString().indexOf('.') != -1 ? value2.toString().split('.').at(-1) : null
    let extNum = decimals1 ? decimals1.length : 0
    if (decimals2 && decimals2.length > extNum) {
      extNum = decimals2.length
    }
    let extLength = extNum
    extLength = extLength % 2 == 0 ? extLength + 1 : extLength
    let num = 0
    if (type == '+') {
      num = ((Number(value1) * Math.pow(10, extLength)) + (Number(value2) * Math.pow(10, extLength))) / Math.pow(10, extLength)
    }
    if (type == '-') {
      num = ((Number(value1) * Math.pow(10, extLength)) - (Number(value2) * Math.pow(10, extLength))) / Math.pow(10, extLength)
    }
    if (type == '*') {
      num = ((Number(value1) * Math.pow(10, extLength)) * (Number(value2) * Math.pow(10, extLength))) / (Math.pow(10, extLength) * Math.pow(10, extLength))
    }
    if (type == '/') {
      num = ((Number(value1) * Math.pow(10, extLength)) / (Number(value2) * Math.pow(10, extLength)))
    }

    return num
  },
  numFormatK(value){
      if (!value) return 0
      // 方法一:
       const valueArray = value.toString().split('.')
      valueArray[0] = valueArray[0].toString().replace(/,/g, '').split('').reverse().join('').replace(/(\d{3})/g, function(word) {
        return word + ','
      }).replace(/^(\s|,)+|(\s|,)+$/g, '').split('').reverse().join('')
      return valueArray.join('.')
      
      // 方法一:
      // const value_zhi = value.toString().split(',').join('')
      // const value_zhiArray = value_zhi.split('.')
      // if (value_zhiArray[0] == '') {
      //   return ''
      // }
      // const oneNumArray = value_zhiArray[0].split('').reverse()
      // const numArray = new Array(oneNumArray.length).fill('null')
      // const qianArray = []
      // if (numArray.length >= 3) {
      //   numArray.forEach((_, index) => {
      //     if (index % 3 == 0 && index > 0) {
      //       qianArray.push(index)
      //     }
      //   })
      // }
      // let num = 0
      // qianArray.forEach(item => {
      //   oneNumArray.splice(item + num, 0, ',')
      //   num++
      // })
      // return oneNumArray.reverse().join('') + (value_zhiArray.length > 1 ? `.${value_zhiArray[1]}` : '')
    }

}
export default tools



挂载其他方法,包括filters.js :

//引入filters.js
import * as filters from '@/common/utils/filters.js'
//引入tools.js
import * as tools from '@/common/utils/tools.js'

let authList=[]//权限列表
const install=(Vue,router)=>{
  //挂载filters.js
 Object.keys(filters).forEach(key => {
	    Vue.filter(key,filters[key])
	    Vue.prototype[key] = filters[key];
 })
// 挂载 tools.js里面的方法
Object.keys(tools).forEach(key => {
    Vue.prototype['$'+key]=tools[key]
})

//html标签处理
Vue.prototype.$htmlChange=(str)=>{
      const objectFn = {
        // 获取标签上面的数据
        getDomValue(word, type, value) {
          const regXLink = RegExp(`<${type}`, 'g')
          const regXLink1 = RegExp(`${type}>`, 'g')
          const wordDiv = word.replace(regXLink, '<div').replace(regXLink1, 'div>')
          const Dom = document.createElement('div')
          Dom.innerHTML = wordDiv
          return Dom.children[0].getAttribute(value)
        },
        // 打电话
        // <phone>10086</phone>
        phoneChange: (word, type, text) => {
          return `<a  href='tel:${text}'>${text}</a>`
        },
        // 发短信
        // <sms phone='10086' message='短信消息'>短信</sms>
        smsChange: (word, type, text) => {
          const phone = objectFn.getDomValue(word, type, 'phone')
          const message = objectFn.getDomValue(word, type, 'message')
          return `<a  href='sms:${phone}?body=${message}'>${text}</a>`
        },
        // 发送位置
        // <location location='116.281469,39.866035'>发送位置</location>
        locationChange: (word, type, text) => {
          const location = objectFn.getDomValue(word, type, 'location')
          return `<a href="geopoint:${location}">${text}</a>`
        },
        // 发送邮件
        // <email>15683520@qq.com</email>
        emailChange: (word, type, text) => {
          return `<a href="mailto:${text}">${text}</a>`
        },
        init: (str) => {
          if (!str) return
          const regX = RegExp(`<[a-zA-Z]+.*?>([\\s\\S]*?)<\/[a-zA-Z]*?>`, 'gm')
          return str.replace(regX, function(word, text) {
            let type = ''
            word.replace(/<\/[a-zA-Z]*?>/gm, function(wordType) {
              type = wordType.replace('</', '').replace('>', '')
              return wordType
            })
            // 运行特殊处理的标签方法
            if (objectFn[`${type}Change`]) {
              return objectFn[`${type}Change`](word, type, text)
            } else {
              // 没有方法就不处理
              return word
            }
          })
        }
      }
      return objectFn.init(str)
    }
    // 判断元素是否被隐藏(会一直往上查 ,查询父级有没有隐藏。元素隐藏,display:none) 
     Vue.prototype.$getIsNone=(el)=>{
        const getAllComputedStyle=(obj,property)=>{      
          if(window.getComputedStyle){
            //现在要把用户输入的property中检测一下是不是驼峰,转为连字符写法
            //强制把用户输入的词儿里面的大写字母,变为小写字母加-
            //paddingLeft  →  padding-left
            property = property.replace(/([A-Z])/g , function(match,$1){
              return "-" + $1.toLowerCase();
            });
            return window.getComputedStyle(obj)[property];
          }else{
            //IE只认识驼峰,我们要防止用户输入短横,要把短横改为大写字母
            //padding-left  → paddingLeft 
            property = property.replace(/\-([a-z])/g , function(match,$1){
              return $1.toUpperCase();
            });
            return obj.currentStyle[property];
          }
        }
        const getNone=(el)=>{
             if(el.nodeName!='BODY'){
                if(getAllComputedStyle(el,'display')=='none'){
                     return true
                }
                return  getNone(el.parentNode) 
            }
            return false
        }
        return getNone(el)
    }  

   // 获取相同元素在页面的显示节点方法一,
  // {
  //   el: '.box-item',//显示的盒子
  //   scrollDom: '.main-wrapper',//滚动的盒子,页面滚动传递'window',默认'window'
  //   isRepetition: true,//是否重复获取,默认true
  //   lookRatio: 0//显示盒子的判断比例,默认0(表示只要显示一点就说明在页面上)
  // }
   Vue.prototype.$getDomViewShow=(objectData)=>{
    const { el, scrollDom = 'window', isRepetition = true, lookRatio = 0 } = objectData
    let scrollY = 0
    if (scrollDom != 'window' && document.querySelector(scrollDom)) {
      scrollY = document.querySelector(scrollDom).getBoundingClientRect().y
    }
    const getDom = (domEl, parent = null) => {
      const elArray = domEl.split(' ').filter(n => n != '')
      const parentDom = parent || document
      let thisDom = null
      try {
        thisDom = parentDom.querySelectorAll(elArray[0])
      } catch (_) {
        thisDom = [parentDom.querySelector(elArray[0])]
      }
      const nextArray = elArray.slice(1, elArray.length)
      if (nextArray.length > 0) {
        return getDom(nextArray.join(' '), thisDom[0])
      } else {
        return thisDom
      }
    }
    const Dom = getDom(el)
    const DomArray = []
    if (Dom) {
      Dom.forEach(item => {
        const clientRect = item.getBoundingClientRect()
        const isViewShow = item.getAttribute('isViewShow') || 0
        if (clientRect.y >= 0) {
          if (clientRect.y <= window.innerHeight && (window.innerHeight - clientRect.y) >= item.offsetHeight * Number(lookRatio)) {
            if (isViewShow == 0) {
              item.setAttribute('isViewShow', 1)
              DomArray.push(item)
            }
          } else {
            if (isRepetition)item.setAttribute('isViewShow', 0)
          }
        } else {
          if (Math.abs(clientRect.y + scrollY) <= item.offsetHeight * (1 - Number(lookRatio))) {
            if (isViewShow == 0) {
              item.setAttribute('isViewShow', 1)
              DomArray.push(item)
            }
          } else {
            if (isRepetition)item.setAttribute('isViewShow', 0)
          }
        }
      })
    }
    return DomArray
  }
    
    // 获取相同元素在页面的显示节点方法二,
    // {
    //   el: '.card-item',//显示的盒子
    //   scrollDom:document.querySelector('.main-wrapper'),//滚动的盒子,不传默认null
    //   isRepetition: false,//是否重复获取,默认false
    //   lookRatio: 0//显示盒子的判断比例,默认0(表示只要显示一点就说明在页面上)
    // }
    // this.$getDomViewShow2({
    //       el: '.card-item'
    // }).then(res => {
    //    console.log(res)
    // })
    Vue.prototype.$getDomViewShow2=(obj)=>{
      return new Promise((r, _) => {
        const { el, scrollDom = null, isRepetition = false, lookRatio = 0 } = obj
        const options = {
          root: scrollDom,
          rootMargin: '0px',
          threshold: lookRatio
        }
        const observer = new IntersectionObserver((entries) => {
          const arrayDom = []
          entries.forEach(item => {
            if (item.isIntersecting) {
              arrayDom.push(item.target)
              item.target.setAttribute('isViewShow', 1)
              if (!isRepetition) {
                 observer.unobserve(item.target)
              }
            }else{
              if(isRepetition){
                 item.target.setAttribute('isViewShow', 0)
               }
            }
          })
          r(arrayDom)
        }, options)
        const getDom = (domEl, parent = null) => {
          const elArray = domEl.split(' ').filter(n => n != '')
          const parentDom = parent || document
          let thisDom = null
          try {
            thisDom = parentDom.querySelectorAll(elArray[0])
          } catch (_) {
            thisDom = [parentDom.querySelector(elArray[0])]
          }
          const nextArray = elArray.slice(1, elArray.length)
          if (nextArray.length > 0) {
            return getDom(nextArray.join(' '), thisDom[0])
          } else {
            return thisDom
          }
        }
        const Dom = getDom(el)
        // 关闭监视器
        observer.disconnect()
        Dom.forEach(item => {
          // 关闭监察
          observer.unobserve(item)
          if (item.getAttribute('isViewShow') != 1) {
            observer.observe(item)
          }else{
            if(isRepetition){
               item.setAttribute('isViewShow', 0)
            }
          }
        })
      })
    }

    
    // 深拷贝
    Vue.prototype.$deepCopy = (data) => {
      const map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object'
      }
      const fn = (data) => {
          const type = map[Object.prototype.toString.call(data)]
          let dataObjectArray = null
          if (type == 'array') {
            dataObjectArray = []
            data.forEach(item => {
              dataObjectArray.push(fn(item))
            })
            return dataObjectArray
          } else if (type == 'object') {
            dataObjectArray = {}
             for (const key in data) {
              dataObjectArray[key] = fn(data[key])
            }
            return dataObjectArray
          } else {
            return data
          }
        }
      return fn(data)
    }

     /**
     * 设备类型
     * @param 1.ios App
     * @param 2.android App
     * @param 3.wap
     * @param 4.wechat
     * @param 5.小程序
     * @param 5.钉钉
     */
    Vue.prototype.deviceType = function () {
      let useragent = window.navigator.userAgent,
        ua = window.navigator.userAgent.toLowerCase();
      if (useragent.indexOf("iOS_APP") != -1) {//ios
        return 1;
      } else if (useragent.indexOf("ANDROID_APP") != -1) {//android
        return 2;
      } else if (ua.match(/MicroMessenger/i) == "micromessenger") {//微信环境
        //需引入weixin-js-sdk依赖
        wx.miniProgram.getEnv((res) => {
          if (res.miniprogram) { //在微信小程序中
            return 5;
          } else { //在微信浏览器
            return 4;
          }
        });
      } else if(useragent.indexOf('DingTalk')!=-1){//钉钉环境
        return 6;
      }else {//其他
        return 3;
      }
    }

     // 权限列表判断,使用 v-auth='权限名'
    Vue.directive('auth', {
        inserted:(el, binding)=>{
            let value=binding.value
            if(authList.indexOf(value)==-1){
                el.parentNode.removeChild(el)
            }
        }
    })

    // 总线跨页面传值
    //this.$HWBUS.$on('fn',res=>{
    //     console.log(res)
    // })//监听
    // this.$HWBUS.$emit('fn',999)//传值
    Vue.prototype.$HWBUS=new Vue()
    

    // 替换文本中的${xx}参数
    // const data = {
    //  date: '2022-12-02',
    //  name: 'xxx',
    //  address: '上海'
    // }
    // const str = '${name}于${date},出生于${address}'
    // console.log(this.$analysis(str, data)) //xxx于2022-12-02,出生于上海
    Vue.prototype.$analysis=(str, data, matchArray = ['${', '}']) => {
        // const regX = RegExp(`<[a-zA-Z]+.*?>([\\s\\S]*?)<\/[a-zA-Z]*?>`, 'gm')
        const regX = RegExp(`\\${matchArray[0]}+.*?([\\s\\S]*?)${matchArray[1]}.*?`, 'g')
        return str.replace(regX, function(word, key) {
          const returnData = data[key] || null
          if (returnData) {
            return returnData
          }
          return word
        })
     }
    
    //格式化字符串里面的html,并添加样式
    Vue.prototype.$formatHtml(val) {
      const sing = '`'
      const regxd = RegExp(`${sing}<[^${sing}]+>${sing}`, 'g')
      val = val.replace(regxd, function(word) {
        if (/<[^<]+>/g.test(val)) { // 判断是否存在html标签
          const getHtml = (word) => {
            let wordString = word.replace(/^(\s|`)+|(\s|`)+$/g, '')// 清除前后`符号
            const htmlArray = []
            wordString.replace(/<\/[^<]+>/g, function(word1) { // 获取每个标签类型的结束标签,即存在/的标签,比如:</div>
              htmlArray.push(word1.replace(/^(\s|<\/)+|(\s|>)+$/g, ''))// 获取html里面存在的标签,并清除前<,后>
            })
            // 获取html标签以及中间的值
            const htmlText = []
            htmlArray.forEach(item => {
              const regX = RegExp(`<${item}[^<]+<\/${item}>`, 'g')
              console.log(regX)
              wordString.replace(regX, function(word2) {
                htmlText.push(word2)
              })
            })
            console.log(htmlText)
            htmlText.forEach(item => {
              var ele = document.createElement('span')
              ele.appendChild(document.createTextNode(item))
              wordString = wordString.replace(RegExp(item, 'g'), `<span class='codeHtml' style='display: inline-block;padding: 4px 2px;background-color: #fff5f5;color: #ff502c;border-radius: 2px;'>${ele.innerHTML}</span>`)
            })
            return wordString
          }
          return getHtml(word)
        } else {
          return word
        }
      })
      return val
    }

    // 选中文本、div、select()
    Vue.prototype.$selectText = (element) => {
      var text = document.getElementById(element)
      var range
      if (document.body.createTextRange) {
        range = document.body.createTextRange()
        range.moveToElementText(text)
        range.select()
      } else if (window.getSelection) {
        var selection = window.getSelection()
        range = document.createRange()
        range.selectNodeContents(text)
        selection.removeAllRanges()
        selection.addRange(range)
        /* if(selection.setBaseAndExtent){
              selection.setBaseAndExtent(text, 0, text, 1);
          }*/
      } else {
        console.log('none')
      }
    }


    // 防止重复点击 this.$throttle(()=>{fn()},isClick,(res)=>{isClick=res} )()
    Vue.prototype.$repeatClick = (fn, isClick, cb) => {
      return function() {
        const context = this
        const args = arguments
        if (isClick) {
          fn.apply(context, args)
          cb && cb(false)
        }
      }
    }
    // 事件节流(多少秒内只能执行一次)
    // fn:方法
    // 时间
    // this.$throttle(fn, 500) || this.$throttle(()=>{fn()}, 500)()
    Vue.prototype.$throttle = (fn, delayTime) => {
      let clickTime = 0
      return function() {
        const context = this
        const args = arguments
        const nowTime = new Date()
        if (nowTime - clickTime > delayTime) {
          fn.apply(context, args)
          clickTime = nowTime
        }
      }
    }
    // 事件防抖(多少秒后执行,再次调用重新计算,比如监听滚动停止等)
    // immediate:是否立即执行
    // this.$debounce(fn, 500) || this.$debounce(()=>{fn()}, 500)()
    Vue.prototype.$debounce = (fn, delayTime, immediate) => {
      let timeout
      return function() {
        const context = this
        const args = arguments
        if (timeout) clearTimeout(timeout)
        if (immediate) {
          var callNow = !timeout
          timeout = setTimeout(() => {
            timeout = null
          }, delayTime)
          if (callNow) fn.apply(context, args)
        } else {
          timeout = setTimeout(() => {
            fn.apply(context, args)
          }, delayTime)
        }
      }
    }
    
    // 计算日期
	Vue.prototype.$getDate=(option={})=>{
		    const {value=null,numD=0,numM=0,numY=0,dayArray=['周一','周二','周三','周四','周五','周六','周天']}=option
			let d=null
			if(!value){
				d=new Date()
			}else{
				let valueSuccess=value.split('-').join('/')
				valueSuccess=value.split('.').join('/')
				d=new Date(valueSuccess)
			}
			
			d.setDate(d.getDate()+numD)
			d.setMonth(d.getMonth()+numM)
			d.setFullYear(d.getFullYear()+numY)
			let yy=d.getFullYear()
			let mm=d.getMonth()+1
			mm=mm<10?'0'+mm:mm
			let dd=d.getDate()
			dd=dd<10?'0'+dd:dd
			let m=d.getMinutes()
			m=m<10?'0'+m:m
			let s=d.getSeconds()
			s=s<10?'0'+s:s
			let day=d.getDay()
			day=day==0?7:day
			let ymd=`${d.getFullYear()}-${d.getMonth()+1}-${d.getDate()}`
			let yymmdd=`${yy}-${mm}-${dd}`
			return{
				yy,mm,dd,m,s,day,dayText:dayArray[day-1],
				ymd:ymd,
				yymmdd:yymmdd,
				ymdms:`${ymd} ${m}:${s}`,
				yymmddms:`${yymmdd} ${m}:${s}`,
			}
	},

     // 判断数据类型
    Vue.prototype.$typeOf=(value)=>{
        let str=Object.prototype.toString.call(value)
        str=str.replace('object','').replace('[','').replace(']','')
        str=str.replace(/(^\s*)|(\s*$)/g, "").toLowerCase()
        if(value=='null' || value=='undefined'){
            str=typeof(value) 
        }
        return str
    }


    // 打印操作
    // html:需要打印页面的html代码,样式必须行内
    // type:需不需要打印
    Vue.prototype.$printFn=(html,type=1)=>{
        var userAgent = navigator.userAgent.toLowerCase(); //取得浏览器的userAgent字符串
            if (userAgent.indexOf("trident") > -1) {
              this.$message.error('请使用google或者360浏览器打印')
              return false;
            } else if (userAgent.indexOf('msie') > -1) {
              this.$message.error('请使用google或者360浏览器打印')
              return false;
            } else {//其它浏览器使用lodop
              var headstr = "<html><head><title></title></head><body>";
              var footstr = "</body></html>";
              var printData = html; //获得 div 里的所有 html 数据
              var wind = window.open("", "newwin","toolbar=no,scrollbars=yes,menubar=no");
              wind.document.body.innerHTML = headstr + printData + footstr;
              if(type==1){
                wind.print();
              }
        }
    }
    // 去除字符串空格
    // isBoolean=true:当数据为空字符串的时,返回false
    Vue.prototype.$trim=(str,isBoolean)=>{
        if (str == null) {
          str = "";
        }
        let thisStr=str.replace(/(^\s*)|(\s*$)/g, "")
        if(isBoolean){
            if(thisStr==''){
                return false
            }else{
                return thisStr;
            }
        }
        return thisStr;
    }
    // 文件预览
    // ops = {
        // "pdf": true, //word文档尝试以pdf方式显示,默认false
        // "watermark": "XDOC文档预览", //水印文本,显示水印
        // "saveable": false, //是否允许保存PDF,默认true
        // "printable": false, //是否允许打印PDF,默认true
        // "copyable": false, //是否允许选择复制内容,默认true
        // "toolbar": false, //是否显示底部工具条,默认true
        // "title": "文档预览", //自定义标题
        // "expire": 30, //预览链接有效期,单位分钟,默认永久有效
        // "limit": "1,3", //限制页数,如:“5”表示只显示前5页,“2,5”表示从第2页开始的5页,对pdf/doc/docx/ppt/pptx有效
        // "mtime": 1633093801, //文件修改时间戳(精确到秒)或修改时间(如:2021-10-01 21:10:01),值改变刷新缓存,实时预览
    // };
    Vue.prototype.$previewFile=(value,ops={})=>{
        let url=`http://view.xdocin.com/xdoc?_xdoc=${value}`
        for (var a in ops) {
            url += "&" + a + "=" + encodeURIComponent(ops[a]);
            
         }
        window.open(url)
    },
    // 文件下载
    Vue.prototype.$downloadFile=(content,fileName='')=>{
        if(content instanceof Array){
            content.forEach(item=>{
                let aLink = document.createElement('a')
                aLink.download = fileName;
                aLink.setAttribute('href',item)
                // a.href = url
                aLink.click()
            })
        }else{
            let aLink = document.createElement('a')
            aLink.download = fileName;
            aLink.setAttribute('href',content)
            // a.href = url
            aLink.click()
        }
       
    },
    // 计算时间差
    Vue.prototype.$dayCha=(value,geshi='天-小时-分-秒',type='string')=>{
        let geshiArray=geshi.split('-')
        var chaTime=value;
        var day=parseInt(chaTime/86400)
        var yu=chaTime % 86400
        var hour=parseInt(yu/3600)
        var yuH=yu % 3600
        var min=parseInt(yuH/60)
        var yuM=yuH%60
        var sec=yuM
        if(type=='string'){
            let str=''
            if(day>0)str+=day+geshiArray[0]
            if(hour>0)str+=hour+geshiArray[1]
            if(min>0)str+=min+geshiArray[2]
            if(sec>0)str+=sec+geshiArray[3]
            if(str==''){
                str='-'
            }
            return str
        }else{
            return {day:day,hour:hour,minute:min,second:sec}
        }
        
    }


    // 复制
    Vue.prototype.$copyToClipboard=(value, cb)=>{
        const textarea = document.createElement("textarea");
        textarea.value = value;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand("copy");
        document.body.removeChild(textarea);
        cb && cb();
    }
    // 页面跳转
    //  type跳转方式:push新增,back 返回,replace 替换,_blank 新开
    // $toPage('/about') 或 $toPage({url:'/about',data:{},callbck:()=>{}})
    Vue.prototype.$toPage=(toData,type='push',is_other=false)=>{
        // console.log(toData,type)
        if(is_other){
            window.open(toData)
            return false;
        }else{
            if(typeof(toData)=='string'){
                if(type=='push'){
                    router.push({ path: toData})
                }else if(type=='back'){
                    router.go(-1)
                }else if(type=='_blank'){
                    let routeUrl = router.resolve({
                            path: toData,
                    });
                    window.open(routeUrl.href, '_blank');
                }else{
                    router.replace({ path: toData})
                }
            }else{
                const {url='/',data={}}=toData
                const queryData=Object.assign({},data)
                if(queryData.callbck)delete queryData.callbck;
                if(type=='push'){
                    router.push({ path: url, query:queryData})
                    setTimeout(()=>{
                        if(data.callbck)data.callbck(true)
                    },0)
                }else if(type=='back'){
                    router.go(-1)
                    setTimeout(()=>{
                        if(data.callbck)data.callbck(true)
                    },0)
                }else if(type=='_blank'){
                    let routeUrl =router.resolve({
                        path: url,
                        query:queryData
                    });
                    window.open(routeUrl.href, '_blank');
                    setTimeout(()=>{
                        if(data.callbck)data.callbck(true)
                    },0)
                }else{
                    router.replace({ path: url, query:queryData})
                    setTimeout(()=>{
                        if(data.callbck)data.callbck(true)
                    },0)
                }
            }
        }
       
       
    },

   

    // 获取页面url参数
    Vue.prototype.$getQueryVariable = (variable) => {
        var vars = []
        // 如果存在#号
        if (window.location.hash != '') {
            // 取消#号
            let hashUrk= window.location.hash.replace('#','')
            // 取值
            var query0 = hashUrk.includes('?')?hashUrk.split('?')[1]:hashUrk;
            let queryArray=query0.split("&").map(item=>{
                if(item.includes('=')){
                    return item
                }else{
                    return '#'+item+'='+item
                }
            })
            if (query0) vars.push(...queryArray);
        } 
        // 如果存在参数
        if(window.location.search != '') {
            var query = window.location.search.substring(1);
            if (query)vars.push(...query.split("&"));
        }
        let queryObject = {}
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split("=");
            queryObject[pair[0]] = pair[1]
        }
        if (variable) {
            if (queryObject[variable] && queryObject[variable] != '') {
                return queryObject[variable]
            } else {
                return false;
            }
        } else {
            return queryObject
        }
    }

    //  修改浏览器url链接和带的参数,不会刷新页面,同时修改route的参数,value不传就会清除当前参数
    Vue.prototype.$setLocaUrlQuery = (key, value='') => {
        let str_url = window.location.href.split('?')[0];
        let data = Vue.prototype.$getQueryVariable()
        if (value == '') {
            delete data[key]
            if (router) delete router.app._route.query[key]
        } else {
            data[key] = value
            if (router) router.app._route.query[key]=value
        }
        let data_str = [];
        Object.keys(data).forEach(item => {
            data_str.push(`${item}=${data[item]}`)
        })
        if (data_str.length > 0) {
            str_url = str_url + '?' + data_str.join('&')
        } else {
            str_url = str_url
        }

        history.replaceState({}, document.title, str_url);
    }
    // 生成唯一UUid
    Vue.prototype.$uuid=()=>{
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;    // d是随机种子
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }

    //修改浏览器title
     Vue.prototype.$ChangePageTitle = (title) => {
        let userAgentObj = JSON.parse(localStorage.getItem('userAgentObj')) || null
        if (userAgentObj && userAgentObj.isDingTalk) {//钉钉内
            window.$dd.ready(function () {
                window.$dd.biz.navigation.setTitle({
                    title: title,//控制标题文本,空字符串表示显示默认文本
                    onSuccess: function (result) {
                    },
                    onFail: function (err) { }
                });
            });
        } else {//微信或浏览器内
            document.title = title;//普通浏览器用这一句就可以修改了
            //微信浏览器需要在页面添加一个 <iframe style="display: none"></iframe>
            //加载成功后 立即删除
        }
    }


 /**
 * 高德/腾讯经纬度转百度地图经纬度
 * @param {Object} lng
 * @param {Object} lat
 */
 Vue.prototype.$qgMapTransBMap=(lng, lat)=>{
    let x_pi = (3.14159265358979324 * 3000.0) / 180.0
    let x = lng
    let y = lat
    let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi)
    let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi)
    let lngs = z * Math.cos(theta) + 0.0065
    let lats = z * Math.sin(theta) + 0.006
    return {
      lng: lngs,
      lat: lats,
    }
  },
  /**
   * 百度地图经纬度转高德/腾讯地图经纬度
   * @param {Object} lng
   * @param {Object} lat
   */
   Vue.prototype.$bMapTransqgMap=(lng, lat)=>{
    let x_pi = (3.14159265358979324 * 3000.0) / 180.0
    let x = lng - 0.0065
    let y = lat - 0.006
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi)
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi)
    let lngs = z * Math.cos(theta)
    let lats = z * Math.sin(theta)
    return {
      lng: lngs,
      lat: lats,
    }
  }
  /**
   * 获取当前时间
   */
   Vue.prototype.$getTime=() => {
           var now = new Date();
           var year = now.getFullYear(); //得到年份
           var month = now.getMonth(); //得到月份
           var date = now.getDate(); //得到日期
           var day = now.getDay(); //得到周几
           var hour = now.getHours(); //得到小时
           var minu = now.getMinutes(); //得到分钟
           var sec = now.getSeconds(); //得到秒
           var MS = now.getMilliseconds(); //获取毫秒
           var week;
           month = month + 1;
           if (month < 10) month = "0" + month;
           if (date < 10) date = "0" + date;
           if (hour < 10) hour = "0" + hour;
           if (minu < 10) minu = "0" + minu;
           if (sec < 10) sec = "0" + sec;
           if (MS < 100) MS = "0" + MS;
           var arr_week = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
           week = arr_week[day];
           var time = "";
           time = year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec;
           date = year + "-" + month + "-" + date;
           return {time,date}
}
 /**
   * 跳转QQ
   * value:qq号
   */
  Vue.prototype.$toQQ=(value) => {
    window.location.href=`tencent://message/?uin=${value}`
  }
//  手机号隐藏中间四位
  Vue.prototype.$geTel=(tel)=>{
    var reg = /^(\d{3})\d{4}(\d{4})$/;  
        return tel.replace(reg, "$1****$2");

 }

// 获取视频第一帧
Vue.prototype.$getVideoImg=(url, time = 0)=>{
      return new Promise((r, j) => {
        const video = document.createElement('video') // 创建video对象
        video.src = url // url地址
        const canvas = document.createElement('canvas') // 创建 canvas 对象
        const ctx = canvas.getContext('2d') // 绘制2d
        video.crossOrigin = 'anonymous' // 解决跨域问题,也就是提示污染资源无法转换视频
        video.currentTime = 1 // 第一秒帧
        video.oncanplay = () => {
          canvas.width = video.videoWidth
          canvas.height = video.videoHeight
          // 利用canvas对象方法绘图
          ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
          r(canvas.toDataURL('image/png'))
          // 转换成base64形式
          // canvas.toDataURL('image/png')
          // 转换成blob
          // canvas.toBlob(function(blob){
          //   console.log(blob,'--blob--')
          // },'image/png')
        }
      })
    }

// 是否存在
    Vue.prototype.$isset=(list,name)=>{
        if(Vue.prototype.$typeOf(list)=='object'){
            if(Object.hasOwnProperty.call(list,name)){
                return true;
            }else{
                return false;
            }
            // list.hasOwnProperty(name)
            // var keys=Object.keys(list)
            // if(keys.indexOf(name)!=-1){
            //   return true;
            // }else{
            //   return false;
            // }
        }else{
            try{
                var value=list[name].toString()
                if(value && value!='' && value!='NAN' && value!=undefined){
                  return true;
                }else{
                  return false;
                }
            }catch(err){
              return false;
            }
        }
       
     }
    
}
export default  install

自定义指令: 

<span v-auth="'placeorder'">更多</span>

Vue.directive("auth", {
  inserted: (el, binding) => {
    el.style.display = "none";
    let key = "";
    let txt = "";
    if (data instanceof Object) {
      key = binding.value.key;
      txt = binding.value.txt;
    } else {
      key = binding.value;
    }
    // 存在权限
    if (key) {
      el.style.display = "revert";
    } else {
      // 存在可替换的值,就实现替换
      if (txt != "") {
        // document.createTextNode
        const Dom = document.createElement("div");
        Dom.innerHTML = txt;
        const styleObject = { display: "", width: "", height: "" };
        const styleArray = [
          ...Object.entries(styleObject).map((item) => {
            if (window.getComputedStyle) {
              return `${item[0]}:${window
                .getComputedStyle(el)
                .getPropertyValue(item[0])}`;
            } else {
              return `${item[0]}:${el.currentStyle[item[0]]}`;
            }
          }),
          "text-align:center",
        ];
        Dom.style = styleArray.join(";");
        el.parentNode.replaceChild(Dom, el);
      } else {
        // 没有可替换的,就删除
        el.parentNode.removeChild(el);
      }
    }
  },
});

自定义指令也像组件那样存在钩子函数:

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
unbind:只调用一次,指令与元素解绑时调用

钩子函数的参数都有以下:

el:指令所绑定的元素,可以用来直接操作 DOM

binding:一个对象,包含以下 property:


`name`:指令名,不包括 v- 前缀。

`value`:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

`oldValue`:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

`expression`:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

`arg`:传给指令的参数,可选。例如 v-my-directive:xx中,参数为 "xx"。

`modifiers`:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }

`vnode`:Vue 编译生成的虚拟节点

`oldVnode`:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

可参考:vue自定义指令 官网vue2

使用:
 

import install from './assets/appConfig/install'
install(Vue) 

uniapp返回页面方法以及判断:

/**
 * 返回页面执行方法
 * index 返回的页数,默认1 返回上一页
 */
export function navigateBack(index=1) {
	return new Promise((r, j) => {
		const pages = getCurrentPages();
		const beforePage = pages[pages.length - (index+1)];
		if (!beforePage) {
			// uni.showToast({
			// 	title: '前面没有页面啦~',
			// 	icon: 'none'
			// })
			j()
		}
		// #ifdef H5
		r({
			beforePage,
			navigateBack() {
				uni.navigateBack({
					delta:index
				})
			}
		})
		// #endif
		// #ifndef H5
		r({
			beforePage: beforePage.$vm,
			navigateBack() {
				uni.navigateBack({
					delta:index
				})
			}
		})
		// #endif
	})

}

使用: 

//可以传值 navigateBack(2),表示返回上两页

navigateBack().then(res => {
             const {
                             beforePage,
                             navigateBack
           } = res
           //beforePage,返回页面的this,可以获取返回页面的数据和方法
           navigateBack()//返回
 })

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值