📑博客主页:@丘比特惩罚陆
💖欢迎关注:点赞收藏⭐留言✒
💬系列专栏:web前端、嵌入式、笔记专栏
🎮 加入社区: 丘比特惩罚陆
🥇人生格言:选对方向,每走一步都是进步!
✒️欢迎大佬指正,一起学习!一起加油!👏 希望大家能小手一动,帮忙点个赞!
😁资源邮箱:2237814512@qq.com
目录
1.第一题:Vue监控属性警告问题
子组件为什么不可以修改父组件传递的Prop,如果修改了,Vue是如何监控到属性的修改并给出相应的警告呢?
<template>
<div>
info: {{ info }}
<input :value=""info.name" Qinput="handleChange"/</div>
</template>
<script>
import proxy from "./proxy";
export default {
props:{
info: object),
created({
this.temp = ( name:"";
Object. keys(this.temp).forEach(key >{proxyfthis.info,this.temp,key););
),
methods: {
handleChange(e) {
//this.info.name = e.target.value;
//this.SforceUpdateO);
this.$emit("change", e.target.value);)
}}};
</script>
proxy.js
const sharedPropertyDefinition = {
enumerable: true,
configurable: true
};
export default function proxy(target,temp,key) {
sharedPropertyDefinition.get = function proxyGetter() {
return temp[key];
};
sharedPropertyDefinition.set = function proxySetter(val){
temp[key) = val;
if (!window.isUpdatingChildComponent) {
console.error('不可以直接更改:$ikey'} ;
window.isUpdatingChildComponent= false;;
Object.defineProperty(target, key,sharedPropertyDefinition);,
2.第二题:this.$emit问题
问题:this.$emit的返回值是什么? --this;--如果需要返回值可以使用回调参数。
解答:
handleChange(e){
const res = this.$emit("change",e.target.value,val →> {console.log(val);
});
console.log(res,res =ss this);
},
handleEventChange(val,callback){
this.name = val;
callback("hello")Areturn "hello";
}
3. 第三题:同名插槽问题
问题:
相同名称的插槽是否合并还是替换?
解答:
Vue2.5版本,普通插槽合并、替换;Vue2.6版本,都是替换;
methods: {
validate(phone = "") {
return phone 8& /^1[8-9]{10$/. test (phone);
}
}
4.第四题:为什么index不可用做key?
问题:
为什么不能用index作为key?
解答;
因为index设计到更新DOM性能问题以及会引起状态BUG问题,所以不可以用为key;
<template>
<div class="border">
<Children v-for="(key, index) in list" :key=" index">
<button @click="() => handleDe Lete (key)">删除</button>
</Children>
<button @click="handleAdd">添加</button>
</div>
</template>
<script>
import Children from "./Children" ;
let key = 1;
export default {
components:{
Children
},
data() {
return {
list: []
};
},
methods: {
handleAdd() {
this. list. push(key++);
},
handLeDe Lete(key) {
const index = this. list. findIndex(k = k === key;
this. list. splice(index, 1);
}
}
};
</script>
<template>
<div class=" border2">
<input v-model=" phone" type=" number" />
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
phone:""
};
}
};
</script>
<template>
<div class="border">
<Children v-for="key in List"( ey="key">
button @click="() => handleDe Lete( key )">删除</button>
</Children>
<button @click="handleAdd">添加</ button>
</div>
</ template>
<script>
import Children from "./Children" ;
let key = 1;
export default {
components: {
Children
},
data() {
return {
list: []
};
},
methods: {
handleAdd() {
this.list. push(key++);
},
},
handleDelete(key) {
const index = this. list. findIndex(k = k === key);
this.list. splice(index, 1);
}
};
</script>
5.第五题:底层原理问题
问题:
数组有哪些方法支持响应式更新,如不支持如何处理,底层原理如何实现的?
解答:
- 支持: push(、pop(、shift()、 unshift(、 splice(、 sort(、 reverse()
- 不支持: filter()、concat()、 slice()
- 原理同样是使用Object.defineProperty对数组方法进行改写
对不支持的方法也很简单,只需要更改整个数组,赋值成一个新的数组就行。这里的改写其实就是中间做了一个代理层。
6. 第六题:防抖改造问题
问题:
对Watch1 Demo进行防抖改造,即直到用户停止输入超过500毫秒后,才更新fullName ;
解答:
- setTimeout
- lodash debounce
- Demo 1.5/Wattch1 pro
<template>
<div>
{{ fulUName }}
<div>f irs tName: <input v-model="f irs tName" /></div>
<div>lastName: <input v-mode L="las tName" /></div>
</div>
</template>
<script>
export default {
data: function() {
return {
firstName: "Foo",
lastName: "Bar" ,
fulIName: "Foo Bar"
};
},
watch: {
firstName: function(val) {
clearTimeout(this. firstTimeout);
this. firstTimeout = setTimeout() => {
this. fullName = val +””+ this. las tName;
}, 5000
},
lastName: function(val) {
clearTimeout(this. lastTimeout);
this. LastTimeout = setTimeout(() => {
this. fulName = this. firstName +””+ val;
},500);
}
}
};
</script>
7.第七题:设计秒杀倒计时组件
问题:设计一个秒杀倒计时组件;
解答:
<template>
<div>
<Spike :start-t ime="startTime" :end-t ime="endTime" />
</div>
</template>
<script>
import moment f rom "moment" ;
import Spike from "./Spike" ;
export default {
components: {
Spike
},
data() {
return {
startTime: moment("2019-03-10 14:44:00"),
endTime: moment("2019-03-08 14:46: 00")
};
}
};
</scripts>
难点在于如何对时间进行校验(因为时间是可以被修改的),一般是通过获取服务器的时间与本地时间计算一个时间差。
8.第八题:生命周期和指令钩子顺序
问题:
怎么查看组件生命周期和指令周期钩子的顺序?
解答:
新建是先组件再指令,更新是先指令再组件,销毁也是先组件再指令。
<temptate>
<div class="border">
<h1>A结点</h1>
<button @click="() => changeColor()">改变color</button>
<ChildrenB />
<ChildrenC />
<ChildrenD />
</div>
</template>
<script>
import Vue from "vue" ;
import ChildrenB from "./ChildrenB";
import ChildrenC from "./ChildrenC";
import ChildrenD from "./ChildrenD";
export default {
components: {
ChildrenB,
ChildrenC,
ChildrenD
},
provide() {
this. theme = Vge. observable({
color: "blue"
});
return {
theme: this . theme
};
},
methods: {
changeColor(color) {
if (color) {
this. theme.color = color;
} else {
this. theme.color = this. theme.color === "blue" ? "red" : "blue";
}
}
};
9.第九题:v-ant-ref指令回调问题
问题:
v-ant-ref指令回调中能不能对更改响应式数据?为什么?
解答:
不能,会死循环!!!