vuex action:
尤雨溪在知乎回答了,区分 actions 和 mutations 并不是为了解决竞态问题,vuex 真正限制你的只有 mutation 必须是同步的这一点,只是为了devtools追踪状态变化,或者说出于单一职责原则。https://www.zhihu.com/question/48759748/answer/112823337
vue事件绑定:
vue的事件绑定,直接绑定给当前元素,打印$event中的target和currentTarget会发现两个是同一个元素,而且是原生事件,用的是addEventListener。methods里面的this指向当前实例,内部用了bind方法,再去绑定this不生效。
vue.use():
vue.ues方法会执行这个插件的instll方法,默认传入vue,这样主要是为了可以让这个插件使用项目使用的vue,而不是自己引入导致vue版本不一致,导致出现一些无法预估的错误。
父子组件生命周期:
父组件执行到beforeMount之后,子组件先执行直到mounted,之后父组件才执行mounted。销毁父组件beforeDestroy,之后子组件销毁父组件才执行destroyed。
路由:
router-link、router-view这两个组件其实就是用Vue.component注册的全局组件。且内部用mixin让每个子组件都获取router实例。
数组函数劫持:
Vue重写了数组的七个会改变原数组的方法,用函数劫持的方法实现的,类似下面:
let oldArrayMethods = Array.prototype;
let arrayMethods = Object.create(Array.prototype);
let arrayPatch = ['push', 'pop', 'unshift', 'shift', 'splice', 'sort', 'reverse'];
arrayPatch.forEach(method => {
arrayMethods[method] = function (...args) {
console.log('调用了' + method);
return oldArrayMethods[method].apply(this, args);
}
})
Array.prototype = arrayMethods;
let arr = [1, 2, 3];
arr.push(4)
console.log(arr);
Vue的nextTick:
Vue 提供的nextTick能保证是在DOM渲染之后执行,主要是内部在调用这个之前会在试图渲染方法执行之后调用,内部会通过判断兼容使用微任务还是宏任务,所以要注意不能把这个nextTick跟微任务process.nextTick混淆。
请求放在生命周期哪个合适:
很多请求会放在created里面,这时候操作dom会失败,因为请求是异步的,一般也不会出现问题,但是建议统一放mounted,主要是这时候dom也就渲染了。而服务的渲染不支持mounted方法,统一放created中。
v-html:
v-html会造成XSS攻击,使用的时候必须确保内容是可信的,而且v-html会造成内部的子元素都被替换掉。
vue是渐进式框架:
你可以只用做模板引擎,或者加上vue提供的路由,或者加上全局状态管理vuex,或者直接使用vue-cli直接搭建项目。你可以在现有程序使用vue,也可以用vue搭建工程。
vue核心是响应式:
通过对data数据变更实现页面更新。
vue的mvvm理解:
view视图层,viewModel是vue的实例,也就是vm(new Vue),model数据,也就是vue里面的data。
vue响应式原理:
vue通过发布订阅和数据劫持的方法对数据进行监听,会给每个默认属性进行监听,深层次的也会递归进行监听,会对改变原数组的数组方法进行函数劫持。因为要对数据进行递归监听,这也是vue性能的一个痛点。到了vue3用proxy进行重写,不需要递归监听,但是proxy兼容性不好。
vue数据不更新到页面:
之前分享过vue数据不更新渲染,其实是错的,vue只能监听默认的属性,数组的索引发生变化或者改变数组长度也不会触发更新。比如你在data定义一个obj: {},然后在其它地方给obj定义一个属性,或者你定义一个数组arr,,然后直接arr[0]赋值,这些都不会进行监听,但是数据是变化的。有可能通过这两个方法页面发生变化了,那是因为有其它监听的数据发生变化,页面重新渲染,会顺带帮你把数据渲染到页面。使用$set可以监听或者$ForceUpdate会强制渲染。
vue中render、template、el:
vue中如果render、template、el都存在的情况下,render优先级最高,接着是template,最后是el:
var vm = new Vue({
render: function(h){
return h('div', {}, '这是render属性方式渲染。')
},
template: '<div>这是template属性模板渲染。</div>',
el: '#app',
});
vue中提供的template:
vue提供的template是无意义的,具有隐藏性、无效性、任意性,如果你用v-if的时候,使用template包裹,渲染的时候template会不存在。v-show不能用在template上。循环的key也不能放在template上。
v-if、v-show、v-for:
v-if是控制dom是否存在,v-show是控制样式display,v-if会重新渲染元素或者组件,并且重新执行涉及的函数。v-for的优先级高于v-if,性能会差一些,所以尽量不要一起使用。
v-model其实是语法糖:
v-model其实是:value和@input方法的语法糖,下面两个等价:
<input type="text" :value="msg" @input="(e) => msg = e.target.value">
<input v-model="msg">
vue组件核心:
组件的优点很多,重用、易维护、解耦等,vue中组件还有一个核心的优点,就是组件级更新,因为每个组件都有自己一个watcher,数据更新了只是重新渲染自己组件,而不会是整个页面。
.vue文件
.vue的script中的export default出去的对象,相当于Vue.extends({})里面的这个对象。import .vue文件,获取的是一个对象,可以打印看看,里面有render函数等。
$bus:
给vue挂一个new Vue,因为每个vue实例都有$on、$emit、$off的事件,用来任意组件监听、通信,但是无法控制监听命名重复,不适合大规模使用,而且必须先监听再发布:
Vue.prototype.$bus = new Vue();
this.$once('hook:beforeDestroy', function () { picker.destroy() }); Vue3.0确实是新增了hook,有点靠近了react,但是这个是很早之前就出的,很奇怪,为什么没多少有介绍到。最简单的使用场景就是监听滚动或者计时器在组件销毁的时候清除,这段代码相当于在组件销毁的时候执行picker.destroy(),在vue官网/教程/深入了解组件/处理边界情况/程序化的事件监听器可以看看API。
@hook:
说实在的,这个语法我中文文档和英文文档都查了很久,没发现API有这个语法,但是确实是能实现,就是监听外部组件的生命周期
当子组件执行mounted的时候,父组件就会执行childrenMounted方法,这在一定场景应该是有用的。
.sync修饰符:
之前就说过v-model是一个双向绑定的语法糖,vue还提供了.sync这个修饰符对一个props进行双向绑定,其实就是v-bind和v-on的语法糖,某些场景比使用props传递更理想。
Component动态组件:
前几天才觉得react可以把组件当作参数传递非常神奇,想想之前在做页面内tab切换的时候,一堆的v-if去判断,其实直接使用内置的动态组件更省事,以前知道这个,但是居然没有在项目中使用:
Object.freeze():
Vue会递归监听data里面所有的对象,这是性能痛点之一,而这个方法,可以冻结一个对象,如果在vue里面声明的数据只是第一次渲染使用,可以直接冻结,不进行监听,如果你想重新进行监听可以直接赋值也是可以的,这方法也可以作为一个长列表性能优化使用:
data里面定义:
obj1: Object.freeze({a:1}),
obj2: {b: 2}
mounted(){
console.log(this.obj1)
console.log(this.obj2)
}
输出:
HTTP协议通信最耗费时间的是建立TCP连接的过程,那我们就可以使用HTTP Keep-Alive。但是,keep-alive长时间的TCP连接容易导致系统资源无效占用。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以正确地设置keep-alive timeout时间非常重要。浏览器对于TCP的keep-alive有连接限制4-6个。
减少HTTP请求次数将多个文件压缩打包成一个,当然也不能都放在一个文件中,因为这样传输起来可能会很慢,权衡取一个中间值。配置使用懒加载,对于一些用户不立刻使用到的文件到特定的事件触发再请求,服务器资源的部署尽量使用同源策略。服务端最好开启gzip。
JSX 语法:
HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,允许 HTML 与 JavaScript 的混写HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。原谅我之前并不能解释jsx语法。