Vue中,key值的作用和原理
作用
key的作用是为了在diff算法执行时更快的找到对应的节点,提高diff速度
key具有唯一性
原理
其原理是vue 在patch中的patchVode下的updateChildren会处理新老子节点可以通过key精准判断俩个节点是否是同一个,如果没有加key就会强应的更新,从而会有频繁的更新过程,性能会很差,加了key还会可以使整个patch 过程更加高效,减少dom 操作,提高性能
V-model底层原理
绑定了value属性与监听了input事件,一旦数据改变了,input事件执行了。
V-model的修饰符
lazy
默认同步更新,加了之后等光标离开之后才会更新
number
如果这个值无法被parseFloat解析,会原样返回,如果可以被解析,会返回解析后的值
trim
掉前后空格
双向数据绑定的原理
在Vue中创建vm实例,通过Object.defineProperty方法为数据动态添加setter.getter方法,在setter方法完成后触发watcher方法,从而数据改变了,视图更新
computed,watch,method区别
computed
可以依赖多个属性的变化,是自执行的,依赖缓存进行,每次只有相关依赖发生变化才会请求值,只有getter属性,不接受传参,必须有return
watch
只能监听一个变量的改变,当需要异步请求或者开销较大的时候使用watch方法,只有setter属性,接受传参,没有return
method
computed中的方法都可以通过method实现,每次调用都需要请求,setter、getter都有
为什么data必须是一个函数
当我们的data是一个函数的时候,每一个实例的data属性都是独立的,组件内数据不会相互影响
正向代理 反向代理
所谓正向代理就是顺着请求的方向进行的代理,即代理服务器他是由你配置为你服务,去请求目标服务器地址。
所谓反向代理正好与正向代理相反,代理服务器是为目标服务器服务的,虽然整体的请求返回路线都是一样的都是Client到Proxy到Server。
单页应用的原理
原理就是通过检测地址栏变化后将对应的路由组件进行切换(卸载和安装)
hash与history的区别
hash模式较丑,history模式较优雅
hash兼容IE8以上,history兼容IE10以上
history模式需要后端配合将所有访问都指向index.html,否则用户刷新页面,会导致404错误
路由守卫
全局路由守卫
router.beforeEach 全局前置守卫 进入路由之前
router.beforeResolve 全局解析守卫在beforeRouteEnter调用之后调用
router.afterEach 全局后置钩子 进入路由之后
独享守卫
beforeRouteEnter 进入路由前
beforeRouteUpdate路由复用同一个组件时
beforeRouteLeave 离开当前路由时
Vuex
解决多组件之间数据共享的问题,将组件与组件之间的关系进行了解耦,强调集中式管理,变成了组件与仓库之间的关系了
Vuex和本地储存的区别
Vuex
储存在内存中,主要用于组件之间传值,刷新页面的时候vuex中储存的值消失
localstorage
以文件的形式储存在本地,只能储存字符串类型,用于页面之间传值,一直存在
sessionStorage
临时保存,只能储存字符串类型,用于页面之间传值,关闭页面就清除掉了
P.S.
在数据不改变的时候,localstorage可以代替vuex,但是如果两个组件共用一个数据时,如果其中一个组件改变了数据,希望另一个组件响应该发生变化的时,localstorage、sessionstorage
Vuex五个核心属性
State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
Module:可以将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
Vuex的项目结构
Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:
1.应用层级的状态应该集中到单个 store 对象中。
2.提交mutation是更改状态的唯一方法,并且这个过程是同步的。
3.异步逻辑都应该封装到action里面。
Vuex持久化
vuex有一个痛点,就是刷新以后vuex里面存储的state就会被浏览器释放掉,因为state都是存储在内存中的。
通过 vuex-persistedstate这个插件,来实现将数据存储到本地
Axios的高级功能
拦截器的封装
//引入axios和 qs
import axios from "axios";
import qs from "qs";
/****** 创建axios实例 ******/
const serve = axios.create({
baseURL: process.env.BASE_URL, // api的基本url,也可以直接写定好的url
timeout: 5000 // 请求超时时间
});
serve.interceptors.request.use(config => {
config.method === 'post'
? config.data = qs.stringify({...config.data})
: config.params = {...config.params};
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
return config;
}, error => { //请求错误处理
Promise.reject(error)
}
);
用axios拦截器
请求之前的拦截 : 一般可以在发送请求给后端的时候,携带一些数据给他们
响应之后的拦截 : 可以根据响应后的不同的状态码进行判断分析,给前端返回不同的符合条件的数据
什么时候使用拦截器
一般在登录功能的时候,通过vue-router提供的路由守卫拦截,token失效了(axios的拦截器进行了)
null和undefined的区别?
type数据类型不同
null
没有对象,即此处不该有值
undefined
缺少值,此处应该有一个值,还没有定义
自定义指令
作用
操作真实DOM元素
如何定义自定义指令
全局Vue.directive() 局部directives
自定义指令钩子函数
bind
inserted
update
componentUpdated
unbind
JS事件中的冒泡事件什么意思
事件到达事件目标之后不会结束,会逐级向上层冒泡,直到document对象
阻止事件冒泡
e.stopPropagation()
e.cancelBubble = true
实例
搜索框,点击出现下拉菜单,光标依旧存在输入框
什么是回调函数
将B函数作为参数传入到A函数中,在执行A的时候执行B,那就叫做B函数为回调函数,如果没有函数名称就叫做匿名函数
应用
Vue在Created异步请求数据
Vue组件中父子组件之间如何互相传值的
通过属性传递的方法传递数据
父组件声明一条数据,写一个更改自身的方法,将更改自身的方法通过属性传递的方式传给子组件
子组件用props接受父组件传递的属性,调用父组件传递的方法
子父通信
通过事件传递的方法传递数据
父组件绑定一个自定义方法,子组件通过this.$emit触发自定义方法
兄弟通信
通过公共实例传值
on绑定一个等待触发的自定义事件
隔代传递
通过绑定ref链
ref.$children[0].
怎么将Vue项目中的所有异常信息发到后台
利用vue自带的拦截器
Vue.config.errorHandler = function (err, vm, info) {
// 参数解析:
// 1.err:错误对象;
// 2.vm:Vue实例;
// 3.info:Vue 特定的错误信息,比如错误所在的生命周期钩子
// 错误被捕获后,不会再在控制台输出错误信息,可以补输出:
console.error(err)
// 然后完成错误上报,一般是发送到一个收集错误的 API 接口
// 如有必要,你还可以把 navigator 对象(客户端信息)一起上报
}
浏览器兼容问题
透明度
opcatity=0.5
filter:alpha(opacity=50)
列表缩进问题
消除ul、ol等列表的缩进时,样式应写成:list-style:none;margin:0px;padding:0px;
经验证,在IE中,设置margin:0px可以去除列表的上下左右缩进、空白以及列表编号或圆点,设置padding对样式没有影响;在 Firefox 中,设置margin:0px仅仅可以去除上下的空白,设置padding:0px后仅仅可以去掉左右缩进,还必须设置list- style:none才能去除列表编号或圆点。也就是说,在IE中仅仅设置margin:0px即可达到最终效果,而在Firefox中必须同时设置margin:0px、 padding:0px以及list-style:none三项才能达到最终效果。
图片间隙
IE6下图片会有间隙,改变html的排版,或者设置img为display:block或者设置vertical-align属性为vertical-align:top/bottom/middle/text-bottom都可以解决.
es6新增数组语法
from
把一些集合,或者长的像数组的伪数组转换成真的数组
of
把参数合并成一个数组返回
fill
//数组中的每一个元素替换成指定值
let arr = [1, 2, 3, 4] arr.fill(5) //arr全变成了5
//指定范围替换
arr.fill(6, 1, 3) //arr=[1,6,6,4]
entries/keys/values
let arr=['a', 'b', 'c'] for(let key of arr.keys()){} //取键
for(let value of arr.values()){} //取值
for(let [key, value] of arr.entries()){} //都取
includes
var a = function(){}
[1, 2, 3, 4, a].includes(a) //true
JS 垃圾回收机制的原理
内存泄漏:
不再用到的内存,没有及时释放,就叫做内存泄漏。
解决内存的泄露,垃圾回收机制会定期找出那些不再用到的内存(变量),然后释放其内存。
现在各大浏览器通常采用的垃圾回收机制有两种方法:标记清除,引用计数。
标记清除:
js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在一个函数中声明一个变量,就将这个变量标记为"进入环境",从逻辑上讲,永远不能释放进入环境变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为"离开环境"。
function test(){
var a = 10; //被标记"进入环境"
var b = "hello";} //被标记"进入环境"
test(); //执行完毕后之后,a和b又被标记"离开环境",被回收
引用计数:
言引擎有一张"引用表",保存了内存里面所有资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。
//如果一个值不再需要了,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏。
const arr = [1,2,3,4];
console.log("hello world")
//上面的代码中,数组[1,2,3,4]是一个值,会占用内存。变量arr是仅有的对这个值的引用,因此引用次数为1尽管后面的代码没有用到arr,它是会持续占用内存。
//如果增加一行代码,解除arr对[1,2,3,4]引用,这块内存就可以被垃圾回收机制释放了。
let arr = [1,2,3,4];
console.log("hello world");
arr = null;
//上面代码中,arr重置为null,就解除了对[1,2,3,4]的引用,引用次数变成了0,内存就可以释放出来了。
//因此,并不是说有了垃圾回收机制,程序员就轻松了。你还是需要关注内存占用:那些很占空间的值,一旦不再用到,你必须检查是否还存在对它们的引用。如果是的话,就必须手动解除引用
filter()、forEach()、map()、reduce()、reduceRight()的区别
every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true ,则返回 true。
some():对数组中的每一项运行给定函数,如果该函数对任一项返回 true ,则返回 true
filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。