目录
5. Vue和jQuery的区别在哪里?为什么放弃jQuery用Vue?
20. 对象新属性无法更新视图,删除属性无法更新视图,为什么?怎么解决?
21. 直接arr[index] = xxx无法更新视图,为什么?怎么解决?
24. 为什么不建议使用index作为key,为什么不建议使用随机岁做key?
Object.defineProperty和Proxy的优缺点?
47. 计算变量时,methods和computed哪个好?
1. Vue的优点?Vue的缺点?
优点:渐进式、组件化、轻量级、虚拟 DOM 、响应式、单页面路由、数据与试图分开。
缺点:单页面不利于 SEO、不支持IE8以下、首屏加载时间长。
2. 为什么说Vue是一个渐进式框架?
我觉得可能是因为 Vue主张少,不强势。你可以在核心功能的基础上任意选用其他的部件,不一定要全部整合在一起。可以看到,所说的渐进式,其实就是 Vue 的使用方式,同时也体现了 Vue 的设计的理念,总而言之,你可以有很多选择,并不是非常强制你一定要用那种方式,Vue 只是为我们提供了视图层,至于底层的实现,还是有非常多的选择的。
3. Vue跟React的相同点与不同点?
相同点:
- 都使用了虚拟 DOM。
- 组件化开发。
- 都是单向数据流(父子组件之间,不建议子组件修改父组件传递下来的数据)。
- 都支持服务端渲染。
不同点:
- React 的 JSX,Vue 的 template。
- 数据变化:React 手动(setState),Vue 自动(初始化已响应式处理,Object.defineProperty)。
- React 是单向绑定,Vue 是双向数据绑定。
- React 使用 Redux,Vue 使用 Vuex。
4. MVVM是什么?和MVC有什么区别呢?
MVC:是Model View Controller的简写
- Mode(模型):负责从数据库中取数据。
- View(视图):负责展示数据的地方。
- Controller(控制器):用户交互的的地方例如点击时间等。
- 思想:Controller将Model的数据展示在View上。
MVVM:是Model View ViewModel的简写
- Mode(模型):负责从数据库中取数据。
- View(视图):负责展示数据的地方。
- ViewModel(): mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
- 思想:实现了 View 和 Model 的自动同步,也就是当 Model 的属性改变时,我们不用再自己手动操作 Dom 元素,来改变 View 的显示,而是改变属性后该属性对应 View 层显示会自动改变(对应 Vue 数据驱动的思想)。
区别:
整体看来,MVVM 比 MVC 精简很多,不仅简化了业务与界面的以来,还解决了数据频繁更新的问题,不用再用到选择器操作DOM元素。因为在 MVVM 中,View 不知道 Model 的存在,Model 和View Mode l也观察不到 View,这种低耦合模式提高代码的可可重用性。
5. Vue和jQuery的区别在哪里?为什么放弃jQuery用Vue?
- jQuery 是直接操作 DOM,Vue 不直接操作 DOM,Vue 的数据与视图是分开的,Vue 只需要操作数据即可。
- 在操作 DOM 频繁的场景里,jQuery 的操作 DOM 行为是频繁的,而 Vue 利用虚拟 DOM 的技术,大大提高了更新 DOM 是的性能。
- Vue 中不倡导直接操作 DOM,开发者只需要把大部分精力放在数据层面上。
- Vue 集成的一些库,大大提高开发效率,比如 Vuex,Router 等。
6. 为什么 data 是个函数呢?
组件中的 data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变了全都会变的结果。
7. Vue 的修饰符有哪些呢?
- .trim 修饰符的作用类似与 js 中的 trim() 方法,作用是吧 v-model 绑定的值首尾空格给过滤掉。
<input type="text" v-model.trim="value">
- .number 修饰符的作用是将值转换成数字,但是先输入字符串和先输入数字是两种情况。先输入数字的话,只取前面数字部分。先输入字母的话,number 修饰符无效。
<input type="text" v-model.number="value">
- .lazy 修饰符的作用是改变输入框的值时 value 不会改变,当光标离开输入时,v-model 绑定的 value 才会改变。
<input type="text" v-model.lazy="value">
- .stop 修饰符的作用是阻止冒泡。
<div @click="clickEvent(2)" style="width:300px;height:100px;background:red"> <button @click.stop="clickEvent(1)">点击</button> </div> methods: { clickEvent(num) { console.log(num) // 不加 stop 点击按钮输出 1 2 , 加了 stop 点击按钮输出 1 } }
- .capture 事件默认是由里往外冒泡,capture 修饰符的作用是反过来,由外往内捕获。
<div @click.capture="clickEvent(2)" style="width:300px;height:100px;background:red"> <button @click="clickEvent(1)">点击</button> </div> methods: { clickEvent(num) { console.log(num) // 不加 capture 点击按钮输出 1 2,加了 capture 点击按钮输出 2 1 } }
- .prevent 修饰符的作用是阻止默认事件(比如a标签的跳转)。
<a href="#" @click.prevent="clickEvent(1)">点我</a> methods: { clickEvent(num) { console.log(num) // 不加 prevent 点击a标签 先跳转然后输出 1,加了 prevent 点击a标签 不会跳转只会输出 1 } }
- .self 修饰符的作用是只当在 event.target 是当前元素自身时触发处理函数。
<div @click.self="clickEvent(2)" style="width:300px;height:100px;background:red"> <button @click="clickEvent(1)">点击</button> </div> methods: { clickEvent(num) { console.log(num) // 不加 self 点击按钮输出 1 2,加了 self 点击按钮输出 1 点击div才会输出 2 } }
- .once 修饰符的作用是事件将只会触发一次。
<div @click.once="clickEvent(2)" style="width:300px;height:100px;background:red"> <button @click="clickEvent(1)">点击</button> </div> methods: { clickEvent(num) { console.log(num) // 不加 once 多次点击按钮输出 1,加了 once 多次点击按钮只会输出一次 1 } }
- .passive 当我们在监听元素滚动事件的时候,会一直触发onscroll事件,在pc端是没啥问题的,但是在移动端,会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符。
<div @scroll.passive="onScroll">...</div>
- .left .middle .right 这三个修饰符是鼠标左中右出发的事件。
<button @click.middle="clickEvent(1)" @click.left="clickEvent(2)" @click.right="clickEvent(3)">点我</button> methods: { // 点击中键输出1 // 点击左键输出2 // 点击右键输出3 clickEvent(num) { console.log(num) } }
- .sync 修饰符
// 当父组件传值进子组件,子组件想要改变这个值时,可以这么做. // 父组件里 <children :foo="bar" @update:foo="val => bar = val"></children> // 子组件里 this.$emit('update:foo', newValue) // sync修饰符的作用就是,可以简写: // 父组件里 <children :foo.sync="bar"></children> // 子组件里 this.$emit('update:foo', newValue)
8. 常用的 Vue 指令有哪些呢?
- v-model 多用于表单元素实现双向数据绑定,也可实现父子组件传值,本质上是一个语法糖,底层原理是由 @input 事件 + value 实现的。
- v-bind 为元素的属性动态绑定值,一般简写为 : 。
v-bind:class 三种绑定方法 1、对象型 '{red:isred}' 2、三元型 'isred?"red":"blue"' 3、数组型 '[{red:"isred"},{blue:"isblue"}]'
- v-for 列表循环渲染,数组、对象、数字、字符串都可以。基于一个数组来渲染一个列表。建议设置 key 值,并且保证每个 key 值是独一无二的,这便于 Diff 算法进行优化。
1. 在写v-for的时候,都需要给元素加上一个key属性。 2. key的主要作用就是来提高渲染性能的(能够更高效的更新虚拟 DOM)。 3. key的属性可以避免数据渲染混乱的情况出现(如果元素中包含了临时数据的元素,如果不用key就会产生数据混乱)。 4. 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。而Key会帮我们记住元素们的顺序,并根据这个顺序在适当的位置插入/删除元素来完成更新,这种方法比没有key属性时,就地复用策略的效率更高。
- v-show 显示内容,原理是动态为元素添加或移除 display 样式,来实现元素的显示和隐藏。
- v-if 显示与隐藏,原理是动态的在 DOM 树上创建或移除元素,实现元素的显示和隐藏。
v-else-if 和 v-else 必须和 v-if 连用 不能单独使用 否则报错 模板编译错误。
v-if和v-show的区别:1. 手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏。 2. 编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换。 3. 编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留。 4. 性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗。
- v-on 事件绑定,可以缩写为@,例如绑定一个点击函数 函数必须写在 methods 里面。
- v-text、v-html 解析文本。
区别:
v-text:用于解析文本,但不能解析标签,并且会覆盖元素内部原有的内容!
v-html:可以把带有标签的字符串,渲染成真正的 HTML 内容! -
v-slot 在
v2.6
中,为具名插槽和作用域插槽引入了一个新的统一语法,即 v-slot。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。 - v-once 作用就是定义它的元素或组件只会渲染一次,包括元素或者组件的所有字节点
- v-pre 跳过这个元素和它的子元素的编译过程。
- v-cloak 可以使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除。
当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。
9. 组件之间通信方式有哪些?
- 父组件传值给子组件,子组件使用 props 进行接收
- 子组件传值给父组件,子组件使用 $emit + 事件 对父组件进行传值
- 组件中可以使用 $parent 和 $children 获取到父组件实例和子组件实例,进而获取数据
- 使用 $attrs 和 $listeners,在对一些组件进行二次封装时可以方便传值,例如A->B->C
- 使用 $refs 获取组件实例,进而获取数据
- 使用 Vuex 进行状态管理
- 使用 eventBus 进行跨组件触发事件,进而传递数据
- 使用浏览器本地缓存,例如 localStorage
10. 路由有哪些模式呢?又有什么不同?
hash 模式:通过 #号 后面的内容的更改,触发 hashchange 事件,实现路由切换。
history模式:通过 pushState 和 replaceState 切换 url,实现路由切换,需要后端配合。