一、.sync修饰符在jsx中如何写

<cl-dialog title="用户使用详情" visible={this.visible} {...{on: {'update:visible': val => this.visible = val}}} width={"60%"}>
Vue中的.sync原理是:
prop.sync="data" 只是 :prop="data" @update:prop="val => data = val" 的语法糖,JSX 下自己实现监听逻辑即可。

在Vue3中.sync被v-model代替了
自定义组件上的 v-model 相当于传递了 modelValue prop 并接收抛出的 update:modelValue 事件

<ChildComponent v-model="pageTitle" />

<!-- 是以下的简写: -->

<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>

这也可以作为 .sync 修饰符的替代,而且允许我们在自定义组件上使用多个 v-model

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />

<!-- 是以下的简写: -->

<ChildComponent
  :title="pageTitle"
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
/>

二、CSS补充

❤️css控制页面文字不能被选中: user-select:none;
❤️关于antd中ul有个margin-bottom的样式干扰,之前一直以为是干扰,其实不是!!是因为我对ul标签的错误使用!!!ul样式外面应该有个父div包裹他们,而不要在ul标签上定义块的高度之类的,尽量ul标签上不要有任何东西,然后v-for写在li标签中。如下
<div class="wsb-content flex">
  <ul>
    <li class="flex justify-between align-center" v-for="(item, index) in webMessage" :key="index">
      <span class="text-grey">{{item.link}}</span>
      <a-button type="link" style="margin-right: 50px;" @click="() => webMessage.splice(index, 1)">
        移除
      </a-button>
    </li>
  </ul>
</div>
❤️继续上面的点,ul外面的div如果是flex,且div是一个有min-height和max-height高度的盒子的时候,不要设置algin-center!!!,不然ul块会顶破外面盒子。
  <div class="content flex align-start justify-center">
    <template v-if="contentLoading">
      <div>
        <a-spin>
          <a-icon slot="indicator" type="loading" style="font-size: 60px" spin></a-icon>
        </a-spin>
      </div>
    </template>
    <ul v-else>
      <template v-for="(item, index) in compSearchResult">
        <li class="flex justify-start align-center" :class="{'li-ready': itemReadyedIndex === index}" :key="index">
          <img :src="item.icon" style="width: 30px; height: 30px;">
          <div class="flex flex-direction justify-center align-start" style="padding-left: 20px">
            <div>{{item.title}}</div>
            <div>{{item.attached}}</div>
          </div>
        </li>
      </template>
    </ul>
  </div>
❤️继续上面,ul标签默认li循环出来的结果是竖向排布的,我们如果设置ul的dispaly:flex,把外层的div也设置成dispaly:flex,就可以变为横向,且能自定义li的宽度大小。这里最关键的是!!不要把ul设置可滚动视口宽度!!!
image.png
❤️hover时改变另一元素的显示/隐藏,如下代码需要控制a-icon标签的显示与隐藏,首先使用visibility的hidden和visible去控制。然后注意的点是不要把visibility:hidden的代码写在行内样式中,因为行内的优先级比较高,不然在外部样式表中的hover中的代码就一定要!important了。
<li class="flex justify-between align-center" v-for="(item, index) in lumenMessage" :key="index">
<div class="flex flex-direction justify-around align-start">
  <span class="text-black" style="font-weight: 500;">{{item.title}}</span>
  <span class="text-grey-sm sg-omit2-sm">{{item.body}}</span>
  <span class="text-grey-sm">{{item.time}}</span>
</div>
<a-icon class="closex" type="close-circle" theme="filled" :style="{ fontSize: '16px' }"></a-icon>
</li>
ul {
  width: 94%;
  li {
    height: 50%;
    padding: 10px 0px;
    border-bottom: 1px solid #dddcdc;
    .closex {
      visibility: hidden;
    }
    &:hover {
      .closex {
        visibility: visible;
      }
    }
  }
}
❤️关于fixed的居中设置
.gs-dialog {
  position: fixed;
  left: 50%;
  top: 50%;
  margin-top: -150px;   /* 基于块height高度/2 */
  margin-left: -150px;  /* 基于块width宽度/2 */
  width: 300px;
  height: 300px;
}
关于fixed基于父元素全铺
.gs-dialog {
  position: fixed;
  left: 0%;
  top: 0%;
  width: 100%;
  height: 100%;
}
❤️input输入框中关于focous的知识点

