开发经验汇总和一些问题的解决方法

js深拷贝浅拷贝

  • Object.create()为对象层面的深拷贝

  • Object.assign()当对象只有一层时为深拷贝,当有嵌套对象时为深拷贝

对象多个属性赋值

Vue.options.components = {}
Vue.options.directives = {};
Vue.options.filters = {};

// 相当于,且更方便维护
const ASSET_TYPES = ['component','directive','filter'];
ASSET_TYPES.forEach(type => {Vue.options[type + 's'] = Object.create(null)});

使用js+css实现粘性布局

// 获取滚动的总高度
getScrollTop() {
let scrollTop = 0;
let bodyScrollTop = 0;
let documentScrollTop = 0;
if (document.body) {
bodyScrollTop = document.body.scrollTop;
}
if (document.documentElement) {
documentScrollTop = document.documentElement.scrollTop;
}
scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
return scrollTop;
},
// 文档的总高度
getScrollHeight() {
let scrollHeight = 0;
let bodyScrollHeight = 0;
let documentScrollHeight = 0;
if (document.body) {
bodyScrollHeight = document.body.scrollHeight;
}
if (document.documentElement) {
documentScrollHeight = document.documentElement.scrollHeight;
}
scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
return scrollHeight;
},
// 获取可见页面的总高度
getWindowHeight() {
let windowHeight = 0;
if (document.compatMode === 'CSS1Compat') {
windowHeight = document.documentElement.clientHeight;
} else {
windowHeight = document.body.clientHeight;
}
return windowHeight;
},
window.onscroll = function(){
if(getScrollTop() + getWindowHeight() == getScrollHeight()){
alert("已经到最底部了!!");
}
};

flex自动充满的用处

display: flex;

// 子容器中
height: auto;

html 拖拽代码

let draging = false;
let isdrop = false;

function getDOMs(el) {
return document.querySelectorAll(el);
}

function setData(e, data) {
const setDate = JSON.stringify(data);
if (e.dataTransfer.setData) {
e.dataTransfer.setData('dropData', setDate)
}else {
sessionStorage.setItem('dropData', setDate);
}
}

function getData(e) {
if (e.dataTransfer.getData) {
return JSON.parse(e.dataTransfer.getData('dropData'));
}else {
return JSON.parse(sessionStorage.getItem('dropData'));
}
}

function bindDrag(dom,dragStart,dragEnd) {
let offsetX;
let offsetY;
dom.ondragstart=function(e){
if (draging) return;
draging = true;
dom.style.opacity = 0;
if (dragStart) {
dragStart();
}
setData(e, {
componentName: e.srcElement.dataset.componentname,
groupName: e.srcElement.dataset.group,
type: 'component',
})
}
dom.ondrag=function(e){
let x= e.pageX;
let y= e.pageY;
//drag事件最后一刻,无法读取鼠标的坐标,pageX和pageY都变为0
if(x === 0 && y === 0){
return; //不处理拖动最后一刻X和Y都为0的情形
}
x-=offsetX;
y-=offsetY;
}
dom.ondragend=function(e){
draging = false;
// if (isdrop) {
// isdrop =false;
// }else {
// dom.style.opacity = 1;
//};
dom.style.opacity = 1;
if (dragEnd) {
dragEnd();
};
}
}


function dragenter(e) {
e.stopPropagation();
e.preventDefault()
};
function dragover(e) {
e.stopPropagation();
e.preventDefault();
};
function drop(e, dropCB) {
e.stopPropagation();
e.preventDefault();
console.log(getData(e))
if (dropCB) {
// 调用增加组件方法
return dropCB(getData(e));
}
return false;
}

function getDOM(el) {
return document.querySelector(el);
}

const DragUtil = {
drag (el,dragStart,dragEnd) {
const doms = getDOMs(el);
doms.forEach( item => {
bindDrag(item,dragStart,dragEnd);
})

},
addDropListen(el,dropCB) {
let dom = getDOM(el);
dom.ondragenter = function(e){
dragenter(e);
};
dom.ondragover = function(e) {
dragover(e);
};
dom.ondrop = function(e) {
const returnFlag = drop(e,dropCB);
isdrop = true;
};
},
};

export default DragUtil;
// 因为业务的原因,也增加了一些多余的逻辑,当拖拽的元素使用opacity:0时,如果不加动画效果延迟,拿拖拽就为空,这里需要注意下

vue子组件修改props的问题

  • 再使用iview的抽屉时,因为将抽屉做成了一个组件,所以使用props去控制抽屉的打开与关闭,但是因为右上角自带的关闭按钮导致子组件
    会自动修改props中的值,触发报错。

  • 一开始想用computed去吧props的值做一个copy,但是由于vue的新版本导致computed的属性必须要set,所以做如下修改

computed: {
showDrawerTemp: {
get() {
return this.showDrawer;
},
set() {
},
},
},

关于github提交没有提交记录的问题

  • 经常发现是用另外一个电脑去提交代码的时候,git没有算到我的提交记录里面,经过查证发现,是因为邮箱地址的错误,导致提交时不算是我的
    将邮箱地址修改即可

  • Git总结

1

2

3

git上ssh的问题

git修改最近一次的commit信息

git commit --amend

better-scroll 滚动

vuepress中重复提交导致docs目录覆盖dist目录的问题

