Vue组件data为什么必须是函数?
- new Vue()实际中,data可以直接是一个对象,为什么在Vue组件中,data必须是一个函数那?
- 因为组件是可以复用的,JS里对象是引用关系,如果组件data是一个对象,那么子组件中的data属性值会互相污染,产生副作用;
- 所以一个组件的data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝.new Vue的实例是不会被复用的,因此不存在以上问题.(简述:组件是复用的,所以需要保证每个组件都单独的维护一份状态,所以需要写成函数返回一个对象)
v-if和v-for嵌套使用的问题?
- 优先级:
- 在vue2中v-for优先级高;
- 在vue3中v-if优先级高;
- 但是无论如何两个组合在一起使用官方都不推荐
- 因此同时出现,会导致先for循环子元素,在判断每个子元素的if情况下.
- 想要先执行if,在满足的条件下再循环子元素,可以在v-for的元素外层加一个有if指令的template标签;
什么是MVVM框架?
- MVVM是Model-View-ViewModel缩写;也就是把MVC中的Controller演变成ViewModel.
- Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到ViewModel层并自动将数据渲染到页面中,视图变化的时候会通知ViewModel层更新数据.
- 总之,我的理解是数据驱动视图,通过状态的修改MVVM的框架就会去主打的更新视图;
Vue能监听到数组变化的方法有哪些?
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()这些方法,都是在框架内重写过的,并不是原生的方法,新的方法,里边增加了监听;
Proxy 与Object.defineProperty的优劣势对比?
- Proxy的优势如下:
- Proxy可以直接监听对象而非属性;
- Proxy可以直接监听数组的变化;
- Proxy有多达13种拦截方法,不限于apply.ownKeys.deleteProperty. has等等是Object.defineProperty不具备的;
- Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
- Object.defineProperty的优势:兼容性好,支持IE9;
Vue-router hash模式和history模式是如何实现的?
- hash模式:
- #后面hash值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请求,就不会刷新页面.同时通过监听hashchange事件可以知道hash发生了哪些变化,然后根据hash变化来实现更新页面部分内容的操作;
- history模式:
- history模式的实现,主要是HTML5标准发布的两个API,pushState和replaceState,这两个API可以在改变url,但是不会发送请求,这样就可以监听url变化来实现更新页面部分内容的操作.
- 区别:
- url展示上,hash模式有"#",history 模式没有;
- 刷新页面时,hash模式可以正常加载到hash值对应的页面,而history没有处理的话,会返回404,一般需要后端将所有页面都配置重定向到首页路由;
Vuex的理解:
- Vuex是为了大型项目开发的,实现不同组件之间的状态管理(数据共享),适用于多个组件之间的数据交互;
- Vuex应用核心就是store(仓库). store就是一个容器,包含了应用中大部分的state(状态)
- Vuex是单项的数据流,组件不能直接修改容器中state的状态(数据)
- 改变 store中的状态的唯一途径就是显示commit(提交) mutation,组件状态state发生变化.
- 在非严格模式下,strict:false 允许直接来修改状态state,但是一般都是在严格模式中通过mutation来修改数据;
- 缺点:Vuex的数据不能持久化.Vuex在页面刷新后数据不会再存在;
- 主要有以下几个模块:
- State:定义了应用状态的数据结构,可以在这里设置默认的初始化状态;
- Getter:允许组件从store 中获取数据,mapGetters 辅助函数仅仅是将store中的getter映射到计算属性.
- Mutation: 唯一更改store中状态的方法,并且必须是同步函数.
- Action:用于提交mutation,而不是直接变更状态,可以包含任意异步操作.
- Module:允许将单一的store拆分为多个store并且同时保存在单一的状态树中;
- 扩展:action和mutation之间的区别:
- mutation对象是Vue中唯一一个可以修改state状态的方式.mutation对象中方法必须是同步的,因为提交的mutation触发时回调函数还没有被调用,那么数据的状态就无法准确的知道是不是最新的.
- action对象用于提交的是一个mutation事件,不可以修改数据的状态.action中的方法支持异步;
如何让样式当前有效?如何修改第三方组件的样式?
- style设置一个scoped属性就表示当前组件内有效;
- 第三方组件(类似elementui)设置样式,超逸使用::v-deep 新建的话用:deep这两个内置选择器来穿透到组件内部去覆盖它的样式.如果使用ui组件提供有一些变量的话,(类似elementui就提供有),那么直接给这些变量重新赋值也可以进行修改;
谈一谈nextTick的原理?
- 在下次DOM更新循环结束之后执行延迟回调.nextTick主要使用了宏任务和微任务.根据执行环境分别尝试采用:
- Promise
- MutationObserver
- setlmmediate
- 如果以上都不行则采用setTimeout
- 定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列;
vm.$set()实现原理是什么?
受现代JavaScript的限制(而且Object.observe 也已经被废弃),Vue无法检测到对象属性的添加或删除.
- 由于Vue会在初始化实例时对属性执行getter/setter转化,所以属性必须在data对象上存在才能让Vue将它转换为响应式的.
- 对于已经创建的实例,Vue不允许动态添加到根级别的响应式属性.但是,可以使用Vue.set(object,propertyName,value)方法向嵌套对象添加响应式属性;
- 总之,通过$set可以对指定的属性通过Object.definePropertytian