首页 > 其他分享 >Web笔记

Web笔记

时间:2023-05-19 09:47:17浏览次数:45  
标签:function Web return graph 笔记 let new const

WEB

vue

组件

全局组件

在main.js中注册

//引入组件
import TypeNav from '@/components/TypeNav'
// 第一个参数:全局组件的名字  第二个参数:哪一个组件
Vue.component(TypeNav.name,TypeNav)

使用:无需引入,直接使用标签

<TypeNav />

节流和防抖

lodash

节流:

在规定的间隔时间范围内不会重复出发回调,只有大于这个时间间隔才会出发回调,把频繁出发变为少量触发。

//lodash
import throttle from "lodash/throttle";
testfuntion: throttle(funtion(){
	console.log('每秒只执行一次')
},1000)
//使用定时器写法
function throttle(fn, delay) {
            let flag = true
            return function () {
                if (flag) {
                    setTimeout(() => {
                        fn.call(this)
                        flag = true
                    }, delay)
                }
                flag = false
            }
        }

vue中使用

封装方法

//	utils/index.js文件内
/**
 * 节流
 * @param {Function} fn 
 * @param {Number} delay 
 * @returns 
 */
export function throttle(fn, delay) {
  //距离上一次的执行时间
  let lastTime = 0;
  return function () {
    let _this = this;
    let _arguments = arguments;
    let now = new Date();
    //如果距离上一次执行超过了delay才能再次执行
    if (now - lastTime > delay) {
      fn.apply(_this, _arguments);
      lastTime = now;
    }
  };
}

引入使用

import { throttle } from "@/utils/index";

//submit需要节流的函数事件
submit:throttle(function(){
    console.log('delay后才能触发下一次')
},delay)

防抖:

前面的所有出发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发,只会执行一次。

//使用定时器写法
function debounce(fn, delay) {
            let t = null
            return function () {
                if (t !== null) {
                    clearTimeout(t)
                }
                t = setTimeout(() => {
                    fn.call(this); //改变this指向
                }, delay)
            }
        }
//vue中使用时   
// 鼠标滚动事件
    handleScroll(e) {
      let direction = e.deltaY > 0 ? "down" : "up";
      if (direction == "down") {
        // 下一页
        this.debounce(this.getNext, 200);
      } else {
        // 上一页
        this.debounce(this.getPrev, 200);
      }
    },

    // 防抖
    debounce(func, wait) {
      let context = this; //this指向变化,在return之前获得实例
      let args = arguments;
      return function () {
        if (context.timer) clearTimeout(context.timer);
        context.timer = setTimeout(() => {
          func.apply(context, args);
        }, wait);
      }(); //添加括号手动执行
    },

事件委托

Event

$nextTick

解决需数据渲染完毕,再执行DOM操作

  watch: {
    // 监听bannerList数据变化
    bannerList: {
      // 执行handler方法,代表组件实例上属性的属性值已经有了
      // 只能保证bannerList获取完毕,不能保证v-for渲染完毕
      handler(newValue, oldValue) {
        // 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
        // 它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上
        this.$nextTick(() => {
          // 保证数据已经获取并且循环已经循环已经渲染完毕,
          //再执行操作DOM
          var mySwiper = new Swiper(
            this.$refs.mySwiper,
            {
              loop: true, // 循环模式选项
              // 如果需要分页器
              pagination: {
                el: ".swiper-pagination",
                clickable: true,
              },
              // 如果需要前进后退按钮
              navigation: {
                nextEl: ".swiper-button-next",
                prevEl: ".swiper-button-prev",
              },
              // 如果需要滚动条
              scrollbar: {
                el: ".swiper-scrollbar",
              },
            }
          );
        });
      },
    },
  },

组件通信

props:

用于父子组件通信,父传子

自定义事件:

@on

@emit 可以实现子传父

父组件

<SearchSelector @trademarkInfo="trademarkInfo" />
trademarkInfo(trademark) {
      this.searchParams.trademark = `${trademark.tmId}:${trademark.tmName}`;
      this.getData();
    },

子组件

tradeMatkHandler(trademark) {
      this.$emit("trademarkInfo", trademark);
    },

全局事件总线:

$bus 全能

main.js

new Vue({
  router,
  store,
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this;
  },

}).$mount('#app')

Header/index.js

mounted() {
    // 全局事件总线清除关键字
    this.$bus.$on("clear", () => {
      this.keyword = "";
    });
  },

Search/index.js

    // 面包屑删除(关键字)
    removeKeyword() {
      this.searchParams.keyword = undefined;
      this.$bus.$emit("clear");
      this.$router.push({ name: "search", query: this.$route.query });
    },

插槽,vuex

Tips

请求

请求携带多个属性,且属性可有可无时,可赋值为undefined

发送请求时当属性值为undefined不会传给后台

数组去重

    attrInfo(attrs, attrValue) {
      let props = `${attrs.attrId}:${attrValue}:${attrs.attrName}`;
      // 数组去重
      if (this.searchParams.props.indexOf(props) == -1) {
        this.searchParams.props.push(props);
        this.getData();
      }
    },

Filter()检查数组

