前端工作记录二

工作记录二

组件篇

1. 在前端ui组件中的聚焦或者失焦事件中拿不到event.capture用法
@focus.native.capture="selectFocus($event)"           @blur.native.capture="selectBlur($event)"

会覆盖掉原有组件的失焦事件

2. ref的一些小细节
  • 组件内部有多个同名ref引用时

    • 没有父子关系
    <template>
      <h2 ref="test">test1</h2>
      <h2 ref="test">test2</h2>
    </template>
    
    <script>
     export default {
         mounted(){
             console.log(this.$refs.test)
         }
     }
     </script>
    <!-- 
    	为最后一个元素的dom
    --!>
    
    • 存在父子关系
    <h2 ref="test">
        test1
        <h3 ref="test">children test1</h3>
    </h2>
    <script>
    export default {
        mounted(){
            console.log(this.$refs.test)
        }
    }
    </script>
    <!-- 
    	为父元素的dom
    --!>
    
    • 使用v-for循环生成
    <ul>
        <template v-for="i in 3">
            <li :key="i" ref="test">i</li>
        </template>
    </ul>
    <script>
    export default {
        mounted(){
            console.log(this.$refs.test)
        }
    }
    </script>
    <!--
    	为长度为3的数组
    --!>
    
3. vue数字变化动画插件

Vue CountTo

4. 炫酷外壳,轻量大数据展示组件

DataV

5. 精致开源的icon

css.gg

官网上有对react中使用css.gg的例子,在vue中我是这么使用的。

//安装一下css.gg库
yarn add css.gg
//在mian.js中添加
import 'css.gg/icons/all.css';
//然后就可以写了
<i class="gg-{iconName}" />
//例如
<i class="gg-add-r" />
6. 中国风的配色网站

中国色

7. 前端新手引导组件

intro.js

8. vue莫名刷新问题
//App.vue
<div class="contain" @click="mouse">
  <HelloWorld :image="{src:musi}" />
  <span>{{visible}}</span>
</div>
<script>
import HelloWorld from './components/HelloWorld.vue'
import musi from "@/assets/musi.gif";
export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data(){
    return{
      musi,
      visible:false
    }
  },
  methods:{
    mouse(){
      this.visible++
    }
  }
}
</script>
//HelloWorld.vue
<template>
    <div style="width:fit-contain">
        <img 
            :src="image.src"
        >
    </div>
</template>

<script>
export default {
    name:"list",
    props:{
        image:Object
    },
    beforeUpdate(){
        console.log('change');
    }
}
</script>

这是一个很简单的设计,点击contain数字+1,但是由于是临时创建的对象,每次点击contain都会导致Helloword.vue刷新,以后千万不能用对象包裹,去data声名一下。

9. vue打包之后添加二级目录
//在router的index.js中
const router = new VueRouter({
  mode: 'history',
  base: '/web',
  //添加被嵌套的文件夹
  routes
})
//在vue.config.js中
module.exports = {
  publicPath:"/web"
}
//在入口文件的index.html中
<meta base ="/web/">
10.hooks模拟componentWillUnmount
useEffect(() => {
  return () => {
    console.log('will unmount');
  }
}, []);

复制代码当在 useEffect 的回调函数中返回一个函数时,这个函数会在组件卸载前被调用。我们可以在这里面清除定时器或事件监听器。

11.有趣的动画插件

wow.js

12.antd在线配置样式网站

antd-theme

加载有点慢…耐心等待…

13.element在线配置样式网站

element-theme

14.浏览器顶部进度条组建

NProgress.js

15.console.log输出颜色

chalk

16.terminal的等待动画

ora

17.md文件徽牌

Shields.io

一篇少数派的使用文章

18. ip校验工具

Range Check

CSS样式

1. onResizeResizeObserver因为出现滚动条不停抖动的解决方式
/*其实暂时没有一个很好的解决方法,我认为可以通过debounce函数解决。
既然是因为滚动条的出现而不停抖动的话,那就直接让滚动条全都显示出来,*/
body{
    overflow-y: scroll
}
2. 元素垂直居中的方法
  • 使用绝对定位,设定四个方向值为0,设置margin为auto
.center{
  width: 100px;
  height: 100px;
  position: absolute;
  border: 1px solid red;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin: auto;  
}
  • 绝对定位,top50%,left50%,margin为负(必须知道子元素高度)
