1.组件通信
- 父传递子如何传递
- (1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量
- (2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props:["属性 名"] props:{属性名:数据类型}
- 子传递父如何传递
-
(1)在父组件的子组件标签上自定义一个事件,然后调用需要的方法
(2)在子组件的方法中通过 this.$emit("事件")来触发在父组件中定义的事件,数据是以参数的形式进行传递的 - 兄弟组件如何通信
-
(1)在src中新建一个Bus.js的文件,然后导出一个空的vue实例
(2)在传输数据的一方引入Bus.js 然后通过Bus.$emit(“事件名”,"参数")来派发事件,数据是以$emit()的参数形式来传递
(3)在接受的数据的一方 引入 Bus.js 然后通过 Bus.$on("事件名",(data)=>{data是接受的数据})
2.自定义指令
-
【全局指令】
使用 Vue.diretive()来全局注册指令。
【局部指令】
也可以注册局部指令,组件或 Vue 构造函数中接受一个 directives 的选项。钩子函数。指令定义函数提供了几个钩子函数(可选)。
- 钩子函数
- 有哪些钩子函数,及自定义指令的使用场景
- bind(){} 只调用一次,指令第一次绑定到元素时调用
- inserted(){}被绑定元素插入父节点时调用
- update(){}被绑定元素所在的模板更新时调用,而不论绑定值是否变化
- componentUpdated(){}被绑定元素所在模板完成一次更新周期时调用
- unbind(){}只调用一次, 指令与元素解绑时调用
-
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM 在每个函数中,第一个参数el ,表示被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象,。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
3.Vue中双向数据绑定是如何实现
vue.js是采用数据劫持
结合发布者-订阅者模式
的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。
-
第一步: 需要
observer
的数据对象进行递归遍历
,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值
,就会触发setter
,那么就能监听到了数据变化第二步:
compile
解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图第三步:
Watcher
订阅者是Observer
和Compile
之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep
)里面添加自己
2、自身必须有一个update
()方法
3、待属性变动dep.notice()
通知时,能调用自身的update()方法
,并触发Compile中绑定的回调
,则功成身退。第四步:
MVVM
作为数据绑定的入口,整合Observer、Compile和Watcher三者,
通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。 -
Object.defineProperty(obj, prop, descriptor)
参数:
obj:
必需。目标对象;prop:
必需。需定义或修改的属性的名字;descriptor:
必需。目标属性所拥有的特性;
4.简述虚拟DOM和React diff算法
- 虚拟dom是利用js描述元素与元素的关系。
- 好处:是可以快速的渲染和高效的更新元素,提高浏览器的性能
- diff算法
- 优点:最终表现在DOM上的修改只是部分的变更,可以保证高效的渲染,提高网页的性能
- 缺点:首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHtml慢一点
- keep-alive是vue提供给我们的一个组件,用来在路由切换的时候保存我们的组件状态
- 当我们在切换路由需要保存失活组件的状态的时候需要用到,比如我浏览淘宝滑动的中间位置,然后又去购物车页面,再回到首页的时候能够保存住我刚才滑动的位置
https://blog.csdn.net/qq_37430247/article/details/110621729
5.keep-alive是什么
keep-alive是Vue提供给我们一个内置组件,他可以用来保存我们路由切换时组件的状态
1. 全局保存在App.vue中 <keep-alive>把routerView保存起来
2. 部分缓存
1、router.js中设置要缓存的页面
{
path: '/child1',
name: 'Child1',
component: Child1,
meta:{
keepAlive:true
}
}
},
2、用v-if来显示router-view是否在keep-alive中出现
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
6.生命周期共有几个?分别在什么时候使用?
- 1.创建 beforeCreate() 在执行这个钩子的时候 只有一些实例本身的事件和生命周期函数 用户自定义不能使用 created() 最早开始使用 data和methods中数据的钩子
- 2.挂载 beforeMount() 指令已经解析完毕 内存中已经生成dom数 mounted()dom已经渲染完毕 页面和内存的数据已经同步
- 3.更新 beforeUpdate() 当data的数据发生改变会执行这个钩子 内存中数据是新的 页面是旧的 updated() 内存和页面都是新的
- 4.销毁 beforeDestroy()即将销毁 data和methods中的数据此时还是可以使用的,可以做一些释放内存的操作 destroyed()已经销毁完毕
- activated(组件激活时):和上面的beforeDestroy和destroyed用法差不多,但是如果我们需要一个实例,在销毁后再次出现的话,用 beforeDestroy和destroyed的话,就太浪费性能了。实例被激活时使用,用于重复激活一个实例的时候
- deactivated(组件未激活时):实例没有被激活时。
- errorCaptured(错误调用):当捕获一个来自后代组件的错误时被调用
7.路由守卫
路由钩子函数有三种分别为 全局守卫 单个路由守卫 组件内部守卫
- 全局守卫钩子 beforeEach
- 单个路由守卫 beforeEnter
-
组件内部守卫 beforeRouteEnter beforeRouteUpdate beforeRouteLeave
- to 对象 去哪儿 from 对象 从哪来 next 函数 next()==next(true) 继续执行 不写next==next(false)终止执行 next(path)跳转
8.vuex是什么
- state 存储数据 在组件中的使用 this.$store.state.属性名
- mutations 直接操作state中的数据 在组件中的使用 this.$store.commit("方法名",参数)
- actions 可以实现异步操作 在actions中操作mutations中的数据 在组件使用 this.$store.dispatch("方法名",参数)
- getters 类似于计算属性可以对state中数据进行逻辑计算 在组件中 this.$store.getters.方法名
- modules 将state分模块
9.闭包
函数嵌套函数 当内部函数访问外部函数变量时 就产生了闭包
内部函数可以直接访问外部函数的内部变量或参数
变量或参数不会被垃圾回收机制回收
10.原型和原型链
-
原型的概念
- javascript的所有对象都包含一个 proto 属性 这个属性对应的就是自身的原型 JavaScript的函数对象,
- 除了原型 proto 属性之外 还有 prototype 属性 当函数对象作为构造函数创建实例时,该 prototype 属性值将被作为实例对象原型 proto
- 原型链的概念
- 当一个对象调用自身不存在的属性或方法时,就会去自己 proto 关联的前辈 prototype 对象上去找
- 如果没找到就接着往上找 直到找到属性或方法 找不到就 返回 undefined 这就是原型链
11.作用域
-
js中首先有一个最外层的作用域,
全局作用域
; -
js中可以通过函数来创建一个独立作用域称为
函数作用域
,函数可以嵌套,所以作用域也可以嵌套; -
es6中新增了
块级作用域
(大括号,比如:if{},for(){},while(){}…) es6作用域,只适用于const,let ;
12.继承
-
Es5中的继承有:
-
原型继承:父类的实例作为子类的原型
-
构造函数继承:在子类中使用call方法调用父类的方法并将父类的this改成子类的this
不能继承原型属性/方法,只能继承父类的实例属性和方法
-
组合继承:既能调用父类的实例属性又能调用父类的原型属性
由于调用了两次父类,所以产生了两份实例
函数可以复用
- Es6有class继承
-
class就相当于Es5中的构造函数
-
class中定义方法是前后不能加function,全部都定义在class的prototype属性中
-
class中只能定义方法不能定义对象变量等
-
class默认是严格模式
-
在子类中调用extends方法可以调用父类的属性,用eat调用父类的方法
-
-
13.深拷贝浅拷贝
- 浅拷贝只复制指向某个对象的指针,不复制对象本身(引用),新旧对象还是共享同一块内存。
- 深拷贝会另外创造一个一模一样的对象(拷贝的是全部),新对象跟原对象不共享内存,修改新对象不会改到原对象。
14.let,const,var的区别
- 是否存在块作用域
- var 是不存在块作用域的,let和const有块作用域
- 是否有变量提升
- var有变量提升:
- 声明之前调用,就会把变量提升到最顶部。 let和const没有变量提升
- 是否允许重复声明
- var允许重复声明 let和const在同一个作用域内不予许重复声明
- 是否存在暂时性死区
- var没有暂时性死区 let和const存在暂时性死区:在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”,
- 是否可以修改声明的变量
- var和let可以修改 ,const不可以,因为const声明的变量是一个常量,一旦定义必须赋值且不可改变
15.解构赋值
- 解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象或数组中取出,赋值给其他变量。
16.箭头函数和普通函数的区别
为了解决普通函数this指向问题
-
是匿名函数,不能作为构造函数,不能使用new,
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式:一种只包含一个表达式,连{ … }和return都省略掉。还有一种可以包含多条语句,这时候就不能省略{ … }和return。
-
箭头函数内没有arguments,可以用展开运算符…解决,arguments是参数的集合, 是一个类数组/伪数组体现在他不能调用数组的方法
-
箭头函数的this,始终指向父级上下文(箭头函数的this取决于定义位置父级的上下文,跟使用位置没关系,普通函数this指向调用的那个对象)
-
箭头函数不能通过call() 、 apply() 、bind()方法直接修改它的this指向。(call、aaply、bind会默认忽略第一个参数,但是可以正常传参)
-
箭头函数没有原型属性
18.什么是promise
-
promise简单来说就是一个容器,里面存放一些异步操作的结果
-
也可以说他是一个对象,他可以获取异步操作的最终结果(成功或者失败)
-
他还是一个构造函数,他有对外统一的API,自身有all ,reject ,resolve等方法,他的原型上有then ,catch等方法。
-
他可以链式调用,(.then().then()。。。。。)
-
解决了地狱回调
-
应用场景:封装ajax,axios的get,post封装,微信小程序中封装wx.request(),uniapp开发中uni.request()
-
promise(首字母小写)对象指的是“Promise实例对象” ,Promise首字母大写且单数形式,表示“Promise构造函数” ,Promises首字母大写且复数形式,用于指代“Promises规范”
-
他的状态一旦改变就不可逆,只能从初始状态改成成功或者失败状态
-
all的方法是并行执行异步操作,等所有异步操作完成后才会执行回调
-
promise异步加载图片://函数直接调用,在.then中进行成功的操作,在.catch中进行失败的各种操作.
-
function loadImageAsync(url){ return new Promise((resolve,reject)=>{ let image=new Image(); image.onload=function(){ resolve(image); }; image.onerror=function(){ reject(new Error('Could not image at'+url)); } image.src=url; }) }
19.async和await
-
asyns 可以把普通的函数改成异步函数,调用都是一样的
-
异步的asyns函数返回的是一个promise对象
-
async配合await使用(阻塞式)是异步方法但它是一个阻塞的异步方法
他们的优点
-
方便联机调用,依次发生的场景
-
同步代码编写方式,从上到下执行
-
多个参数传递,跟promise不一样,可以当做普通变量来处理,也可以当做块级变量,想怎么用就怎么用,想定义几个变量就定义几个
-
同步代码和异步代码可以一起编写,不用纠结同步和异步的区别,把异步封装成一个promise对象放在await后面
-
是对promise的优化,
20.Vue 自定义组件及组件疯装
- 自定义组件分为三步
- 引用组件 注册组件 使用组件
- Vue组件封装(以封装一个button组件为例)
- 1/在components文件内创建一个button文件,文件内创建一个index.vue文件,在index.vue文件内写的是原型(包含组件的名字,应用的最底层的HTML标签,分别根据什么条件显示什么功能),同时该文件导出的数据为一个对象。
- 2/在button文件下建立一个index.js文件,文件内对新构建组件的名字进行注册。
- 3/ 与button文件同级建立一个index.js文件,对组件进行注册,同时也注册进install中,在导出时,不仅要引出全局的,而且单个的也要引出,便于局部或全局引用。
- 4/要在main.js中进行引用
- 5/到这里,组件便是封装完成了,在App.vue中可以进行使用了
21.Vue项目的开发流程
- 首先,拿到项目我们应该分析下项目的需求以及思路
- 其次还要有一个GIT远程仓库,给团队提供便携的开发
- 然后再看看项目里面的一个大体的开发功能以便做好准备
- 例如登录:
- 先必须要有一个表单,然后是按钮,绑定v-model
- 然后在mehods中定义事件,在mounted中调用接口,在data中定义数据
- 调用接口拿到数据,然后用状态码判断是否登录成功,成功则跳转到首页,同时存到localstorage中
- 接着在路由中通过token/localstorage设置路由守卫,达到登录鉴权的目的
22.输入url到页面加载完成发生了什么
-
DNS解析
-
TCP连接
-
发送HTTP请求
-
服务器响应请求并返回相应的数据
-
浏览器解析渲染页面
-
连接结束
原文:https://blog.csdn.net/qq_37430247/article/details/112002255
拓展:
三次握手,四次挥手 https://blog.csdn.net/qq_36903042/article/details/102656641 (终极奥秘)
23.HTTP 状态码
- 1 临时响应
- 2 成功
- 3 重定向
- 4 请求错误
- 5.服务器错误
23.vue项目打包
一、修改请求静态资源的路径
打开config下的index.js文件,修改assetsPublicPath的值,从‘/’改为‘./’。即从根路径改为相对路径。
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
}
二、修改本地图片的路径
打开build下的utils.js文件,增加 publicPath:’…/…/’
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath:'../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
三、在终端运行npm run build。
25.防抖和节流
防抖: 触发高频事件后 定时器内函数只会执行一次,如果定时器内高频事件再次被触发,则重新计算时间
场景:
按钮提交场景:防止多次提交按钮,只执行最后提交的一次。
节流 :高频事件触发,在定时器内只会执行一次,所以节流会稀释函数的执行效率。
1.拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动
2.缩放场景:监控浏览器 resize
3.动画场景:避免短时间内多次触发动画引起性能问题
26.数组去重
indexOf
function newArr(array){
//一个新的数组
var arrs = [];
//遍历当前数组
for(var i = 0; i < array.length; i++){
//如果临时数组里没有当前数组的当前值,则把当前值push到新数组里面
if (arrs.indexOf(array[i]) == -1){
arrs.push(array[i])
};
}
return arrs;
}
var arr = [1,1,2,5,5,6,8,9,8];
console.log(newArr(arr))
Set
function newArr(arr){
return Array.from(new Set(arr))
}
var arr = [1,1,2,9,6,9,6,3,1,4,5];
console.log(newArr(arr))
利用递归去重
24.Git指令
git init 初始化git仓库
git status 查看文件状态
git add 文件列表 追踪文件
git commit -m 提交信息 向仓库中提交代码
git log 查看提交记录
覆盖工作目录中的文件: git checkout --文件名
将文件从暂存区中删除: git r m --cached 文件名
git branch 查看分支
git branch 分支名称 创建分支
git checkout 分支名称 切换分支
git merge 来源分支 合并分支 (必须在master分支上才能合并d)
git branch -d 分支名称 删除分支(分支被合并后才允许删除)(-D 强制删除)
将本地仓库推送到远程仓库: git push 项目链接
Git 添加远程仓库origin (origin是仓库别名): git remote add 仓库名 项目链接
git push origin master
git push -u origin master
-u 将推送地址和分支保存,下次推送输入git push即可
25.什么是盒子模型?
在我们HTML页面中,每一个元素都可以被看作一个盒子,而这个盒子由:内容区(content)、填充区(padding)、边框区(border)、外边界区(margin)四部分组成。
26.什么是内存泄漏
程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存。
对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
27.原生Ajax的创建过程
1.创建xhr 核心对象
2.调用open 准备发送
3.如果是post请求,必须设置请求头。
4.调用send 发送请求 (如果不需要参数,就写null)
5.监听异步回调
备注:如果是post请求,想要传json格式数据。
28.事件冒泡
事件冒泡:事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。
事件捕获:事件捕获会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。
29.阻止事件冒泡
1.event.stopPropagation();
事件处理过程中,阻止了事件冒泡,但不会阻击默认行为
2.return false;
事件处理过程中,阻止了事件冒泡,也阻止了默认行为
还有一种有冒泡有关的:
3.event.preventDefault();
它的作用是:事件处理过程中,不阻击事件冒泡,但阻击默认行为
30.箭头函数与普通函数区别
箭头函数是匿名函数不能作为构造函数不能使用new
箭头函数不绑定arguments,需要用运算符解决…解决
箭头函数不绑定this,会捕获其所在的this值,作为自己的this值
箭头函数通过call()或apply()调用一个函数,只传入了一个参数,对this并没有影响.
箭头函数没有原型属性
31.跨域解决问题
-
jsonp
-
代理跨域
-
cors
-
html5 中的 window.postMessage
-
反向代理
-
哈希
32.单向数据流和双向绑定
1.Vue 在不同组件间强制使用单向数据流,父组件可以向子组件传递数据,但是子组件不能直接修改父组件的状态。
2.数据的双向绑定
主要由MVVM框架实现,主要由三部分组成View、ViewModel和Model组成,其中view和model不能直接进行通信,他们通过中间件ViewModel来进行通信。
33.图片懒加载
对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小。当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户。
所以,对于图片过多的页面,为了提高加载速度, 我们需要将页面内未出现在可视区域内的图片先不做加载, 等到访问到可视区域后再去加载。这样子对于页面加载性能会有很大的提升,也提高了用户体验。
34.nextTick的理解
使用nextTick的原因:Vue是异步修改DOM的,并且不鼓励开发者直接接触DOM,但是有时候需要必须对数据更改后的DOM元素做相应的处理,但是获取到的DOM数据并不是更改后的数据,这时候就需要this.$nextTick();
原理:Vue通过异步队列控制DOM更新和nextTick回调函数先后执行的方式。
35.判断数据类型的4种方法
instanceof
typeof
object.prototype.toString()
constructor构造函数
https://blog.csdn.net/qq_37430247/article/details/111504352
36.Vue 组件中 data 为什么必须是函数?
- 使每个组件闭包
- 容易互相影响
其实就是一个原因,实例化出来的根组件只有一个,你可以将它写成对象,或者是返回一个对象的函数。但是子组件不够健壮,容易在内存的地址中互相影响,就像我们常用的深浅拷贝所能解决的那样。所以为了防止意外的发生,是不被允许在子组件中使用对象来写data。
当data选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的。
37.mvc和mvvm的区别?(个人总结)
mvc:model模型 view视图 controller控制器
视图请求数据到控制器,控制器向模型获取数据后,模型返回数据到视图渲染
mvvm:model数据 view视图UI viewmodel控制器
两者不同的之处在于后者mvvm在处理返回数据时,不需要在将数据传到控制器到视图渲染,这个时候是自动的(双向数据绑定),一端更新,另一端自动更新
https://blog.csdn.net/qq_37430247/article/details/111830286
38.JS中判断数据类型的方法有几种?
最常见的判断方法:typeof
判断已知对象类型的方法: instanceof
根据对象的constructor判断: constructor
完美的解决方案:Object.prototype.toString.call()
无敌万能的方法:jquery.type()
39.深度监听
data:{
return(){
form:{id:1,name:marry}
}
},
watch:{
1.监听对象
form:{
handler(a,b){
//代码块
}
deep:true // 默认值是 false
,代表是否深度监听
immediate:true //代表在wacth里立即先去执行handler方法
},
2.监听对象中的一个属性(用字符串)
"form.name":{
handler(a,b){
//代码块
}
deep:true // 默认值是 false
,代表是否深度监听
immediate:true //代表在wacth里立即先去执行handler方法
}
}
https://blog.csdn.net/wandoumm/article/details/80259908
40.object.defineproperty()
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
object.defineproperty(obj,prop,descriptor)有三个参数:
object:必需。目标对象
propName:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性
https://blog.csdn.net/u011884290/article/details/51941605?
41、 sessionStorage localStorage cookie 的区别
1.localStorage 生命周期是永久,这意味着除非用户显示在浏览器提供的UI 上清除 localStorage 信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
2.sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除。存 放数据大小为一般为 5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。源生接口可以接受,亦可再次封装来对 Object 和 Array 有更好的支持。
作用域不同
不同浏览器无法共享 localStorage 或 sessionStorage 中的信息。相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享 sessionStorage 的信息。这里需要注意的是,页面及标
3.cookie 的优点:具有极高的扩展性和可用性
1.通过良好的编程,控制保存在 cookie 中的 session 对象的大小。
2.通过加密和安全传输技术,减少 cookie 被破解的可能性。
3.只有在 cookie 中存放不敏感的数据,即使被盗取也不会有很大的损失。
4.控制 cookie 的生命期,使之不会永远有效。这样的话偷盗者很可能拿到的就是一个过期的 cookie。
4.cookie 的缺点:
1.cookie 的长度和数量的限制。每个 domain 最多只能有 20 条 cookie,每个cookie 长度不能超过 4KB。否则会被截掉。
2.安全性问题。如果 cookie 被人拦掉了,那个人就可以获取到所有 session
信息。加密的话也不起什么作用。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务端保存一个计数器。若吧计数器保存在客户端,则起不到什么作用。 localStorage、sessionStorage、Cookie 共同点:都是保存在浏览器端,且同
源的。
42.原型链,继承和promise