totalPrice() {
      let sum = 0;
      let list = this.cartInfoList;
      // function checked(list) {
      //   return list.isChecked == 1;
      // }
      list
        .filter((list) => {
          //返回数组中满足条件的值
          return list.isChecked == 1;
        })
        .forEach((item) => {
          sum += item.skuNum * item.skuPrice;
        });
      return sum;
    },

vue-router

路由

push和replace重写

call||apply区别
相同点:都可以调用函数一次,都可以篡改函数的上下文一次
不同点:call与apply传递参数:call传递参数用逗号隔开,apply方法执行,传递数组

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 重写push方法
// 保存push||replace原型
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace
// 第一个参数:告诉原来的push方法,往哪里跳转(传递哪些参数)
// 第二个参数:成功的回调
// 第三个参数:失败的回调
VueRouter.prototype.push = function(location,resolve,reject){
  if(resolve && reject){
    originPush.call(this,location,resolve,reject)
  }else{
    originPush.call(this,location,()=>{},()=>{})
  }
}
VueRouter.prototype.replace = function(location,resolve,reject){
  if(resolve && reject){
    originReplace.call(this,location,resolve,reject)
  }else{
    originReplace.call(this,location,()=>{},()=>{})
  }
}

滚动行为

const router = new VueRouter({
  routes,
  scrollBehavior(to, from, savedPosition) {
    return { y: 0 }
  },
})

Axios

API

二次封装request

自定义的 axios 实例添加拦截器。

import axios from 'axios';
// 1:利用axios对象的方法create,去创建一个axios实例
// 2:request 就是axios,只不过稍微配置了一下
const requests = axios.create({
    // 配置对象
    // 基础路径,发请求的时候,路径当中会出现api
    baseURL:"/api",
    // 代表请求超时的时间5s
    timeout:5000,
})
// 请求拦截器:在发送请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use((config)=>{
    // config:配置对象,对象里面有一个属性很重要,header请求头
    return config;
})
// 响应拦截器
requests.interceptors.response.use((res)=>{
    // 成功的回调函数:服务器响应数据回来以后,响应拦截器可以检测到,可以做一些事情
    return res.data;
},(error)=>{
    // 响应失败的回调函数
    return Promise.reject(new Error('faile'));
})
// 对外暴露
export default requests;

进度条

requests.interceptors.request.use((config)=>{
    // nprogress开始
    nprogress.start();
    return config;
})
requests.interceptors.response.use((res)=>{
    // 进度条结束
    nprogress.done();
    return res.data;
},(error)=>{
    return Promise.reject(new Error('faile'));
})

跨域问题

proxy代理

src/vue.config.js文件

module.exports = {
    devServer :{
        proxy: {
            "/api": {
              target: "http://39.98.123.211",
            //   pathRewrite: {"^/api" : ""}
            }
          }
    }
}

vuex

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import home from './home'
import search from './search'
export default new Vuex.Store({
  // state:仓库存储数据的地方
  state: {},
  // mutations: 修改state的唯一手段
  mutations: {},
  // actions:处理action,可以书写自己的业务逻辑,也可以处理异步
  actions: {},
  // getters: 理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
  getters: {},
  // 实现Vuex仓库模块式开发存储数据
  modules: {
    home,
    search
  }
})

Tips

1.****多个字符串检查

通常,你可能需要检查string是否等于多个值之一,并且可能会非常快地变得疲惫。幸运的是,JavaScript有一个内置的方法来帮助您解决这个问题。

const isVowel = (letter) => {
if(
    letter==='a'||
    letter==='e'||
    letter==='i'||
    letter==='o'||
    letter==='u'||
){
    return true
    }
return false;
}

//short-hand
const isvowel = (letter) =>
['a','e','i','o','u'].includes(letter);

2.For-ofFor-in****循环

For-of和For-in循环是在array或object上迭代的好方法,而无需手动跟踪objectkeys的索引。

For-of
const arr = [1,2,3,4,5]
//Long-hand
for(let i = 0; i < arr.length; i++){
    const element = arr[i]
}

//short-hand
for(const element of arr){
    //...
}
For-in
const obj = {
    a:1,
    b:2,
    c:3,
};
//Long-hand
const keys = object.keys(obj);
for(let i = 0; i<keys.length; i++){
    const key = keys[i];
    const value = obj[key];
    //...
}

//short-hand
for(const key in obj){
    const value = obj[key];
    //...
}

3.Falsey****检查

如果你想检查变量是null、undefined、0、false、NaN还是空string,你可以使用逻辑(!)操作员一次检查所有条件,而无需编写多个条件。这使得检查变量是否包含有效数据变得容易。

//Long-hand
const isFalsey = (value) =>{
    if(
        value ===null||
        value ===undefind||
        value === 0||
        value ===false||
        value ===NaN||
        value ===""
    ){
        return true;
    }
    return false;
};
//short-hand
const isFalsey = (value) => !value;

4.****三元运算符

作为JavaScript开发人员,你必须遇到过ternary operator。这是编写简洁的if-else语句的好方法。但是,你也可以使用它来编写简洁的代码,甚至将其链接起来以检查多个条件。

//Long-hand
let info;
if(value < minValue){
    info = "value is too small";
}else if(value > maxValue){
    info = "value is too large";
}else{
    info = "value is in range";
}

