Vue的知识梳理总结及面试可能

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ## Vue的数据驱动原理?数据更新原理?响应式原理?
  1. 数据通过object.defineProperty进行getset拦截。
  2. 通知watcher(观察者模式)订阅发布模式,触发组件重新渲染,创建新的虚拟DOM,对比旧的虚拟DOM,通过diff找出不同,以最小代价更新节点。

什么是Vue?

  1. 核心代表人物 尤雨溪
  2. Vue是饿了么ued团队开发并维护的一个渐进式框架,核心关注视图层
  3. vue的核心是一个允许采用简洁的模板声明式的将数据渲染进DOM系统
  4. m与v没有任何联系,VM=>双向数据绑定

为什么vue中m层改变了,viewmodel知道m层变化,或双向数据绑定的原理?

  1. vue在创建视图时,会将数据配置到vue实例中,然后内部通过object.defineProperty方法,为数据动态添加get和set方法,当获取数据时会触发get方法,当设置对象时会触发set方法;当set方法触发 完成时,进一步watcher触发,数据改变完成了,试图也进行了重新渲染。

数组的更新检测

  1. vue将被侦听的数组的变更方法进行了包裹,所以他们将会触发视图更新
  2. push() 在数组后面添加元素,返回数组的长度
  3. pop() 在数组后面删除一个元素,返回删除的数据
  4. shift() 在数组前面删除一个元素,返回删除的数据
  5. UNshift()
  6. splice() 数组的剪贴,删除,插入
  7. sort() 数组的排序
  8. reserve() 数组的反转
    不会触发视图更新的有:concat() slice()

事件修饰符

  1. stop 阻止事件冒泡
  2. prevent 取消事件默认行为
  3. self 只有在自身上面触发
  4. once 触发一次

v-model 底层实现原理

  1. 内部给输入框绑定value属性,和监听input属性
    修饰符:
    lazy 等光标离开后进行更新操作
    number 若能被parsefloat解析则输出结果否则原样输出
    trim 去掉前后空格

计算属性 及watcher与computed区别

  1. 计算属性会根据现有元素生成一个新的数据,并且两者产生永久性关联,建立缓存关系,当无关数据变动时,计算属性不会重新计算,而直接从缓存取值即可
  2. 区别: watch监听只能是单个的监听,每次监听只能一个变量的修改,计算属性可以依赖多个数据的变化。2.当需要数据变化时执行异步操作或开销较大时用watch

什么是虚拟DOM?

  1. 虚拟DOM就是虚拟对象,属于虚拟数据,真实DOM的一种映射
  2. 内存中生成一棵虚拟DOM
  3. 将内存中的虚拟DOM树初始化渲染成一颗真实DOM树
  4. 当我们修改vue实例中data数据时
  5. 之前的虚拟DOM结合更改后的数据生成一颗新的虚拟DOM
  6. 将此次生成的虚拟DOM与上一次虚拟DOM对比(diff算法)
  7. 将对比后差异的部分进行重新真实的DOM渲染

浏览器加载一个HTML文件的大致流程

  1. 构建DOM树
  2. 构建style rules ,页面样式表
  3. 将DOM树和样式表结合形成render tree(渲染树)
  4. 布局 为每个render 树上的节点确定在显示屏上的精准坐标信息
  5. 绘制 触发每个节点的paint方法

为什么组件的data必须是函数?

因为每个实例可以维护一份被返回对象的独立拷贝

slot插槽

vue提供了一种将父组件内容和子组件的模板整合的方法,内容分发,通过slot插槽实现.
分为具名插槽和匿名插槽

ref

在关系链中可以用this.$children[X].xxx=" ” 改变子组件的xxx数据
用ref链实现修改

<son ref="a"/>// 在父组件的触发方法中写this.$refs.a.msg= " "

event bus事件总线

1.需要创建一个公共的vue实例对象 let bus = new Vue()
2.弟弟组件准备一个方法,如

hit(){
	this.isShow=true;//用于一个标签显示隐藏
}

3.弟组件