.center{
  width: 100px;
  height: 100px;
  position: absolute;
  border: 1px solid red;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -50px;
}
  • 绝对定位,top50%,left50%,translate(-50%,-50%)
.center{
  width: 100px;
  height: 100px;
  position: absolute;
  border: 1px solid red;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
  • display:flex
.contain{
  width: 500px;
  height: 500px;
  display: flex;
  justify-content: center;
  align-items:center;
  position: relative;
  border: 1px solid red;
}
.center{
  width: 100px;
  height: 100px;
  border: 1px solid red;
}
  • 使用伪元素基线校准
.contain{
  width: 500px;
  height: 500px;
  text-align: center;
  position: relative;
  border: 1px solid red;
}
.center{
  width: 100px;
  height: 100px;
  display: inline-block;
  vertical-align: middle;
  border: 1px solid red;
}
.contain::after{
  content: "";
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}
3. css一像素线缩放实现方法
  .onepixel {
    display: block;
  }
  .onepixel::before{
    content: "";
    display: block;
    transform-origin: 0 0;
  }
  .onepixel.top::before {
    width: 100%;
    border-top: 1px solid #000;
  }
  @media (min-resolution: 2dppx) {
    .onepixel.top::before {
      width: 200%;
      transform: scale(.5) translateZ(0);
    }
  }
  @media (min-resolution: 3dppx) {
    .onepixel.top::before {
      width: 300%;
      transform: scale(.333333) translateZ(0);
    }
  }
4. 好看的滚动条样式
<style>
*::-webkit-scrollbar {
  width: 7px;
}

/*滚动条的滑轨背景颜色,可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。*/

*::-webkit-scrollbar-track {
  background-color: #f5f5f5;
  -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.1);
  border-radius: 5px;
}
*::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}
*::-webkit-scrollbar-button {
  background-color: #eee;
  display: none;
}
*::-webkit-scrollbar-corner {
  background-color: black;
}
</style>

vue项目放在App.vue中就可以。

JS

1. 原型 原型链
2. 闭包
3. 深拷贝浅拷贝

是什么

  • 浅拷贝:浅拷只是复制某个对象的指针,而不复制对象本身,新旧对象中还有一部分共处同一个内存。
  • 深拷贝:深拷贝完全创造一个一模一样的对象,并不会共享内存。

怎么弄

  1. 浅拷贝
  • 对于对象来说可以Object.assign
let a = {
    1:"a",
    2:"b",
    3:{
        1:"a"
    }
}
let b = Object.assign({},a)
b[3][1]="b"
console.log(a)
/*{
    1: "a",
	2: "b",
	3: {1: "b"}
}*/
  • 对于数组来说

    • Array.prototype.concat()
    let a = [1,2,{
        3:'a'
    }]
    let b = a.concat([])
    a[2][3] = 'b'
    console.log(a)
    /*[
        0: 1,
        1: 2,
        2: {3: "b"}
    ]*/
    
    • Array.prototype.slice()
    let a = [1,2,{
        3:'a'
    }]
    let b = a.slice(0)
    a[2][3] = 'b'
    console.log(a)
    /*[
        0: 1,
        1: 2,
        2: {3: "b"}
    ]*/
    
    • 共有方法扩展运算符...
  1. 深拷贝
  • 自己写简单的
// 定义检测数据类型的功能函数
function checkedType(target) {
 return Object.prototype.toString.call(target).slice(8, -1)
}
// 实现深度克隆---对象/数组
function clone(target) {
 // 判断拷贝的数据类型
 // 初始化变量result 成为最终克隆的数据
 let result, targetType = checkedType(target)
 if (targetType === 'object') {
   result = {}
 } else if (targetType === 'Array') {
   result = []
 } else {
   return target
 }
 // 遍历目标数据
 for (let i in target) {
   // 获取遍历数据结构的每一项值。
   let value = target[i]
   // 判断目标结构里的每一值是否存在对象/数组
   if (checkedType(value) === 'Object' ||
     checkedType(value) === 'Array') { 
      // 对象/数组里嵌套了对象/数组
      // 继续遍历获取到value值
     result[i] = clone(value)
   } else { 
     // 获取到value值是基本的数据类型或者是函数。
     result[i] = value;
   }
 }
 return result
}
  • JSON,stringify
