0311-0312的笔记
1 elementui里datepicker组件实现结束时间大于起始时间
<el-form-item label="xxx:">
<el-col :span=“10">
<el-form-item prop="startdate">
<el-date-picker
type="date"
:editable="false"
value-format="yyyy-MM-dd"
placeholder="请选择开始时间"
v-model="sxyInfo.startdate"
:picker-options="pickerOptionsStart"
style="width: 100%;"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="1" style="text-align:center;">至</el-col>
<el-col :span=“13">
<el-form-item prop="enddate">
<el-date-picker
type="date"
:editable="false"
value-format="yyyy-MM-dd"
placeholder="请选择结束时间"
v-model="sxyInfo.enddate"
style="width: 100%;"
:picker-options="pickerOptionsEnd"
></el-date-picker>
</el-form-item>
</el-col>
</el-form-item>
data(){
return{
sxyInfo:{},
pickerOptionsStart: {
disabledDate: time => {
let endDateVal = this.sxyInfo.enddate;
if (endDateVal) {
return time.getTime() > new Date(endDateVal).getTime();
}
}
},
pickerOptionsEnd: {
disabledDate: time => {
let beginDateVal = this.sxyInfo.startdate;
if (beginDateVal) {
return (
time.getTime() <
new Date(beginDateVal).getTime() - 1 * 24 * 60 * 60 * 1000
);
}
}
},
}
}
2 img与background-image 的区别
img:
从页面元素来说,页面中的图片是作为内容出现的,比如广告图片,比如产品图片,那么这个必然是用img了,因为这个是页面元素内容。页面元素内容最关键的一点就是,当页面没有样式的时候,还是能一眼看过去就知道什么是什么……
background-image:
背景图片,修饰性的内容,在页面中可有可无。有,是为了让页面中视觉感受上更美;无,并不影响用户浏览网页获取内容。
还有其他的区别之分:
-
1、 是否占位
background-image是背景图片,是css的一个样式,不占位 <img />是一个块状元素,它是一个图片,是html的一个标签,占位
-
2、否可操作
background-image是只能看的,只能设置background-position, background-attachment, background-repeat <img/>是一个document对象,它是可以操作的。比如更换img src的路径可以达到更换图片的目的,也可以移动它的位置,从document中移除等等操作。
-
3、 加载顺序不同
在网页加载的过程中,以css背景图存在的图片background-image会等到结构加载完成(网页的内容全部显示以后)才开始加载, html中的标签img是网页结构(内容)的一部分会在加载结构的过程中加载。 换句话讲,网页会优先加载标签img的内容,再加载背景图片background-image。
-
5、从SEO角度看
Img标签优点是自闭和,可以避免空标签出现(空标签也是w3c验证的内容之一)。采用background方式就会出现空标签。 Img标签是自闭和的,不能添加文本内容,但是,Img有一个alt属性,而且这个属性在w3c标准中,要求必须有,这样做的优点还是很多的。 第一,图片比较大,或者用户网速比较窝火的时候,加载失败了,至少还有文字提示告诉用户这里是个什么内容的图片。如果用户非要看这个图,那就多刷几次去加载。另外,alt属性有利于辅助阅读,尤其是对盲人朋友,他们使用阅读器浏览页面,如果没有文本提示,就太不厚道了。 第二,alt属性有利于SEO,搜索引擎实现很好的图像识别还是有一段路要走。 当然也有缺点: 第一,Img加载的图片是通过src拿到的,如果HTML代码不允许修改,那怎么换图,只有同名文件替换,但是有可能遇到304状态,需要服务器端做相应的设置。这时background的优点就出来了,换皮肤就是这个栗子。 第二,如果图片显示区域空间大小是预留的,那么图片必须和预留的空间一致,否则图片要么被拉伸要么被压缩,都不是等比例操作。当然,避免这种问题就需要前端和视觉设计师遵守一定的规范。
3 input img textarea 是行内即置换元素
替换元素:替换元素根据其标签和属性来决定元素的具体显示内容,置换元素一般内置框高属性,因此可以设置其框高。
可以来说这些是个行内块元素,相对于display:inline-block
比如:img根据src属性来显示,input根据value属性来显示,因此可知道img和input是置换元素,当然同理textarea, select,也是置换元素
4 DOM文档的加载顺序是由上而下的顺序加载
-
1、DOM加载到link标签
css文件的加载是与DOM的加载并行的,也就是说,css在加载时Dom还在继续加载构建,而过程中遇到的css样式或者img,则会向服务器发送一个请求,待资源返回后,将其添加到dom中的相对应位置中; -
2、DOM加载到script标签
由于js文件不会与DOM并行加载,因此需要等待js整个文件加载完之后才能继续DOM的加载,倘若js脚本文件过大,则可能导致浏览器页面显示滞后,出现“假死”状态,这种效应称之为“阻塞效应”;会导致出现非常不好的用户体验;
而这个特性也是为什么在js文件中开头需要$(document).ready(function(){})或者(function(){})或者window.onload,即是让DOM文档加载完成之后才执行js文件,这样才不会出现查找不到DOM节点等问题;
js阻塞其他资源的加载的原因是:浏览器为了防止js修改DOM树,需要重新构建DOM树的情况出现; -
3、解决方法
前提,js是外部脚本;
在script标签中添加 defer=“ture”,则会让js与DOM并行加载,待页面加载完成后再执行js文件,这样则不存在阻塞;
在scirpt标签中添加 async=“ture”,这个属性告诉浏览器该js文件是异步加载执行的,也就是不依赖于其他js和css,也就是说无法保证js文件的加载顺序,但是同样有与DOM并行加载的效果;
同时使用defer和async属性时,defer属性会失效;
可以将scirpt标签放在body标签之后,这样就不会出现加载的冲突了。
5 vue cloned[i].apply is not a function
出现的原因是组件传值的桥梁名字不对,注意组件传值的名字(子=>父)
6 vue组件传值
- 父 => 子
通过props
可以传一个静态值,也可以传个动态值
可以是字符串形式的数组,也可以是对象
array: ['a','b','c']
object: {
'a':String,
'b':Number,
'c':Boolean,
'd':Array,
'e':Object
}
object:{
'q':{
type: Number,
default: 0
}
'a':{
type:String,
required: true //必填项
},
'b':{
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
'c':{
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
- 子 => 父
1 子组件用this.$emit('事件名',值)发送
this.$emit('myclick', '这是我暴露出去的数据', '这是我暴露出去的数据2')
第一个参数是自定义事件的名字
后面的参数是依次想要发送出去的数据
2 父组件利用v-on为事件绑定处理器
<my-component2 v-on:myclick="onClick"></my-component2>
methods: onClick(val){console.log(val)}
注意: 在使用v-on绑定事件处理方法时,不应该传进任何参数,而是直接写v-on:myclick="onClick",不然,子组件暴露出来的数据就无法获取到了
- 兄弟 => 兄弟 (该方法也适合父子之间传值)
1 设置中间件
let Bus = new Vue()
new Vue({
el: '#app',
data:{
Bus
},
components: {App}
})
2 this.$root.Bus.emit()
当前点击发送的事件里
methods: {
click(){
this.$root.Bus.$emit('send',值)
}
}
3 this.\(root.Bus.\)on() 需要在created钩子函数里。
要接受的组件里的created钩子函数里
created(){
this.$root.Bus.$on('send',val => {
console.log(Val)
})
}
7 getElementById,getElementsByTagName,getElementsByName,getElementsByClassName的区别
-
getElementById 根据id声明元素
-
getElementsByTagName 根据标签名声明元素,是一个数组
-
getElementsByName 根据标签里的name名声明元素。是一个数组
-
getElementsByClassName 根据类名声明元素,是一个数组
html: <div id="one">111</div> <div class="two" name="three">222</div> <div class="two" name="three">333</div> <div class="two">444</div> script: let one = document.getElementById('one') let lists = document.getElementsByName('three') let arr = document.getElementsByTagName('div') let arr1 = document.getElementsByClassName('two') console.log('one',one) // one <div id="one">111</div> console.log('lists',lists) // lists NodeList(2) [div.two, div.two] console.log('arr',arr) // arr HTMLCollection(4) [div#one, div.two, div.two, div.two, one: div#one, three: div.two] console.log('arr1',arr1) // arr1 HTMLCollection(3) [div.two, div.two, div.two, three: div.two]
8 DOM操作--- 如何添加、移除、移动、复制、创建和查找节点
-
1)创建新节点
document.createDocumentFragment() //创建一个DOM片段 DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素所代替。 因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。 document.createElement() //创建一个具体的元素 document.createTextNode() //创建一个文本节点
-
2)添加、移除、替换、插入、复制
appendChild() 用于向childNodes列表的末尾添加一个节点,返回要添加的元素节点 insertBefore() 如果不是在末尾插入节点,而是想放在特定的位置上,用这个方法,该方法接受2个参数,第一个是要插入的节点,第二个是参照节点,返回要添加的元素节点 removeChild() 用于移除节点,接受一个参数,即要移除的节点,返回被移除的节点,注意被移除的节点仍然在文档中,不过文档中已没有其位置了 replaceChild() 用于替换节点,接受两个参数,第一参数是要插入的节点,第二个是要替换的节点,返回被替换的节点 cloneNode() 用于复制节点, 接受一个布尔值参数, true 表示深复制(复制节点及其所有子节点),false 表示浅复制(复制节点本身,不复制子节点)
-
3)查找
getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值 getElementById() //通过元素Id,唯一性 getElementsByClassName()
例子:
<div id="pp">111</div>
<ul id="ul">
<li class="frist">1</li>
<li>2</li>
<li>3</li>
</ul>
例子:
var frame = document.createDocumentFragment();
var one = document.createElement('div');
var pp = document.getElementById('pp');
var text = document.createTextNode('112221')
frame.appendChild(text)
frame.appendChild(one);
pp.appendChild(frame);
var ul = document.getElementById('ul');
var li1 = document.createElement('li');
li1.innerHTML='red'
var firstChild = document.getElementsByTagName('li')[1];
ul.insertBefore(li1,firstChild); // 在第二个li的前面加上里li1
var li2 = document.createElement('li');
li2.innerHTML='green'
ul.replaceChild(li2,li1) // red被替换成green
ul.removeChild(li2) // green 被删除
var lastUl = ul.cloneNode(true) // 如果为false,则只复制ul
pp.appendChild(lastUl) // pp里多了ul一样的元素
9 vue给input添加enter事件
<input v-on:keyup.enter="submit”>
在使用过程中,如果页面只针对一个Input添加键盘enter事件,可以直接按照官方文档定义的别名增加相应事件就可以了.但是如果是要对页面的button添加enter键盘事件,就不能写在input或者button上,因为获取不到焦点,这时候可以直接写在created里,
// 错误写法:这么写没有生效
<input type="search" aria-label="Search" maxlength="32" v-model.trim="search_value" @keyup.enter="enterSearchMember">
<button @click="goSearch">搜索</button>
//不能直接将事件添加写在input上,因为这样必须焦点在input上才能触发,所以可以直接绑定在document上即可
created() {
document.onkeydown = e=> {
var key = window.event.keyCode;
if (key == 13) {
this.goSearch()
}
}
},
methods: {
goSearch: function() {
},
enterSearchMember () {
// 无效
}
},
10 vue对于父子组件之间的互相传值,报错如下
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "propTextTip"
大概意思是:避免直接更改一个PROP,因为每当父组件重新呈现时,该值就会被覆盖。
解决办法:
不要直接引用父组件传过来的值,可以把接收到的父组件的值赋值给一个新的属性
11 写出三角形的方法
-
1 css
div{ width:0px; height:0px; border-right:50px solid transparent; border-left:50px solid transparent; border-bottom:50px solid green }
-
2 canvas
html <canvas id="canvas" height="50px" width="50px"></canvas> js let canvas = document.querySelector('canvas'); let ctx = canvas.getContext('2d'); ctx.fillStyle = "red"; ctx.moveTo(0,0); ctx.lineTo(25,25); ctx.lineTo(0,25); ctx.lineTo(0,0); ctx.fill();