mounted(){
	bus.$on("hit",this.hit)//绑定一个事件,等待一个机会执行
}

4.哥组件触发的方法

bus.$emit("hit")

v-once

只渲染元素和组件一次,随后的重新渲染,元素/组件及其子节点将被视为静态资源跳过,这属于优化更新性能。

animation动画

<transition name="abc"></transition>
//name属性写后改为abc-的样式名,默认v-

.abc-enter-alive

  • .abc-enter 刚开始的样式
  • .abc-enter-to 进入过程结束的时候

.abc-leave-active

  • .abc-leave 离开动画开始时
  • .abc-leave-to

多元素同时增加动画

 <transition-group></transition-group>
 //子元素要加key属性

多元素的过渡模式

  • in-out 新元素先进行过渡,完成后当前元素在过度离开
  • out-in 当前元素先过渡离开完成后新元素再过渡离开
    在transition用model属性调用

多个元素过渡
transition里只能是一个元素,但增加v-if/v-else
当相同标签名切换时,由于虚拟DOM机制,会直接让动画消失,所以给transition组件中多个设置key是一个更好地实践

生命周期

vue生命周期分三个阶段
初始化:beforeCreate/created/beforeMount/mounted
运行中:beforeUpdate updated
销毁:beforeDestroy destroyed

  1. 一个组件或者实例的生命周期都是从new开始
  2. 初始化事件与生命周期的相关配置
beforeCreate(){
	//不能拿到this
}
  1. beforeCreate是初始化阶段触发执行的,数据获取不到真实DOM也拿不到。
  2. created
created(){
	//此钩子函数数据已加载完毕,但DOM未生成。   
	// 通常在这里面初始化一些事件与ajax请求
}
  1. 组件或模板查找对应的模板结构,将其渲染成虚拟DOM
  2. beforeMount()表示真实DOM节点马上要渲染出来了,单页面未生成
  3. 编译好虚拟DOM后,在render函数中将虚拟DOM初始化渲染成为真实DOM
  4. mounted()初始化最后一个钩子函数,一般在此做一些实例化操作 如拖拽
  5. 当真实DOM挂载结束后,再去操作数据,才会触发这个钩子函数,beforeUpdate()
  6. .updated()数据改变了,内部生成新的虚拟DOM,然后diff算法,重新渲染真实DOM树
  7. beforeDestroy()组件销毁前执行,在此写一些善后东西,如在created()写个定时器,在beforeDestroy中销毁
  8. destroyed()组件已销毁

keep-alive

当动态组件被keep-alive包裹时,created只会执行一次,并且组件一直缓存在内存中,没有销毁,
问题:
例如我们在created中绑定一个定时器时,会造成定时器无法关闭。
解决:
动态组件给我们提供了activated和deactivated钩子函数
默认缓存所有组件
可以用include="组件名,组件名"指明有条件缓存
可以使用正则 :include=“/a|b/”
可以使用数组 :include=“[‘a’,‘b’]”
exclude是除了谁都缓存

自定义指令

目的:操作底层DOM元素,例如让初始化时输入框获取焦点

//全局的
<input v-focus/>
Vue.directive("focus",{
	//当被绑定的元素插入父节点时,会触发inserted
	inserted(el){
		el.focus()
	}
})
//局部的
new Vue({
	el:"#box",
	directives:{
		focus:{
			inserted(el){
				el.focus()
			}
		}
	}
})

自定义指令钩子函数

页面加载时:bind inserted
更新组件: update componentUpdate
卸载组件: unbind
重新加载组件: bind inserted
bind:指令第一次绑定到元素时调用;
inserted:被绑定元素插入父节点时调用
update:所在组件的vnode更新时调用,但可能发生在其子vnode更新之前
componentUpdated:指令所在组件的vnode及其子vnode全部更新后调用
unbind: 指令与元素解绑是调用

自定义指令钩子函数的参数

el:指令绑定的元素,可以用来直接操作DOM
binding:一个对象,包含以下property。

  1. name:指令名,不包括v-前缀
  2. value:指令的绑定值,例 v-my-directive=“1+1”绑定值为2
  3. oldValue:指令绑定的前一个值,仅在update和componentUpdate可用,且无论值是否改变
  4. expression:字符串形式的表达式
