数组去重
1.利用ES6 Set去重(ES6中最常用) ...new set()
2.利用for嵌套for,然后splice去重
3.利用indexOf去重
4.利用sort()
5.利用filter
6.利用Map数据结构去重
vuex
1.vuex是一个为 Vue.js 应用程序开发的状态管理模式。采用集中式存储管理应用的所有组件的状态,以相应的规则保证状态以一种可预测的方式发生变化。
2.每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割
3.单向数据流
数据可视化
https://www.cnblogs.com/xiyangbaixue/p/4034437.html
v-if和v-show的区别
共同点:v-if 和 v-show 都能实现元素的显示隐藏
区别:
1. v-show 只是简单的控制元素的 display 属性,而 v-if 才是条件渲染(条件为真,元素将会被渲染,条件为假,元素会被销毁);
2. v-show 有更高的首次渲染开销,而 v-if 的首次渲染开销要小的多;
3. v-if 有更高的切换开销,v-show 切换开销小;
4. v-if 有配套的 v-else-if 和 v-else,而 v-show 没有
5. v-if 可以搭配 template 使用,而 v-show 不行
基本数据类型:number,string,boolean,null,undefined,symbol等;
引用数据类型:object({}对象,数组[]),function函数等;
栈: 原始数据类型(Undefined,Null,Boolean,Number、String)
堆: 引用数据类型(对象、数组、函数)
深拷贝浅拷贝
浅拷贝,只是拷贝指向原来对象的地址,新旧对象共享一块内存;
深拷贝,复制并创建一个一摸一样的对象(拷贝的值是一样的,但是内存地址不一样,)
1.列表内容会创建一个新的内存空间,
2.不共享内存,修改新对象,旧对象保持不变
实现浅拷贝的方法
1.利用es6 Obect.assign()实现浅拷贝
var obj = {name:"lily",age:18};
var copy_obj = Object.assign({},obj) // {name: "lily", age: 18}
2.直接引用赋值
var arr1 = ["a","b",1,2,3];var arr2 = arr1
3.$.extend( [deep ], target, object1 [, objectN ] )jquery实现浅拷贝
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
var obj1 = {name:"lily"};
var obj2 = {age:16};
var obj3 = {sex:male};
var objnew = $.extend(false,{},obj1,obj2,obj13)
实现深拷贝的方法
1.$.extend( [deep ], target, object1 [, objectN ] )jquery实现浅拷贝
第一个参数改为true可以实现深拷贝
2.递归实现深拷贝
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } }
}
} return objClone;}
3.可以借用JSON对象的parse和stringify
function deepClone(obj){ let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone}
使用typeof来检测数据类型
可以使用typeof来检测数据类型:
“undefined”-->这个变量是未定义的(为初始化的变量和未声明的变量的typeof操作都返回undefined)
”boolean“-->这个值是布尔值
”string“ -->这个值是字符串
”number“-->这个值是数字
”object“-->这个值为null或者obejct
”function“-->这个值是函数、
div居中
1.text-align:center
2:margin:0 auto
3:行内元素的垂直居中把height和line-height的值设置成一样的即可。
4:使用css3的translate水平垂直居中元素
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
5: 使用css3计算的方式居中元素calc
position: absolute;
top: calc(50% - 50px); //高的一半
left: calc(50% - 150px); //宽的一半
width: 300px;
height: 100px;
6:使用position:fixed为最佳方案,因为position:fixed定位是相对于整个浏览器页面的。
7:flex布局
父级元素:{ display:flex;flex-direction:row;justify-content:center;align-items:center;}
子级元素:{flex:1}
lass和scss 与 css 的区别
sass的内联写法:
<style lang="sass" scoped>
//sass样式
</style>
less的内联写法:
<style lang="less" scoped>
//less样式
</style>
css的内联写法:
<style lang="css" scoped>
//css样式
</style>
less和sass引用方法
<style lang="sass" src="./index.sass"></style>
css引用方法
<style lang="css">
@import './index.css'
</style>
或者
<style lang="css" src="./index.css"></style>
写法区别
Sass 时不带有大括号和分号,
1.变量,Less-作用域
如
@color:#00c;
#header{
@color:#c00;/*red*/
border:1px solid @color;/*红色边框*/
}
#footer{
border:1px solid @color;/*蓝色边框*/
}
就相当于js里面设置全局变量和局部变量的作用域
2.嵌套,
3.运算符,可以直接在css预处理中进行样式计算
body{
margin:(14px/2);
top:50px+100px;
right:100px-50px;
left:10*10;
}
4.混入(Minxin),
创建一个minxin来处理不同浏览器的css写法是很简单的,节省了大量的重复工作和痛苦的代码编辑。
Sass
@mixin border-radius($values){
-webkit-border-radius:$values;
-moz-border-radius:$values;
border-radius:$values;
}
5.继承,
如:sass写法
.block{
margin:10px 5px;
padding:2px;
}
p{
@extend .block;/*继承上面声明的.block*/
border:1px solid #fee;
}
6.颜色处理,
css预处理一般都会内置一些颜色处理函数用来对颜色值进行处理,如:加亮,变暗,颜色梯度等。
如sass的部分颜色处理函数:
lighten($color,10%);
darken($color,10%);
实例:
$color:#89234c
h1{
background:$color;
border:3px solid darken($color,50%)
}
Less和Sass的主要不同就是他们的实现方式。
Less是基于JavaScript,是在客户端处理的。
Sass是基于Ruby的,是在服务器端处理的。
关于变量在Less和Sass中的唯一区别就是Less用@,Sass用$。
keep—alive
以Vue提供了一个内置组件keep-alive来缓存组件内部状态,避免重新渲染。(在开发Vue项目的时候,有一部分部分组件是没必要多次渲染的)
keep-alive属性:
include - 字符串或正则表达式。只有匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。
缓存动态组件:
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们(此种方式并无太大的实用意义)
缓存路由组件:
使用keep-alive可以将所有路径匹配到的路由组件都缓存起来,包括路由组件里面的组件,keep-alive大多数使用场景就是这种。
meta:{
keepAlive:true
}
缓存你想要缓存的:
使用v-if通过路由元信息判断缓存哪些路由
生命周期钩子:
在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated 与 deactivated
activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用
deactivated:组件被停用(离开路由)时调用
注意:使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
新增属性:
include:匹配的 路由/组件 会被缓存
exclude:匹配的 路由/组件 不会被缓存
include和exclude支持三种方式来有条件的缓存路由:采用逗号分隔的字符串形式,正则形式,数组形式。
注:当组件被exclude匹配,该组件将不会被缓存,不会调用activated 和 deactivated。
commponted和行watch区别
computed 是计算属性,依赖其他属性计算值,并且 computed 的值有缓存,只有当计算值变化才会返回内容。
watch 监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。
所以一般来说需要依赖别的属性来动态获得值的时候可以使用 computed,对于监听到值的变化需要做一些复杂业务逻辑的情况可以使用 watch。computed计算属性,用于对原数据进行修改
computed: {
newPrice () {
return '¥' + this.price + '元';
}
}
TCP三次握手建立连接
1 . 第一次握手
客户端发送带有SYN标志的连接请求报文段,然后客户端就进入了SYN_SEND状态 等待服务器确认
2 . 第二次握手
服务端接收到了客户端浏览器发送的SYN标志报文段后,需要发送ACK确认报文段对这个SYN报文段进行确认。同时又会向客户端发生自己的SYN请求信息。服务端会将上述信息放到一个报文段(SYN+ACK报文段)中 一同发送给客户端。此时服务端进入SYN_RECV阶段
第三次握手
客户端浏览器接收到了服务端返回的SYN+ACK报文段(请求+返回)后,会向服务器发送新的ACK确认报文段。该报文段发送完毕后,客户端和服务端都进入到了ESTABLISHED状态,此时 就完成了三次握手
实例事件
$on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法
你了解插槽不?
回答:插槽就是slot,是组件的一块Hmtl模板
你了解axios吗?
Axios 是基于 promise 的 HTTP 库,用在浏览器和 node.js 中。就是前端最火最简单的一个http请求解决方案。
v-if和v-for的优先级
v-for和v-if不应该一起使用,必要情况下应该替换成computed属性。
原因:v-for比v-if优先级高,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。
防抖和节流
防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
应用场景
(1) 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;
(2) window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;流
节流:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
应用场景:
(1)鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
(2)在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;
(3)监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;
效果:
函数防抖是某一段时间内只执行一次;而函数节流是间隔时间执行,不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。
-- 原理:
防抖是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发。
节流是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器。、
vue传参方式
1:父传子
父 v-bind:fData="data1"
字: props: ['fData', 'fMessage'],
2:子传父
子:在子组件中创建一个按钮,定义一个点击事件,点击事件里用this.$emit方法触发一个自定义事件,并传递一个参数
触发一个方法 调用 this.$emit("toFatherData","给爸爸的爱")
父:在父组件中的子标签中监听该自定义事件并添加一个响应该事件的处理方法,将接收到的值赋给data中的sendSonMessage
<Son :toSonData="toSonData" @toFatherData="sendSonData"></Son>
sendSonData(data){ this.sendSonMessage=data; }
Vue更改了data里的数据,但是视图却没有更新
1、v-for遍历的数组,当数组内容使用的是arr[0].xx =xx更改数据,vue无法监测到
数组数据变动:我们使用某些方法操作数组,变动数据时,有些方法无法被vue监测,有些可以
Vue包装了数个数组操作函数,使用这些方法操作的数组去,其数据变动时会被vue监测:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
vue2.0还增加个方法可以观测Vue.set(items, indexOfItem, newValue)
filter(), concat(), slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组
Vue 不能检测以下变动的数组:
① 当你利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
② 当你修改数组的长度时,例如: vm.items.length = newLength
map filter foreach区别
1.forEach循环,循环数组中每一个元素并采取操作, 没有返回值, 可以不用知道数组长度
2.map函数,遍历数组每个元素,并回调操作,需要返回值,返回值组成新的数组,原数组不变
3.filter函数, 过滤通过条件的元素组成一个新数组, 原数组不变
4.some函数,遍历数组中是否有符合条件的元素,返回Boolean值
5:every函数, 遍历数组中是否每个元素都符合条件, 返回Boolean值
js数组转字符串(3种方法)
1: toString()
2: toLocalString()
3: join()
vara=[1,2,3,4,5];//定义数组
vars=a.join("==");//指定分隔符
console.log(s);//返回字符串“1==2==3==4==5”
js字符串转数组
1: split() 方法把字符串转换为数组。
split() 方法是 String 对象方法,与 join() 方法操作正好相反。该方法可以指定两个参数
第 1 个参数为分隔符,指定从哪儿进行分隔的标记;第 2 个参数指定要返回数组的长度
vars="1==2== 3==4 ==5";
vara=s.split("==");
console.log(a);
console.log(a.constructor==Array);