踩坑记录

363 阅读9分钟

使用vue自带的component组件来注册组件

组件化与模块化的区别

  • 什么是组件:组件的出现,就是为了拆分Vue实例的代码量,能够让我们以不同的组件,来划分不同的功能模块 ,将来我们需要什么功能,就可以去调用对应的组件即可

组件化与模块化的不同:

  • 模块化:是从代码逻辑的角度进行分析,方便代码分层开发,保证每个功能模块的职能单一  
  • 组件化:是从UI界面的角度进行划分,前端的组件化,方便UI组件的重用。

组件的引用可以使用组件的名字直接引用 也可以使用Vue给我们提供的的元素

Vue 提供了component,来展示对应名称的组件

component是一个占位符,:is属性可以用来指定要展示的组件名称

<compnent :is="comName" ></component>
 <component :is="menu.component"
            v-for="(menu, index) in menuList"
            :id="String(index)"
            :key="menu.name"
            ref="menuItem"
            v-bind="menu.attrs"
            v-on="menu.events"></component>
            
            menuList() {
            return [
                {
                    component: MenuEvent
                },
                {
                    component: MenuOnline,
                    events: this.menuEvents
                },
                {
                    name: 'flowOffline',
                    component: MenuOffline,
                    events: this.menuEvents
                },
                {
                    component: MenuScript,
                    events: this.menuEvents
                },
                {
                    component: MenuDataSheet
                },
                {
                    component: MenuMq
                },
                {
                    component: MenuResource
                }
            ];
        },

拖动拖到子元素的时候会触发父元素的dragleave

stackoverflow.com/questions/1…

var dragging = 0;

attachEvent(window, 'dragenter', function(event) {

    dragging++;
    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragover', function(event) {

    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragleave', function(event) {

    dragging--;
    if (dragging === 0) {
        $(dropzone).removeClass('drag-n-drop-hover');
    }

    event.stopPropagation();
    event.preventDefault();
    return false;
});

滚动条悬浮内容上面

overlay属性在有滚动条的情况下不会挤压内容区域而影响布局,但是只要Chrome浏览器支持,所以前面在加个属性。

overflow: auto
overflow:overlay 

module.export 和 exports

在commonjs规范中,模块到处的是module.exports,而exports是对module.exports的一个引用。相当于exports = module.exports;若你修改exports的引用,那么他将与module.exports无关。

export 和 export default

exportexport default均可用于导出常量、函数、文件、模块等
在一个文件或模块中,exportimportexport defaul都可以有多个
通过export方式导出,在导入时要加{ },export default则不需要
export能直接导出变量表达式,export default不行。

async 并发执行

// 并发的两种写法
// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

git pull --rebase解决冲突

2020/2/19

element表单验证多层嵌套 segmentfault.com/a/119000001…

不记录时间了

pointer-events: none

阻止用户的点击动作产生任何效果

阻止缺省鼠标指针的显示

阻止CSS里的 hover 和 active 状态的变化触发事件

阻止JavaScript点击动作触发的事件

2019/9/23-2019/9/27

  • user-select
  • git reset和git revert的区别
  • drag的学习

1.user-select

使用场景: 做网页的时候,有些文字我们需要能被选中,有些我们不要能被选中,那么这就需要用到一个css属性了,那就是 user-select。

属性值:

none : 元素和子元素的文本将无法被选中
text : 文本可以被选中
auto : 文本将根据浏览器的默认属性进行选择
all : 当所有内容作为一个整体时可以被选择。如果双击或者在上下文上点击子元素,那么被选择的部分将是以该子元素向上回溯的最高祖先元素

2.git reset和git revert

在利用github实现多人合作程序开发的过程中,我们有时会出现错误提交的情况,此时我们希望能撤销提交操作,让程序回到提交前的样子,总结两种解决方法:回退(reset)、反做(revert)。