如果强行不选中可以直接设置tabindex = -1 的方式解决
以下是关于tabindex的知识点:
1、https://developer.mozilla.org...
2、http://bluegalaxy.info/codewa...

❤️flex遇到min-height和max-height的内层盒子,justify-between之类的无效
image.png
详解:内层.recent-open-content的高度由于需要min和max自由调节,所以外层.recent-open的height无论设置什么值,都是无效的,所以也就无法再在.recent-open上通过flex justify-between弹开之类的样式设置。!!牢记这种方式只有内盒子的高度是固定的时候,我们才能用flex对外盒子的快写去设置内盒子的样式表现
image.png
❤️css对div⽤hover设置border,出现抖动和div⾛位问题,解决⽅法

第一步:将这个div的border颜⾊设置为透明
border:1px solid transparent;
第二步:然后再引⼊动作hover
hover { border:1px solid red;}

❤️CSS中定义class时,中间有空格和没空格的区别

1、.example .pp中间用空格隔开,表示后代选择器,选择的是.example内的.pp

<div class="example">
    <div class="pp">被选择的元素</div>
</div>

2、.example.pp中间没有空格隔开,选择的是class中同时包含example和pp的元素

<div class="example pp">
    被选择的元素
</div>
❤️CSS中行内元素与块级元素的区别:

一区别:
1、行内元素会在一条直线上排列(默认宽度只与内容有关),都是同一行的,水平方向排列。
2、块级元素各占据一行(默认宽度是它本身父容器的100%(和父元素的宽度一致),与内容无关),垂直方向排列。块级元素从新行开始,结束接着一个断行。
3、块级元素可以包含行内元素和块级元素。行内元素不能包含块级元素,只能包含文本或者其它行内元素。
4、行内元素与块级元素属性的不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效

display:block; (字面意思表现形式设为块级元素)
display:inline; (字面意思表现形式设为行内元素)

二、inline-block
inline-block 的元素(如input、img)既具有 block 元素可以设置宽高的特性,同时又具有 inline 元素默认不换行的特性。当然不仅仅是这些特性,比如 inline-block 元素也可以设置 vertical-align(因为这个垂直对齐属性只对设置了inline-block的元素有效) 属性。
HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,使用inline-block 会产生元素间的空隙。

三、修改Mac本机host,调试用

sudo vim /etc/hosts打开配置文件编辑
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
127.0.0.1 test.com  //添加此行作为测试域名
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

四、root伪类

:root
这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 <html> 元素,除了优先级更高之外,与 html 选择器相同

image.png

五、关于oninput事件和onchange事件在<input>标签中的表现

image.png

六、el.onscroll 元素的scroll事件处理函数

image.png

// 监听自定义滚动条事件
scrollEvent() {
  //拿到ref="menusScrollbar"的__wap类,元素对象。
  let scrollbarEl = this.$refs.menusScrollbar.wrap
  scrollbarEl.onscroll = () => {
    this.subHeaderShadow = scrollbarEl.scrollTop > 0
  }
},

mounted() {
    //在mounted里调用就会持续监听
    this.scrollEvent()
}

七、标签不识别\n的解决办法

识别不了 ‘\n’,只要在结果所在的标签设置css样式:
white-space: pre-line;

八、reduce使用

首先看reduce源码

Array.prototype.fakeReduce = function(fn, initialValue) {
  if (typeof fn !== 'function') {
    throw new TypeError('fn is not a function!');
  }
  // 保存原数组
  let initialArr = this;
  // 复制原数组
  let arr = [...initialArr];

  if (initialValue) arr.unshift(initialValue);
  let index, newValue;

  while (arr.length > 1) {
    index = initialArr.length - arr.length + 1;
    // 返回数组的前2项的计算结果
    newValue = fn.call(null, arr[0], arr[1], index, initialArr);
    // 将arr数组的前2项删除并将其计算结果推到arr数组的首部
    arr.splice(0, 2, newValue);
  }
  return newValue;
};