重复提交之前,需要使用git init来将仓库清空,重新去上传dist文件夹

使用vue-meta-info和预渲染解决单页面应用seo问题

vue路由重定向

if (to.path !== '/login' && !Util.getDataFormSessionStorage('USERINFO', true, '') && !Util.getDataFromLocalStorage('USERINFO', true)) {
router.push({ path: '/login' });
next({
path: '/login',
// query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
});
} else {
next();
}

flex无限放大的问题

  • 主要是因为当前dom宽度超过界面宽度,所以当界面拖动的时候,display:webkit-box和display:flex会导致元素无限变成,解决方法就是将元素的宽度限制死,不要超过界面宽度

移动端开发的常见问题和解决方案

//640px作为设计稿基准
$vm_base: 640;
@function vm($px) {
@return ($px / 640) * 100vw;
}

//通过代码,假如设计稿中元素的宽度是 40px ,那么就可以在样式中写
.test{
width:vm(40)
}

less中使用calc函数

.echarts {
height: calc(~"100vh - 222px");;
}

纯css的波浪条纹实现

.ivu-progress-bg {
background: repeating-linear-gradient(-60deg,#166aee 10px,#72a8f5 0%,#72a8f5 20px,#166aee 0%,#166aee 30px, #72a8f5 0%);
background-size: 100% 13px;
}
注意其中background-size的把控

css修改浏览器输入框提示字的样式

  /* WebKit browsers */
input::-webkit-input-placeholder {
color: red;

/* Mozilla Firefox 4 to 18 */
input:-moz-placeholder {
color: #666;
}
/* Mozilla Firefox 19+ */
input::-moz-placeholder {
color: #666;

/* Internet Explorer 10+ */
input:-ms-input-placeholder {
color: #666;
}


### icon-font symbol引用无法修改颜色的问题

* http://www.cnblogs.com/jopny/p/9454785.html

### vue获取当前路由下的组件

```javascript
this.$route.matched[2].components
  • 对当前路由视图直接使用ref,则可以直接指向当前活动的component

关于async await的一些问题

  • await关键字必须在async关键字下使用。。。否则后果很严重

移动端的vw适配方案

  • 设计搞切成375版本,直接使用vw作为单位

  • 字体显示多少pt就用多少px,不需要转换

  • 除了特殊情况,一般都是用vw作为显示单位,如果要支持pad横屏显示,就要用vmin(因为宽度总是小于高度)

vue图片动态加载解决方案

img: require('../../assets/guessLike.png'),

vue预渲染示例

https://github.com/chrisvfritz/prerender-spa-plugin/tree/e2c49428e0efab5a672f421a3a33da45fc345710/examples/vue2-webpack-router

css transform同时实现多个属性

transform: rotate(360deg) scale(2,2) skew(10deg,5deg); //效果中间用空格隔开即可

vue 路由history模式,tomcat配置

tomcat 目录下免得conf文件夹里面的web.xml文件加上下面的配置

<display-name>webapp</display-name>
<description>
webapp
</description>
<error-page>
<error-code>404</error-code>
<location>/</location>
</error-page>

js判断对象中是否存在属性

对于一般的对象属性需要用字符串指定属性的名称   如:
let mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar // returns true
"model" in mycar // returns true

git patch

git format-patch相对于git diff更便于操作,是更新的打包方式,应该采取这种打包方式。git diff打包的patch只能使用git apply处理。而git format-patch的补丁,可以应当使用git am命令。

基本用法

git format-patch xxxx.patch

https://www.cnblogs.com/zzb-Dream-90Time/p/7693860.html

display: flex justify-content实现间隔布局

justify-content: space-between; 实现元素间隔布局

右上角三角形

.select-dup-com-icon {
position: absolute;
right: 2px;
top: 0px;
.select-icon {
height: 12px;
width: 12px;
z-index: 1;
position: relative;
color: white!important;
display: none;
}
&:after {
content: ' ';
position: absolute;
top: -18px;
right: -20px;
border-left: 18px solid transparent;
border-top: 18px solid transparent;
border-right: 18px solid transparent;
border-bottom: 18px solid transparent;
transform: rotate(-45deg);
}
}

webpack项目依赖再多个文件中的引入方式

// 错误方式

a.Vue
import xxx from '../../../xx';

b.Vue
import xxx from '../../../xx';

//正确方式
webpack.config.js
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}

a.Vue
import xxx from '@/xx';

b.Vue
import xxx from '@/xx';

使用别名,减少代码耦合,这样多出修改的时候,就不用那么麻烦了

wx小程序RPX解析

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。 
rpx 为小程序中使用的相对单位,用法和rem类似, 1rpx = 屏幕宽度/750 px, 所以在屏幕宽度为750的设计稿中,1rpx = 1px。

mpvue 采坑记录

https://www.cnblogs.com/zhouyangla/p/9000879.html
https://github.com/Meituan-Dianping/mpvue/issues/21 // mpvue项目征集
https://www.cnblogs.com/xuyan1/p/9549490.html // mpvue使用iview
http://www.php.cn/xiaochengxu-407509.html // mpvue使用iview

css 渐变 linear-gradient

background: linear-gradient(to bottom,#1986ef 0%, #1986ef 60%, #1fb3e8);

表示从上到下0% —— 70% 是#1986ef ,剩下的用#1fb3e8渐变