//short-hand
const info = 
      value < minValue ? "value is too small" : value > maxValue ? "value is too large" : "value is in range";

5.****函数调用

在ternary operator的帮助下,你还可以根据条件确定调用哪个函数。

重要附带说:函数的callsignature必须相同,否则你可能会遇到错误。

function Fn1(){
    //...
}
function Fn2(){
    //...
}

//Long-hand
if(condition){
    Fn1();
}else{
    Fn2();
}
//short-hand
(condition ? Fn1 : Fn2)();

6.****切换速记

长switch cases情况通常可以通过使用以键为switch,将值用作返回值的对象来优化。

cont dayNumber = new Date().getDay();
//Long-hand
let day
switch(dayNumber){
    case 0:
        day = "Sunday";
        break;
    case 1:
        day = "Monday";
        break;
    case 2:
        day = "Tuesday";
        break;
    case 3:
        day = "Wednesday";
        break;
    case 4:
        day = "Thursday";
        break;
        ......
}
//short-hand
const days = {
    0:'Sunday',
    1:'Monday',
    2:'Tuesday',
    3:'Wednesday',
    4:'Thursday',
    5:'Friday',
    6:'Saturday',
};
const day = day[dayNumber];

7.****回退值

||运算符可以为变量设置回退值。

//Long-hand
let name;
if(user?.name){
   name = user.name;
   }else{
    name = "Anonymous";
}

//short-hand
const name = useer?.name || "Anonymous";

vue打印

1.引入打印main.js

"print-js": "^1.6.0",

// 引入打印
import print from 'print-js'
import 'print-js/dist/print.css';

//挂载
Vue.prototype.$print = print;

2.使用

this.$print({
        printable: "el_id", //打印元素ID
        type: "html", //类型
        // header: this.ruleForm.name, // 内容标题
        style:
          "*{ font-weight: bold; color: black !important; font-size: 16px} .el-input__inner{font-weight:bold; color:black;} .textarea__inner{font-weight:bold; color:black; }",
        css: "", //样式url
        // scanStyles: true, // false当前页面样式不应用于打印
        documentTitle: 'String', // 页眉内容
        font_size: "auto",//字体大小自定义
        maxWidth: 3000, //最大宽度
        onPrintDialogClose: this.printClose(), //浏览器打印窗口打开后执行的函数
        // ignoreElements: ["no-print"], //  不打印元素ID
        iframe: false,
        targetStyles: ["*"], // 打印内容使用所有HTML样式,没有设置这个属性/值,设置分页打印没有效果
      });

获取图片信息转Base64

/**
 * 获取图片文件转base64
 * @param {File} file
 * @returns {String}
 */
export function getFileToBase64(file) {
  return new Promise(function (resolve, reject) {
    const reader = new FileReader();
    let imgResult = "";
    reader.readAsDataURL(file);
    reader.onload = function () {
      imgResult = reader.result;
    };
    reader.onerror = function (error) {
      reject(error);
    };
    reader.onloadend = function () {
      resolve(imgResult);
    };
  });
}
        
    this.getBase64(file.raw).then((res) => {
        const params = res.split(",");
        if (params.length > 0) {
          this.picBase64 = params[1];
        }
      });

获取在线Url转Base64

/**
 * 获取url文件转Base64
 */
export function getUrlToBase64(imageUrl) {
  return new Promise(function (resolve, reject) {
    // 画布
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    var image = new Image();
    var dataUrl = ""
    image.setAttribute("crossOrigin", "anonymous");
    image.src = imageUrl + "?v=" + Math.random();
    image.onload = function () {
      canvas.width = image.width;
      canvas.height = image.height;
      context.drawImage(image, 0, 0, image.width, image.height);
      dataUrl = canvas.toDataURL("image/png");
      resolve(dataUrl)
    }
  })
}

去除图片底色

/**
 * 去除图片背景
 * img  图片的base64编码
 * rgba 需要去除的背景色
 * tolerance  容差信息
 */

export function removeImgBg(img, rgba, tolerance) {
  var imgData = null;
  const [r0, g0, b0, a0] = rgba;
  var r, g, b, a;
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  const w = img.width;
  const h = img.height;


  canvas.width = w;
  canvas.height = h;
  context.drawImage(img, 0, 0);
  imgData = context.getImageData(0, 0, w, h);

  for (let i = 0; i < imgData.data.length; i += 4) {
    r = imgData.data[i];
    g = imgData.data[i + 1];
    b = imgData.data[i + 2];
    a = imgData.data[i + 3];
    const t = Math.sqrt((r - r0) ** 2 + (g - g0) ** 2 + (b - b0) ** 2 + (a - a0) ** 2);
    if (t <= tolerance) {
      imgData.data[i] = 0;
      imgData.data[i + 1] = 0;
      imgData.data[i + 2] = 0;
      imgData.data[i + 3] = 0;
    }
  }
  context.putImageData(imgData, 0, 0);
  const newBase64 = canvas.toDataURL('image/png');
  img.src = newBase64;
}

HTML转图片

引入npm i html2canvas

import html2canvas from "html2canvas";