let arr = [1, 3, {
   username: ' kobe'
},function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
  • 会忽略 undefined
  • 会忽略 symbol
  • 不能序列化函数
  • 不能解决循环引用的对象
  • 函数库lodash
var _ = require('lodash');
var obj1 = {
   a: 1,
   b: { f: { g: 1 } },
   c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false
4. vue2监听数据的方法简写
//判断函数:如果给的值是对象数据类型,那你再走一遍循环吧。
function judge(value) {
    if(Object.prototype.toString.call(value) !== "[Object Object]"){
        return 
    }
    for(let key in value){
        defineReactive(value,key,value[key])
    }
}
//定义监听函数,可以在set中进行对视图的变化
function defineReactive(obj,key,value){
    judge(value)
    Object.defineProperty(obj,key,{
        get:function () {
            console.log("我被取值了,怎么办好难!")
            return value   
        },
        set:function (newValue) {
            console.log("我被监听到了,可以搞dom了")
            judge(newValue)
            return value = newValue
        }
    })
}
//传入一个对象让他变成可以被监控
function set(obj) {
    for(let key in obj){
        defineReactive(obj,key,obj[key])
    }
}
let test = {
    name:"小红"
}
set(test)
// test.name = "小明"       我被监听到了,可以搞dom了
// test.name = {
//     firstName : "小",    我被监听到了,可以搞dom了
//     lastName : "明",     我被监听到了,可以搞dom了
// }
// console.log(`我的名字是${test.name.firstName}${test.name.lastName}`)
// 我被监听到了,可以搞dom了
// 我被取值了,怎么办好难!
// 我被取值了,怎么办好难!
// 我的名字是小明

这个老哥的Object.defineProperty解释的详细,我记录一下地址

5. Proxy简单例子,简单解释vue3数据监听
let test = {
   name:"小红",
   children:{
       name:"红红"
   }
}
let testObject = new Proxy(test,{
   get(target,key){
       console.log(target,key)
       return key in target ? target[key] : "哈哈并没有"
   },
   set(target,key,value){
       //console.log(target,key,value)
       target[key] = value
       return true
   }
})
//	console.log(testObject.age)
//  testObject.name = "小明"
6. 手写一个简单的promise
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'

function myPromise(fn){
    const that = this
    that.state = PENDING
    that.value = null
    //成功回调的列表
    that.resolvedCallbacks = []
    //失败回调的列表
    that.rejectedCallbacks = []
    //成功时调用的函数
    function resolve(value){
        that.state = RESOLVED
        that.value = value
        that.resolvedCallbacks.map(cb => cb(that.value))
    }
    //失败时调用的函数
    function reject(value){
        that.state = REJECTED
        that.value = value
        that.rejectedCallbacks.map(cb => cb(that.value))
    }
    //then方法
    //必须这两个参数是函数,如果不是函数则定义为一个函数;
    //只有在promise不在等待的状态的时候才会执行传入的函数。
    myPromise.prototype.then = function(onResolve,onReject){
        const that = this
        onResolve = typeof onResolve == 'function' ? onResolve : onResolve => onResolve
        
        onReject = typeof onReject == 'function' ? onReject : onReject => { throw onReject }
        
        if(that.state == PENDING){
            that.resolvedCallbacks.push(onResolve)
            that.rejectedCallbacks.push(onReject)
        }
        
        if(that.state == RESOLVED){
            onResolve(that.value)
        }
        if(that.state == REJECTED){
            onReject(that.value)
        }
    }
    
    try{
        fn(resolve,reject)
    }catch(e){
        reject(e)
    }
}
//例子
new myPromise((resolve)=>{
    console.log("这是promise内部的打印")
    setTimeout(() => {
        console.log("这是settimeout内部的打印")
        resolve("xixi")
    }, 2000);
}).then(res =>{
    console.log(res)
})
console.log("这是最外层")
7. 宏任务微任务之间的执行关系
8. Event loop

由于JavaScript是单线程执行,在主线程上从上到下依次执行,在执行耗时比较大的代码片段会产生堵塞的情况,为了避免这一情况引入异步的思想,异步任务分为宏任务和微任务,所以执行顺序就变成了:

  • 执行主线程的同步代码,即为宏任务执行。存在微任务压入本次task队列。
  • 执行当前轮训的微任务。
  • 执行异步的宏任务,存在微任务压入task队列,再次执行微任务。

这样的轮训机制,直到所有任务完成,这种轮训过程称为event loop

微任务包括 process.nextTickpromise.thenMutationObserver

宏任务包括 scriptsetTimeoutsetIntervalsetImmediate .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值