<p v-color="'color'"></p>
//必须加' ' 否则变量应放在data里声明
Vue.directive("color",{
	bind(el,binding){
		el.style.background=binding.value
	}
})

//有时候,可能在bind和update里触发相同行为可简写
Vue.directive("color",function(el,binding){
	el.style.background=binding.value
})

为什么要用脚手架?

用JavaScript驱动时,有以下缺点:

  1. 全局定义,强制要求每个component命名不得重复
  2. 字符串模板:缺乏语法高亮,在HTML多行时,需要用到/
  3. 不支持CSS
  4. 没有构建步骤,限制只能使用HTML和ES5JAVAScript不能使用预处理器。

以vue-loader的装载器解析以.vue后缀名的文件
以 vue create . 安装vue全部脚手架

如何关闭eslint

//创建vue.config.js文件
module . exports={
	devserve:{
		overlay:{
			warnings:false,
			errors:false
		}
	},
	lintOnSave:false
	//关闭eslint检查
}

//关闭某个eslint
找到.eslintrc.js文件中rules
   error的最后一个单词 ' ' 引起来放到rules里,
   然后    :'off'

scoped

在style中scoped属性指明仅当前组件可用
原理:会给标签添加额外的属性,内部会根据属性选择器来添加样式。
另:style中lang属性可以具体的CSS预处理语言(sass/less)
scoped的穿透问题
设置scoped的目的是为了限制样式只能影响当前的组件
若希望也可以影响到子组件或第三方组件时,需要使用scoped穿透。

div /deep/ p{

}

应用:组件里引用第三方插件时,后续想要在这个组件中修改第三方插件的样式,只能通过/deep/.abc实现scoped穿透修改。

父子通信

//父组件
import Son from "子组件路径"
//或  const Son = require("子组件路径")
1.引入Son组件
2.声明组件并注册
export default{
	components:{
		One
	}
}
3.传数据  :msg="父组件data的要穿的数据"
//子组件
export default{
	props:["msg"]
}

子父通信

//父组件
1.定义空数据
2.定义改变数据的方法
methods:{
	changeData(data){
		this.adata= data
	}
}
<Son @change="changeData"/>
//子组件
created(){
	this.$emit("change",参数)
}
//初始化时触发父组件方法

axios

//通过axios请求本地资源
1.引入axios  
import axios from "axios"
2.export default{
	axios.get("/data.json").then(res=>{
		console.log(res)
	})
}
//注:data.json必须放在public文件里
//访问时须 /  根目录获取

请求在线资源

//请求在线资源要考虑跨域问题
//在控制台response Headers下Access-Control-Allow-Origin代表后台是否写跨域。
//卖座后台解决了跨域问题但在requl.Header下有个请求头 X-Client-Info和X-Host
//请求时需携带请求头
//get("  ",{
//	headers:{
//		' ':'  ',
//		' ':' '
//}
//})
前端写跨域时用proxy 代理服务器
在vue.config.js下的devserve
proxy:{
	'/api':{
		target:'http://m.maizuo.com',
		changeOrigin:true,
		pathRewrite:{
			'^/api':''
		}
	}
}

手机端自适应

网页不是直接放入浏览器中的,而是先放在viewport中,然后viewport再等比例缩放到浏览器宽度,放入浏览器,viewport在缩放过程中,内容也缩小了。
< meta name="viewport" content="width=device-width
	,initial-scale=1.0,maximum-scale=1.0,
	user-scalable=no">
//width=device-width宽度等于当前设备宽度
//initial-scale=1.0初始的缩放比
//maximum-scale=1.0允许用户缩放的最大比例
//minimum-scale=1.0允许用户缩放的最小比例
//user-scalable用户是否可以手动缩放

rem 指相对于根元素的字体大小的单位
VW 设备宽度的1%
布局
xs 超小屏幕 sm 小屏幕 md中等屏幕lg大屏幕