注:页面内图片需转为base64,否则会丢失

    // 导出图片
    getPicture() {
      html2canvas(this.$refs.pircute_ref,{backgroundColor:'#F6F6F6'}).then((canvas) => {
        var imgData = canvas.toDataURL("image/jpeg");
        this.fileDownload(imgData);
      });
    },
    // 下载图片
    fileDownload(downloadUrl) {
      let alink = document.createElement("a");
      alink.style.display = "none";
      alink.href = downloadUrl;
      alink.download = "图片.png";
      document.body.appendChild(alink);
      alink.click();
      document.body.removeChild(alink);
    },

HTML导出PDF

1.使用 html2Canvas + jsPDF 导出PDF

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
function export_PdfAndSave(options) {
    var title = options.pdfName
    html2Canvas(options.pdfDom, {
        allowTaint: true,
        useCORS: true
    }).then(function (canvas) {
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        let pageHeight = contentWidth / 592.28 * 841.89
        let leftHeight = contentHeight
        let position = 0
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new JsPDF('', 'pt', 'a4')
        if (leftHeight < pageHeight) {
            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
            while (leftHeight > 0) {
                PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                leftHeight -= pageHeight
                position -= 841.89
                if (leftHeight > 0) {
                    PDF.addPage()
                }
            }
        }
        PDF.save(title + '.pdf')
    }
    )
}
export default {
    export_PdfAndSave
}

2.调用浏览器自身的方法。window.print() 来打印(打印时可选下载)

HTML导出Word

1.插件

  • "docxtemplater": "^3.36.1",
  • "file-saver": "^2.0.5",
  • "jszip": "^2.6.1",
  • "jszip-utils": "^0.1.0",
  • "docxtemplater-image-module-free": "^1.1.1",

2.方法函数

// htmlToDocx.JS
import { saveAs } from "file-saver";
import docxtemplater from "docxtemplater";
import JSZipUtils from "jszip-utils";
import JSZip from "jszip";
import ImageModule from "docxtemplater-image-module-free";
function exportWord(formData, companyData) {
    // let _this = this
    // 读取并获得模板文件的二进制内容
    JSZipUtils.getBinaryContent('./static/exportDocx.docx', function (error, content) {
        if (error) throw error // 抛出异常
        function base64DataURLToArrayBuffer(dataURL) {
            const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/;
            if (!base64Regex.test(dataURL)) {
                return false;
            }
            const stringBase64 = dataURL.replace(base64Regex, "");
            let binaryString;
            if (typeof window !== "undefined") {
                binaryString = window.atob(stringBase64);
            } else {
                binaryString = new Buffer(stringBase64, "base64").toString("binary");
            }
            const len = binaryString.length;
            const bytes = new Uint8Array(len);
            for (let i = 0; i < len; i++) {
                const ascii = binaryString.charCodeAt(i);
                bytes[i] = ascii;
            }
            return bytes.buffer;
        }
        // 图片Base64
        var opts = {
            centered: false,
            getImage(tagValue) {
                return base64DataURLToArrayBuffer(tagValue)
                // return new Promise(function (resolve, reject) {
                //     JSZipUtils.getBinaryContent(tagValue, function (error, content) {
                //         if (error) {
                //             return reject(error)
                //         } else {
                //             
                //             return resolve(content)
                //         }
                //     })
                // })
            },
            getSize(img, tagValue, tagName) {
                return [100,100];     //  图片固定大小
                // let wid = 200; //最大值
                // return new Promise(function (resolve, reject) {
                //     var image = new Image()
                //     image.src = tagValue
                //     let imgWidth, imgHeight, scale;
                //     image.onload = function () {
                //         imgWidth = image.width
                //         imgHeight = image.height
                //         scale = 0
                //         // 大小超出最大值,按比例缩放
                //         if (imgWidth > wid) {
                //             scale = wid / imgWidth
                //             imgWidth = wid
                //             imgHeight = imgHeight * scale
                //         }
                //         resolve([imgWidth, imgHeight])
                //     }
                //     image.onerror = function (e) {
                //         
                //         reject(e)
                //     }
                // })
            }
        };
        var imageModule = new ImageModule(opts)
        // 创建一个JSZip实例,内容为模板的内容
        let zip = new JSZip(content)
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater()
        doc.attachModule(imageModule)
        doc.loadZip(zip)
        // 去除null值导致的undefined
        doc.setOptions({
            nullGetter: function () {
                return "";
            }
        });
        // doc.compile();
        doc.setData({ ...formData, ...companyData }) // 设置模板变量的值
        try {
            doc.render() // 用模板变量的值替换所有模板变量
        } catch (error) {
            let e = {
                message: error.message,
                name: error.name,
                stack: error.stack,
                properties: error.properties
            }
            
            throw error // 抛出异常
        }
        // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
        let out = doc.getZip().generate({
            type: 'blob',
            mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        })
        // 将目标文件对象保存为目标类型的文件,并命名
        saveAs(out, formData.projectName + '.docx')
    })
}

export default {
    exportWord
}

3.使用

    // 导出Word
    getDocx() {
        //数据处理后
      htmlToDocx.exportWord(formData, this.companyMessage);
    },

4.模板文件

image-20230329131525019