git的版本管理,及HEAD的理解 使用git的每次提交,Git都会自动把它们串成一条时间线,这条时间线就是一个分支。如果没有新建分支,那么只有一条时间线,即只有一个分支,在Git里,这个分支叫主分支,即master分支。有一个HEAD指针指向当前分支(只有一个分支的情况下会指向master,而master是指向最新提交)。每个版本都会有自己的版本信息,如特有的版本号、版本名等。

git reset

HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

使用场景: 如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法。

版本回退后使用git push -f提交更改,此时使用“git push"会报错,因为本地库HEAD指向的版本比远程库的要旧。

git revert

原理: git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。

使用场景: 如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。

2019/9/16-2019/9/20

  • offsetWidth、offsetLeft是什么
  • echarts样式覆盖?
  • 跳出foreach循环

1. offsetWidth、offsetHeight、offsetTop、offsetLeft...

offsetLeft、offsetTop 子元素相对于父元素的位移(左位移、上位移) offsetWidth、offsetHeight 元素的可见宽度和可见高度 clientX、clientY 用于获取鼠标坐标(相对于页面的坐标)

style.left返回的是字符串、offsetLeft返回的是数值
style.left可读可写,offsetLeft只读
style.left的值需要预先定义,否则取到的值为空; offsetLeft不需提前定义,直接获取

使用场景: 鼠标移上某个菜单或者某个位置,显示一个弹出框,移开则隐藏弹出框,就是css中hover效果,这种通常做法是每个子菜单下都有一个弹框,父元素相对定位,子元素绝对定位,只需要控制的弹框的显示与隐藏即可,但是,当鼠标移动到边界的菜单上时,弹框可能会超出外部元素的范围。

解决方案: 动态的计算弹框距离外部元素的位置,即获取元素的offsetLeft、offsetTop、offsetWidth、offsetHeight,如果弹框的宽度(offsetWidth)+距离左边的距离(offsetLeft)大于父元素的宽度,则判断为超出外部元素范围,需要动态改变弹框距离边框的位置。

这里对弹框的布局有限制,虽然弹框要隐藏,但是不能使用display:none的方式隐藏,可以使用opacity:0或者visibility: hidden隐藏元素,因为display:none方式不能获取到元素的高度,宽度等

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    #box {
        width: 500px;
        height: 500px;
        background: #0a67fb;
        margin: 100px auto;
        position: relative;
    }

    #inner-box {
        width: 200px;
        height: 200px;
        background: #00F7DE;
        position: absolute;
        top: 50px;
        left: 320px;
        visibility: hidden;
    }
</style>
<body>
<div id="box">
    <div id="inner-box">
    </div>
</div>
<script>
    var box = document.querySelector('#box');
    var innerbox = document.querySelector('#inner-box');

    box.onmouseenter = function (e) {
        var wrapperBoxWidth = box.offsetWidth;// 获取父容器宽度
        var wrapperBoxHeight = box.offsetHeight;// 获取父容器高度

        var innerBoxWidth = innerbox.offsetWidth;// 获取弹框宽度
        var innerBoxHeight = innerbox.offsetHeight;// 获取弹框高度
        var innerBoxLeft = innerbox.offsetLeft;// 获取弹框距离左侧宽度
        var innerBoxTop = innerbox.offsetTop;// 获取弹框距离顶部高度

        innerbox.style.visibility = 'visible'  // 鼠标移入时显示弹框

        // 如果弹框宽度+距离左侧宽度大于外部元素的宽度,则右侧溢出
        if (innerBoxLeft + innerBoxWidth > wrapperBoxWidth) {
            innerbox.style.left = 'auto'
            innerbox.style.right = '10px'
        }

        // 如果弹框高度+距离顶部高度大于外部元素的高度,则底部溢出
        if (innerBoxTop + innerBoxHeight > wrapperBoxHeight) {
            innerbox.style.top = 'auto'
            innerbox.style.bottom = '10px'
        }
    }
    box.onmouseleave = function () {
        innerbox.style.visibility = 'hidden' // 鼠标移开时隐藏弹框
    }
</script>
</body>
</html>

2.echarts样式覆盖