设备像素比

dpr = 设备像素比 / CSS像素比
iPhone6 750px dpr=2
css=750 / 2 =375
100vw=375px
100px=26.67vw
iphone5 640px dpr = 2
100px = 31.25vw
1080px dpr=3
100px = 27.78vm

路由

传统多页MPA应用,底部通过a标签实现页面的跳转,但网速卡顿时会产生打开速度慢,并且伴随留白问题,用户体验较差。
引入spa single page application 单页面应用
原理:根据rul地址栏变化,来实现对应路由的组件的切换,整个网页没有刷新。只是组件间的卸载与装载,只有一个页面。
安装插件 yarn add vue-router
通过全局方法 Vue.use()使用插件,他需要在new Vue()启动前应用。
Vue.use()背后原理
通过调用插件里的install
vue-router提供了router-view,用来显示路由视图组件

<router-view></router-view>

一级路由

import Films from '@/views/Films'
//@指向SRC目录
routes =[
	{
		path:'/film',
		component:Films
	}
]

二级路由

import Films from '@/views/Films'
//@指向SRC目录
//引入二级路由
import ComingSoon ....,,
routes =[
	{
		path:'/film',
		component:Films,
		children:[
			{
				path:'/film/comingsoon'
				component:ComingSoon
			}
		]
	}
]

具名路由

//在上面路由配置中加
name : 'cn',
<router-link :to="{name:'cn'}"></router-link>

声明式导航跳转

router-link标签tag = “li” 指明渲染转化的页面标签
to = "/films"跳转地址
active-class="active"带的class名
replace 阻止浏览器返回按键(不留下浏览记录)

编程式导航

<p @click="toMine">点击进入我的页面</p>
export default{
	methods:{
		toMine(){
			this.$router.push("/film")
		}
	}
}<router-link :to="{path:'/film'}">进入我的</router-link>

动态路由

//有时需要我们在路由跳转时带上参数
:to="{path:'/film/100'}"
在配置路由时
{
	path:"/person/:id"
	props:true
}
接收:
props:["id"]this.$route.params.id



:to = "{path:'/film/100?title=我是二号'}"
this.$route.query.title接收

路由懒加载

即需要的时候加载,随用随载
为什么需要懒加载?
向vue等这种单页面应用,若未用懒加载,运用webpack打包后的文件会异常大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间白屏,应用懒加载会分担首页所承担的加载压力,减少首页加载用时。

Es6写法
component:() => import('路径')
ES5写法
component:resolve => require(['路径'],resolve)


//命名webpack包的方法
component:()=>import(/*webpack(hunkName:'film')*/'路径')
 

路由模式

vue中model模式
hash模式原理:调用window.onhashchange方法hash值切换
history模式原理:本质使用H5的history.pushstate方法更改URL

hash与history的区别?

  1. hash带#号,history比较优雅
  2. hash兼容IE8以下,history兼容IE10以上
  3. history模式需要后端配合将所有访问指向index.html,否则用户刷新新页面可能会导致404错误

路由守卫

当路由跳转前或跳转后,进入,离开某个路由,需要做某些操作,就可以使用某些钩子来监听。

全局路由守卫
beforeEach | afterEach
前置路由beforeEach()路由跳转前执行

router.beforeEach((to,from,next)=>{
	if(from.path === '/person'){
		console.log("从哪里来")
	}
	next();
	//代表放行    (必须写)
})
//to:  将要进入的路由对象,
// from:当前导航即将离开的路由

后置路由 跳转之后

router.after((to,from)=>{
	if(to.path==='/person'){
		console.log("进入person")
	}
	
})

局部路由 写在路由配置里,放在person路由路径下

beforeEnter(to,from,next){
	console.log("进入用户前打印")
	next()
}

路由组件钩子
写在person.vue的export default里
beforeRouteEnter(to,from,next){

}
渲染组件的对应路由被confirm前调用,不能获取组件实例this,因为在路由守卫前执行组件未被创建

未完待续,将在本篇文章末尾处持续更新

你可能感兴趣的:(面试,vue.js)