文字:{text};图片:{%image};循环:{#table}{item}{/table}

css动画

1.箭头

<div class="container">
  <div class="chevron"></div>
  <div class="chevron"></div>
  <div class="chevron"></div>
</div>
$base: 0.6rem;

.container {
 display: flex;
 justify-content: center;
 align-items: center;
 width: 100%;
 height: 100vh;
}

.chevron {
  position: absolute;
  width: $base * 3.5;
  height: $base * 0.8;
  opacity: 0;
  transform: scale(0.3);
  animation: move-chevron 3s ease-out infinite;
}

.chevron:first-child {
  animation: move-chevron 3s ease-out 1s infinite;
}

.chevron:nth-child(2) {
  animation: move-chevron 3s ease-out 2s infinite;
}

.chevron:before,
.chevron:after {
 content: '';
 position: absolute;
 top: 0;
 height: 100%;
 width: 50%;
 background: #2c3e50;
}

.chevron:before {
 left: 0;
 transform: skewY(30deg);
}

.chevron:after {
 right: 0;
 width: 50%;
 transform: skewY(-30deg);
}

@keyframes move-chevron {
 25% {
  opacity: 1;
	}
 33.3% {
  opacity: 1;
  transform: translateY($base * 3.8);
 }
 66.6% {
  opacity: 1;
  transform: translateY($base * 5.2);
 }
 100% {
  opacity: 0;
  transform: translateY($base * 8) scale(0.5);
 }
}

video标签

类似于所有其它HTML元素,video元素支持 全局属性 (en-US)

autoplay

布尔属性;指定后,视频会马上自动开始播放,不会停下来等着数据载入结束。

autobuffer

布尔属性;指定后,视频会自动开始缓存,即使没有设置自动播放。该属性适用于视频被认为可能会播放(比如,用户导航到专门播放视频的页面,而不是那种嵌入视频还有其它内容的页面)。视频会一直缓存到媒体缓存满。

实现备注: 虽然是HTML5规范的早期草案的一部分, autobuffer 属性在稍晚的版本被去掉了。 Gecko 2.0 和其它浏览器中已经移除了这个属性,而且有些浏览器中从未实现。规范定义了一个新的枚举属性, preload, 用不同的语法来取代 autobuffer 属性。

buffered

这个属性可以读取到哪段时间范围内的媒体被缓存了。该属性包含了一个 TimeRanges 对象。

controls

加上这个属性,Gecko 会提供用户控制,允许用户控制视频的播放,包括音量,跨帧,暂停/恢复播放。

controlslist

当浏览器显示自己的控件集(例如,当指定了Controls属性时),Controlslist属性将帮助浏览器选择在媒体元素上显示的控件。

允许接受的value有nodownload,nofullscreennoremoteplayback

如果要禁用图片模式(和控件),请使用disablePictureInPicture属性。

crossorigin

该枚举属性指明抓取相关图片是否必须用到CORS(跨域资源共享)。 支持CORS的资源 可在 `` 元素中被重用,而不会被污染。允许的值如下:

anonymous

跨域请求(即,使用 Origin: 的HTTP头)会被执行。但是不发送凭证(即,不发送cookie, X.509 证书或者 HTTP Basic 授权)。如果服务器不提供证书给源站点 (不设置 Access-Control-Allow-Origin: HTTP头),图片会被 污染 并且它的使用会受限。

use-credentials

跨域请求A cross-origin request (i.e. with Origin: HTTP header) 会被执行,且凭证会被发送 (即, 发送一个 cookie, 一个证书和HTTP Basic授权会被执行)。如果服务器不提供证书给源站点 (通过Access-Control-Allow-Credentials: HTTP 头),图像会被 污染 且它的使用会受限。

不加这个属性时,抓取资源不会走CORS请求(即,不会发送 Origin: HTTP 头),保证其在 `` 元素中使用时不会被污染。如果指定非法值,会被当作指定了枚举关键字 anonymous 一样使用。 查看 CORS 设置属性 (en-US) 获取更多信息。

currentTime

读取CurentTime返回一个双精度浮点值,指示以秒为单位的媒体的当前播放位置。如果video尚未开始播放,则会在开始播放后返回偏移量。通过CurentTime将当前播放位置设置为给定时间,会在加载媒体时将媒体查找到该位置(从指定的位置开始播放)。

媒体正在播放的情况下,如果媒体缓冲区的数据已经过期(视频已经播放完),则 user agent有可能无法正常拿到数据。有些媒体可能有一个不以0秒开始的媒体时间线(不是从头开始播放的),因此应该将currentTime的时间设置在其数据失效之前。getStartDate() 这个方法可以用来确定媒体时间线起始的坐标。

disablePictureInPicture

防止浏览器建议图片中的上下文菜单或在某些情况下自动请求图片中的图片。该属性可以禁用 video 元素的画中画特性,右键菜单中的“画中画”选项会被禁用

disableRemotePlayback

  • 一个布尔属性,用于禁用使用有线连接的设备(HDMI、DVI等)的远程播放功能。无线技术(Miracast、Chromecast、DLNA、AirPlay等)。
  • 在Safari中,您可以使用x-webkit-airplay=“deny”作为后盾。

duration只读

一个双精度浮点值,它指示媒体的持续时间(总长度),以秒为单位,在媒体的时间线上。如果元素上没有媒体,或者媒体无效,则返回的值为NaN。如果媒体没有已知终点(例如时间未知的实时流、网络广播、来自WebRTC的媒体等等),那么这个值就是Infinity。

height

视频展示区域的高度,单位是CSS像素。

intrinsicsize

这个属性告诉浏览器忽略图像的实际内在大小,并假装它是属性中指定的大小。具体来说,图像将在这些维度上展开,图像上的naturalWidth/naturalHeight 将返回此属性中指定的值。Explainerexamples

loop

布尔属性;指定后,会在视频结尾的地方,自动返回视频开始的地方。

muted

布尔属性,指明了视频里的音频的默认设置。设置后,音频会初始化为静音。默认值是false,意味着视频播放的时候音频也会播放 。

playsinline

一个布尔属性,标志视频将被“inline”播放,即在元素的播放区域内。请注意,没有此属性并不意味着视频始终是全屏播放的。

played

一个 TimeRanges 对象,指明了视频已经播放的所有范围。

preload

该枚举属性旨在告诉浏览器作者认为达到最佳的用户体验的方式是什么。可能是下列值之一:

  • none: 提示作者认为用户不需要查看该视频,服务器也想要最小化访问流量;换句话说就是提示浏览器该视频不需要缓存。
  • metadata: 提示尽管作者认为用户不需要查看该视频,不过抓取元数据(比如:长度)还是很合理的。
  • auto: 用户需要这个视频优先加载;换句话说就是提示:如果需要的话,可以下载整个视频,即使用户并不一定会用它。
  • 空字符串:也就代指 auto 值。

假如不设置,默认值就是浏览器定义的了 (即,不同浏览器会选择自己的默认值),即使规范建议设置为 metadata。

使用备注:

  • autoplay 属性优先于 preload 假如用户想自动播放视频,那么很明显浏览器需要下载视频。同时设置autoplaypreload属性在规范里是允许的。
  • 规范没有强制浏览器去遵循该属性的值;这仅仅只是个提示。

poster

一个海报帧的URL,用于在用户播放或者跳帧之前展示。如果属性未指定,那么在第一帧可用之前什么都不会展示;之后第一帧就像海报帧一样展示。

src

要嵌到页面的视频的URL。可选;你也可以使用video块内的 `` 元素来指定需要嵌到页面的视频。

width

视频显示区域的宽度,单位是CSS像素。

时间偏移量目前是指定为float类型的值,表示偏移的秒数。

        <video
          class="myVideo"
          ref="myVideo"
          preload
          controls
       	  src="./public/video/pwr_video.mp4"
          type="video/mp4"
        ></video>

JS

extends super 关键字

class Person {
    constructor(surname,x,y){
        this.surname= surname;
        this.x = x;
        this.y = y;
    }
    sum(){
        return this.x+this.y
    }
}

class Student extends Person{		//子类继承父类
    constructor(surname,firstname,x,y){
        super(surname,x,y);				//调用父类的constructor(surname)
        this.firstname= firstname;	 //定义子类独有的属性
        this.x = x;
        this.y = y;
    }
    subtract(){
        return this.x-this.y;
    }
}

子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,再使用子类的构造方法)