最近在做关于echarts画图的项目的时候,对于先前生成的echarts图,我后续的操作中改变他的option的时候,它会将先前的数据也加进去;通过查阅echarts文档后,发现,文档中写到 setOption是设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过 setOption 完成,ECharts 会合并新的参数和数据,然后刷新图表。

chart.setOption(option, notMerge, lazyUpdate);
option
图表的配置项和数据,具体见配置项手册。
notMerge
可选,是否不跟之前设置的 option 进行合并,默认为 false,即合并。
lazyUpdate
可选,在设置完 option 后是否不立即更新图表,默认为 false,即立即更新。

解决方案: chart.setOption(option, true);

chart.clear(); //清空当前实例,会移除实例中所有的组件和图表。清空后调用 getOption 方法返回一个{}空对象。

3.终止foreach循环

foreach()无法在所有元素都传递给调用的函数之前终止遍历。

解决方案: 因为foreach()无法通过正常流程终止,所以可以通过抛出异常的方式实现终止。

try {
    var array = ["first","second","third","fourth"];
    
    // 执行到第3次,结束循环
    array.forEach(function(item,index){
        if (item == "third") {
            throw new Error("EndIterative");
        }
        alert(item);// first,sencond
    });
} catch(e) {
    if(e.message!="EndIterative") throw e;
};
// 下面的代码不影响继续执行
alert(10);

2019/9/3-2019/9/6

  • 熟悉filter、map、foreach的使用场景
  • 使用.native
  • transition与display冲突怎么办
  • 如何使子元素滚动父元素不滚动
  • 利用hover伪类改变其他元素

1. 熟悉filter、map

首先这里有一个数组:

let array = [{name:'liuliu',age:8},
             {name:'chuchen',age:10}];

我想拿到其中名字为刘刘的,使用filter: array.filter(callback,[ thisObject]);:

array.filter(item=>{return item.name==='liuliu'})

我想知道数组中所有人的名字,使用map: array.map(callback,[, thisObject])

array.map(item=>{return item.name})

2.使用.native

之前在阅读vue中文文档的时候,没有过多的注意这个修饰符,直到我在使用element组件的时候,想给下拉菜单组件添加一个click事件,却发现没有效果。 查阅资料后才发现,v-on 是对 Vue 的事件体系封装后的 API 接口,官方文档中指出Vue 使用的是一套自己的事件传递机制,如 @click 等事件是经过 Vue 封装的。所以在一些实际上处理 DOM 原生事件的场合需要添加额外的标识符。

所以需要在click后面加一个.native将组件变成一个普通的HTML标签,但是该修饰符对普通HTML标签无效。
<el-dropdown-menu slot="dropdown">
    <el-dropdown-item @click.native="editFeatureGroup(data)">编辑</el-dropdown-item>
    <el-dropdown-item @click.native="deleteFeatureGroup(data)">删除</el-dropdown-item>
</el-dropdown-menu>

3.transition与display冲突怎么办

在做项目的时候,我遇到了这样一个问题,我想让一个div逐渐消失,当然是用transition是没有问题的。但是运行的时候发现,transition没有起到效果,那其中的原因是什么呢? display的操作会触发浏览器的reflow操作,而transition支持的效果只是触发浏览器的repaint操作,如果我们通过visibility属性来控制显示与隐藏,则不会破坏transition的效果。所以,可以暂时这么认为:reflow与repaint的混合会破坏transition的动画效果。

解决方法:使用visibility替代display

visibility:hidden的时候元素任然存在于文档流中,同时visibility:hidden对应的数值0,visibility:visible对应的数值1,transition属性可以对0~1之间进行过渡。

4.如何让div不撑开父元素

  • 1.使用fixed
  • 2.父元素设置overflow:hidden, 子元素设置overflow:auto

5 利用hover伪类改变其他元素

<div class="parentA">
    <div class="children">
    </div>
<div>
<div class="parentB"></div>
  • 改变子元素
.parentA:hover .children {}
  • 改变兄弟元素(只能改变相邻兄弟元素)
.parentA:hover + .parentB{}
.parentA:hover ~.parentB{}