【Vue五分钟】 vue练习题、面试题解答

简介: 子组件为什么不可以修改父组件传递的Prop,如果修改了,Vue是如何监控到属性的修改并给出相应的警告呢?

1.第一题:Vue监控属性警告问题

  子组件为什么不可以修改父组件传递的Prop,如果修改了,Vue是如何监控到属性的修改并给出相应的警告呢?

解答:

 因为 vue 是单向数据流。如果一开始没有 created 则可以修改,加上 created 里面的 proxy 就可以阻止子组件 proxy.vue去修改父组件的 info ,当然如果是通过 $emit 就可以。 Proxy.js 是对 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";
}

子组件返回了值和回调函数,我们这里就接受了值和回调函数即 callback 则不需要后面的 return 了。


3. 第三题:同名插槽问题

问题:

    相同名称的插槽是否合并还是替换?

解答:

    Vue2.5版本,普通插槽合并、替换;Vue2.6版本,都是替换;

2345_image_file_copy_432.jpg

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>

如图每次点击添加的时候就会往数组加 1,而删除的时候则是数组变成了长度为 2index 也跟着变了,那么删除的就是最后一个了,不管点的是哪一个。

修改后:(这样就正常了!!!)

<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

第一种就是利用定时器做一个 500 毫秒的延迟就行(计算属性无法做到)。另一种就是利用第三方库什么的。

<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";
}
}
};

通过 observable 来实现响应式数据。


9.第九题:v-ant-ref指令回调问题

问题:

   v-ant-ref指令回调中能不能对更改响应式数据?为什么?

解答:

  不能,会死循环!!!

组件更新就会触发回调,如果回调中更改数据又会触发组件更新又会触发回调,一直下去。

相关文章
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
JavaScript
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
这篇文章深入探讨了Vue中的`slot`概念,包括它的定义、使用场景和分类(默认插槽、具名插槽和作用域插槽),并通过代码示例展示了如何在组件中使用插槽来实现内容的分发和自定义。同时,文章还对插槽的工作原理进行了分析,解释了`renderSlot`函数和`$scopedSlots`对象的角色。
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
265 64
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
134 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?