utilsFun

1.数组删除

// 需要删除数组 arr
// 需要删除元素集合 list
arr = arr.filter(
     (item) => !list.includes(item)
);

Element-UI

踩坑

1.tree

setCurrentKey方法需要在this.$nextTick()内部或者在setTimout()内部

并设置node-key="id"

this.$nextTick(()=>{
    // 树节点高亮
    this.$refs.tree_ref.setCurrentKey(id);
})              

2.el-row

el-row在span之和超出24之后可能会导致排序混乱,排版错乱等问题;

解决方式:

.el-row{
    display:flex;
    flex-wrap:wrap;
}

MxGraph

1.引用

Api文档:https://tbouffard.github.io/typed-mxgraph

https://www.jianshu.com/p/6234a1dc7685

mxgraph插件包

import mx from "mxgraph";
const mxgraph = mx({});
const { mxGraph, mxClient, mxCodec, mxUtils, mxEvent } = mxgraph;

2.初始化

	<!-- 容器 -->
	<div id="graphCenter" ></div>
    // 初始化mxGraph组件
    initMxGraph() {
      if (!mxClient.isBrowserSupported()) {
        // 判断是否支持mxgraph
        mxUtils.error("浏览器不支持!", 200, false);
      } else {
        // 在容器中创建图表
        let container = document.getElementById("graphCenter");
        let MxCodec = mxCodec;
        let MxGraph = mxGraph;
        var graph = new MxGraph(container);
        // 是否只读
        graph.setEnabled(false);
        // 将节点内容标识为html
        graph.setHtmlLabels(true);
        // 节点大小不允许更改
        graph.setCellsResizable(false);
        // 是否允许Cells通过其中部的连接点新建连接
        graph.setConnectable(false);
        // 边被拖动时始终保持连接
        graph.setDisconnectOnMove(true);
        // 连接线整体不可拖动
        graph.setEdgeLabelsMovable(true);
        //自适应
        // graph.fit();
        // 画布大小
        // graph.setResizeContainer(true);
        // graph.minimumContainerSize = new mxRectangle(0, 0, 800, 500);
        // graph.maximumContainerSize = new mxRectangle(0, 0, 1000, 600);
        // 生成标签
        var parent = graph.getDefaultParent();
        //mxGraph画布
        this.v_graph = graph;
        // 父节点
        this.v_parent = parent;
        try {
          graph.getModel().beginUpdate();
        } finally {
          graph.getModel().endUpdate();
        }

        // 打包XML文件
        let encoder = new MxCodec();
        let xx = encoder.encode(graph.getModel());
        // 保存到getXml参数中
        this.getXml = mxUtils.getXml(xx);
        //自定义事件
        // 基础函数
        this.eventCenter();
        // 鼠标事件
        this.configMouseEvent();
      }
    },