使用场景
1、数组扁平化

function flattMap(arr) {
  return Array.isArray(arr)
    ? arr.reduce((acc, value) => [
      ...acc,
      ...flattMap(value)
    ], [])
    : [arr];
}
flattMap([1, [2, 3], 1]); // [1, 2, 3, 1]

2、对象过滤

const pick = (obj, arr) => {
  return arr.reduce((acc, curr) => {
    if (curr in obj) {
      acc[curr] = obj[curr];
      return acc;
    }
  }, {})
}
pick({a: 1, b: 2}, ['a']) // { a: 1 }

九、$attrs

注意红色的那段话的意思
image.png
也就是一个标签上加上:class="{xxx}"之类的往标签组件中传,却不需要props接收

十、优化for循环嵌套(主要解决for循环children)

#用递归的方式遍历优化
function recursion(arr) {
    arr.forEach(function(item) {
        if (item.children) {
            recursion(item.children);
        }
    });
}
recursion(chapterTree);

十、Vue内置组件transition列表移除动画过渡的效果作用永远在最后一个元素上的问题

解决::key绑定的值为index会导致这个问题,把它修改成id或其他。

十一、transform快速画梯型之类的

image.png

十二、transform的translate实现阴影

image.png

十三、keyup、keydown、keypress

keydown:按下键盘键
keypress:紧接着keydown事件触发(只有按下字符键时触发)
keyup:释放键盘键
keydown -> keypress ->keyup

1、用户按下键盘上的字符键时
首先会触发keydown事件
然后紧接着触发keypress事件
最后触发keyup事件
如果用户按下了一个字符键不放,就会重复触发keydown和keypress事件,直到用户松开该键为止

2、当用户按下非字符键时
首先会触发keydown事件
然后就触发keyup事件
如果用户按下了一个非字符键不放,就会重复触发keydown事件,直到用户松开该键为止

keypress的特别之处

1、keypress对中文输入法支持不好,无法响应中文输入,利用这一项可以对确认事件用@keypress.enter来巧妙得利用
2、在chrome中基本上keypress无法响应大多数的系统功能键(如delete,backspace)

键盘中的键分为 字符键 (可打印) 和 功能键 (不可打印)
keypress支持的系统功能键 :
Firefox:Esc、Enter、Backspace、Pause Break、Insert、 Delete、Home、End、Page Up、Page Down、F1 through F12、The Arrow Keys、上下左右键
Chrome / Oprea / Safari :Enter
IE:Esc、Enter
除了 Firefox,其他chrome、oprea、safari、IE 上下左右键不会触发kepress

十六、JS多态

举个例子:假设家里养了一只猫和一只狗,两只宠物都要吃饭,但是吃的东西不太一样,根据主人的吃饭命令,猫要吃鱼,狗要吃肉,这就包含了多态的思想在里面

let petEat = function (pet) {
  pet.eat()
} 
let Dog = function () {}
Dog.prototype.eat = function () {
  console.log('吃肉')
}
let Cat = function () {}
Cat.prototype.eat = function () {
  console.log('吃鱼')
}

petEat(new Dog())
petEat(new Cat())

JS对象既可以是Dog类型的对象也可以是Cat类型的对象,JS这类动态语言的对象多态性是与生俱来的。多态的作用是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句
如果在没有使用对象的多态性之前代码可能是这样是的:

let petEat = function (pet) {
  if (pet instanceof Dog) {
    console.log('吃肉')
  } else if (pet instanceof Cat) {
    console.log('吃鱼')
  }
}
let Dog = function () {}
let Cat = function () {}
petEat(new Dog())
petEat(new Cat())

代码重构的理念中,是否一定需要消除if条件转为多态的形式,还是根据代码的实际情况来决定是否转为多态重构。
当然上面有个知识点就是:上面两个构造函数,且在原型上写了方法。我们如果把它放到es6的类里面,两个方法就是实例方法,即可以简单得出JS的类的概念、类实例方法构造函数、原型链有底层上的一致性,JS的类不同于java中的类。js是一门基于Function和原型链的语言。


Macrohoo
25 声望2 粉丝

half is wisdom!🤔