点击id为inner元素后,控制台打印是?
<template>
<div>
<div @click="clickMe">
<div @click="clickMe" id="inner">点我</div>
</div>
</div>
</template>
<script>
export default {
name: "test",
methods:{
clickMe(){
console.log('start')
setTimeout(()=>{console.log('setTimeout1')},0)
this.$nextTick(()=>{
console.log('nextTick1')
this.$nextTick(()=>{console.log('nextTick2')})
setTimeout(()=>{console.log('setTimeout2')},0)
})
console.log('end')
}
}
}
</script>
微任务、宏任务
start end nextTick nextTick2
start end nextTick nextTick2
setTimeout setTimeout2 setTimeout setTimeout2
<div id="page" class="page" :class="{'changed':changed===true}">
<div>
<button @click="onclickchange" >点击我</button>
</div>
</div>
<script>
window.page = new Vue({
el:'#app',
data(){
return{
changed:false
}
},
mounted(){
this.el = document.getElementById('page')
this.el.className += 'page-show'
},
methods:{
onclickchange(){
console.log('1:',page.el.className)
this.changed = true
console.log('2:',page.el.className)
setTimeout(()=>{
console.log("3:",page.el.className)
},0)
}
}
})
</script>
1: page page-show
2: page page-show
3: page changed
实现下列代码:[1,2,3,4,5].duplicator();//[1,2,3,4,5,1,2,3,4,5]
let arr = [1.2,3,4,5]
Array.prototype.duplicator = function () {
let len = this.length
for(let i=0;i<len;i++){
this.push(this[i])
}
return this
}
console.log(arr.duplicator())
以下代码的结果是?
let fullname = 'John Doe'
let obj = {
fullname: 'Colin Ihrig',
prop:{
fullname: 'Anrelio De Rosa',
getFullName(){
return this.fullname
}
}
console.log(obj.prop.getFullName())
let test = obj.prop.getFullName;
console.log(test())
//Aurelio De Rosa
//John Doe
实现Function.prototype.bind方法, 使得以下程序最后能输出’success’
function Animal(name,color) {
this.name = name
this.color = color
}
Animal.prototype.say = function () {
return `I'm a ${this.color} ${this.name}`;
}
const Cat = Animal.call(null,'cat')
const cat = new Cat('white')
if(cat.say() === 'I\'m a white cat' && cat instanceof Cat && cat instanceof Animal){
console.log('success')
}
以下代码打印的结果
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
script start -> async1 start -> async2 -> promise1 -> script end -> async1 end -> promise2 -> setTimeout
深度克隆:
const deepClone = function(obj) {
// 先检测是不是数组和Object
// let isArr = Object.prototype.toString.call(obj) === '[object Array]';
let isArr = Array.isArray(obj);
let isJson = Object.prototype.toString.call(obj) === '[object Object]';
if (isArr) {
// 克隆数组
let newObj = [];
for (let i = 0; i < obj.length; i++) {
newObj[i] = deepClone(obj[i]);
}
return newObj;
} else if (isJson) {
// 克隆Object
let newObj = {};
for (let i in obj) {
newObj[i] = deepClone(obj[i]);
}
return newObj;
}
// 不是引用类型直接返回
return obj;
};
Object.prototype.deepClone = function() {
return deepClone(this);
};
Object.defineProperty(Object.prototype, 'deepClone', {enumerable: false});
vue3 六大亮点:
Performance:性能比vue2快1.2~2倍。
Tree shaking support:按需编译,体积比vue2更小
Composition API:组合API
BetterTypescript support:更好的TS支持
Custom Renderer API:暴露了自定义渲染API
Fragment,Teleport(portal),Suspense:更先进的组件。
vue3如何变快的?
diff算法优化:
Vue2中的虚拟算法dom是进行全量的对比。
vue3新增了静态标记(patchFlag);
与上一次虚拟节点进行对比时候,之对比带有patch flag的节点
并且可以通过falg的信息得知当前节点要对比的具体内容
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("span", null, "hello"),
_createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
Vue3.0 diff 在创建虚拟Dom的时候会根据Dom中内容会不会发生变化,添加静态标记。
hoistStatic 静态提升;
Vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染。
vue3中对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可
const _hoisted_1 = /*#__PURE__*/_createVNode("span", null, "hello", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
cacheHandlers 事件侦听器缓存;
默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化
但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可。
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", { onClick: _ctx.btnClick }, null, 8 /* PROPS */, ["onClick"])
]))
}
ssr渲染:
当有大量静态的内容时候,这些内容会被当作纯字符串推进一个buffer里面。
即使存在动态的绑定,会通过模版插入值嵌入进去。这样会比通过虚拟dom来渲染的快的多
当静态内容大到一定量级时候,会用_createStaticVNode方法在客户端去生成一个static node
这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。
vue-cli 4
Vite : 实现原理 利用ES6的import 会发送请求去加载文件的特性,拦截这些请求,做一些预编译,省去了webpack冗长的打包时间。
npm install -g create-vite-app
create-vite-app projectName
cd projectName
npm run dev
API:
createApp
setup()
reactive()
filter()
this.objArr = this.objArrs.filter((item,ind)=>item.name)
const obj1 = Object.assign({},obj)
const minN = (...arr, n = 0) => arr.sort((a, b) => a - b).slice(0, n)
Vue.createApp({
})