3.数据渲染

①节点

      // 初始化节点
      let toNode = this.v_graph.insertVertex(
        this.v_parent, //节点父级
        element.ID, //节点ID
        contentBox, //节点内容 HTML String
        element.CellX, //节点X坐标
        element.CellY, //节点Y坐标
        element.CellWidth, //盒子(contentBox)宽度;
        element.CellHeight, //盒子(contentBox)高度;
       "align=left;fillColor=rgba(235,235,235,0.5);fontColor=#02132a;fontSize=18;strokeColor=rgba(9,215,27,0);"
      );

②线条

线条部分样式

// orthogonalEdgeStyle 正交边

// ElbowConnector 直线

      // 初始化线
      this.v_graph.insertEdge(
        this.v_parent, //父级
        element.ID,  //唯一ID
        "", //线条上文字
        toNode, //起始位置 元素
        toNode2, //终止位置 元素
     "edgeStyle=ElbowConnector;endArrow=none;strokeColor=#01A50E;strokeWidth=2;sourcePerimeterSpacing=5;targetPerimeterSpacing=2;dashed=1;"
      );

4.Api

// 刷新面板graph
this.v_graph.refresh(cell);
// 删除mxgraph所有的分组
var childVertices = this.v_graph.getChildVertices(this.v_parent);
this.v_graph.removeCells(childVertices);
// 面板放大
this.v_graph.zoomIn();
// 面板缩小
this.v_graph.zoomOut();
// 是否只读,不可进行操作
this.v_graph.setEnabled(true);
// 销毁画板
this.v_graph.destroy();

//鼠标事件监听
this.v_graph.addMouseListener({
     currentState: null,
     previousStyle: null,
	//鼠标按下
     mouseDown: (sender, evt) => {
     	//TODO
     },
	//鼠标移动
     mouseMove: (sender, me) => {
     	//TODO    
     },
	//鼠标松开
     mouseUp: (sender, evt) => {
	 	//TODO
     },
});

//节点拖动事件  ps:线条仅整体拖动可触发
this.v_graph.addListener(mxEvent.CELLS_MOVED, (sender, evt) => {
		//TODO
}
                         
//获取组并删除
var portCell = this.v_graph.getModel().getCell(groupID);
portCell.removeFromParent();

jsencryptKey

1.安装插件

npm i jsencrypt --save

2.封装函数

jsencryptKey.js文件

import JSEncrypt from 'jsencrypt'

let publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJEzBDzBqJ/7gKtTZmSrtgz6QGeoCHy2NiPjCslVVr92/oWoglq5gh+tnlS4tqd0TFW+otA3AxHILSiy1D0zoHECAwEAAQ=="
let privateKey = "MIIBOgIBAAJBAJEzBDzBqJ/7gKtTZmSrtgz6QGeoCHy2NiPjCslVVr92/oWoglq5gh+tnlS4tqd0TFW+otA3AxHILSiy1D0zoHECAwEAAQJABSeI+nkrecZtWmejBmbcFxjZKXTbHEZBpMN+EgigBDrwdi11K6AgRtYCfFG6SYtRe2ddNKDHuxX2vN/zNBIQswIhAJI9m/1U0rvevkqWJeG5wSxffbVwNZcGYcEkOWP+bnJzAiEA/i1Ro6i5EKR8hgzJO6w3YsjhZ0ve1MJQfTNwdj1rlIsCIEeHyx0GuG0cboedGbpnWY2Sx7JPyGauwHHwfgHjGbLxAiEAoZ2hRmW23q0n/HhOz+GOCgLex7aHRlMTqLg3bwdYy0cCICX/zKmyB+WXYIpagDnaotTKN7aXiEGdo3cNDET6h2yt"

// 加密方法  公钥
export function getCode(content) {
    let encrypt = new JSEncrypt()
    encrypt.setPublicKey(publicKey)
    let data = encrypt.encrypt(content)
    return data
}

// 解密方法 私钥
export function decryptCode(content) {
    let encrypt = new JSEncrypt()
    encrypt.setPublicKey(privateKey)
    let data = encrypt.decrypt(content)
    return data
}

3.使用

加密

注:加密字符中‘+’号会被转译为空格 encodeURIComponent将密文编码为新的字符串

import { decryptCode } from "@/utils/jsencryptKey"   

let url = "http://192.168.1.5:9530/#/",
    token = "ahpwr",
    account = "admin"; //user account
// 加密token
token = getCode(token);
window.open(url + "?token=" + encodeURIComponent(token) + "&account=" + encodeURIComponent(account), "_blank");

解密

decodeURIComponent解码后再解密

import { decryptCode } from "@/utils/jsencryptKey"

// 解密taoken
let token = decryptCode(decodeURIComponent(to.query.token))

百度地图SDK

1.BMapGL.js 文件

export function BMPGL(ak) {
    return new Promise((resolve, reject) => {
        window.init = function () {
            resolve(BMapGL)
        }
        const script = document.createElement('script')
        script.type = 'text/javascript'
        script.src = `https://api.map.baidu.com/api?type=webgl&v=1.0&ak=${ak}&callback=init`
        script.onerror = reject
        document.head.appendChild(script)
    })
}

2.Demo

<template>
  <div id="MapContainer" style="width: 100%; height: 100%">
  </div>
</template>
<script>
import { BMPGL } from "@/utils/BMapGL.js";
export default {
  data() {
    return {
      ak: "百度Api的AK",
    };
  },

  mounted() {
    this.$nextTick(() => {
      this.initData();
    });
  },

  methods: {
    initData() {
      BMPGL(this.ak)
        .then((BMapGl) => {
          var map = new BMapGl.Map("MapContainer");
          var point = new BMapGl.Point(117.233443, 31.826578);
          map.centerAndZoom(point, 17.5); // 初始化地图,设置中心点坐标和地图级别
          map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
          map.setMapType(BMAP_EARTH_MAP); // 设置地图类型为地球模式
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.map {
  width: 100%;
  height: 100%;
}
</style>

标签:function,Web,return,graph,笔记,let,new,const
From: https://www.cnblogs.com/Rking28/p/RKINGVUE.html

相关文章

  • CTF 在线平台 WEBwp
    1.web_Unagi知识点,xxe编码绕过这道题看到uplaod里面的example,很明显就是xxe了,提示是把/flag读出来。 第四个页面告诉我们flag在/flag中发现上传的是xml,于是自己构造1.xml 这是我们平常用的xxe,但是这个提示是被过滤了,构造完了之后上传发现被WAF拦截了 这里通过XX......
  • es笔记五之term-level的查询操作
    本文首发于公众号:Hunter后端原文链接:es笔记五之term-level的查询操作官方文档上写的是term-levelqueries,表义为基于准确值的对文档的查询,可以理解为对keyword类型或者text类型分词为keyword的字段进行term形式的精确查找。以下是本篇笔记目录:是否存在值前缀搜索......
  • Golang高性能编程笔记--字符串拼接
    Golang中引入五种字符串拼接方法,分别如下:1.+拼接法2.fmt.Sprintf()3.strings.Builder4.bytes.Buffer5.[]byte代码示例,这里将根据《Go语言高性能编程》中的一节,来看一下这五种具体的方法:packagemainimport( "bytes" "fmt" "math/rand" "strings......
  • es笔记一之es安装与介绍
    本文首发于公众号:Hunter后端原文链接:es笔记一之es安装与介绍首先介绍一下es,全名为Elasticsearch,它定义上不是一种数据库,是一种搜索引擎。我们可以把海量数据都放到es里然后提供搜索操作,但是MySQL也同样可以提供搜索,为什么要用es呢?一个是因为它搜索快,使用倒排索引的......
  • 刷题笔记:Luogu P3743
    题目传送门Solution最多能将这些设备一起使用多久,显然答案满足单调性(如果\(x<y\)而不能使用\(x\)时间则一定不能使用\(y\)时间)通俗一点,就是前边的时间不满足则后边一定不满足,也就是局部答案舍弃性,考虑二分时间至于check怎么写呢?和奶牛晒衣服有异曲同工之妙,若设二分出来的时间......
  • 《构建之法》读书笔记
    《构建之法》是法国哲学家、思想家德里达的代表作之一,被誉为是后现代主义的标志性著作。该书的主要论点是,所有的事物都是通过差异和矛盾的构建而成的,这一思想对于人类的思维、语言、文化等方面都具有深远的影响。以下是我对这本书的读书笔记,希望能够对读者有所启示。一、关于质疑......
  • 文心大模型提示词笔记——应用场景案例
    发现:绝大多数应用场景的Prompt,质量都与使用者对“好结果”的了解成正比。1产品海报2写科普文 3写代码指定Markdown、js总结一下这几个例子·拿到应用场景后,先试着判断场景的任务特点,结合任务共性先优化一波。再结合场景主体、应用场合的特点,对生成内容的需求做一些补充说明。......
  • Javaweb期末作品
    用户修改界面update.jsp<html><head><title>update</title><linkrel="stylesheet"href="css/updateUser.css"></head><bodystyle="margin:0100px"><divcla......
  • GO web学习(一)
    跟着b站https://space.bilibili.com/361469957杨旭老师学习做的笔记开启web服务•http.ListenAndServer()•第一个参数是网络地址如果为“”,那么就是所有网络接口的80端口•第二个参数是handler如果为nil,那么就是DefaultServeMux•DefaultServeMux是一个multipl......
  • LLMs Fine-tuning 学习笔记(一):trl+peft
    目录1基本信息2实现步骤3代码分析1基本信息From:Fine-tuning20BLLMswithRLHFona24GBconsumerGPU(huggingface.co)Codes:trl/examples/sentiment/scripts/gpt-neox-20b_peftatmain·lvwerra/trl·GitHub相关工具:peft:用于微调大模型的python库官方文档:htt......