购买天猫店铺网站,做蓝牙app的网站,wordpress批量发文章,百度地图人工服务1. vue优点 轻量级速度快简单易学低耦合可重用性独立开发文档齐全#xff0c;且文档为中文文档 2. ## vue中组件间传值 prop/$emit 父子组件传值 ref 和 $parent/$children 父子组件传值 eventBus($emit/$on) 父子#xff0c;隔代#xff0c;兄弟组件传值 $attrs/$listeners…1. vue优点 轻量级速度快简单易学低耦合可重用性独立开发文档齐全且文档为中文文档 2. ## vue中组件间传值 prop/$emit 父子组件传值 ref 和 $parent/$children 父子组件传值 eventBus($emit/$on) 父子隔代兄弟组件传值 $attrs/$listeners 隔代 provide/inject 隔代 vuex 父子隔代兄弟组件传值 3. ## vue生命周期vue2和3 vue2beforeCreate/created、beforeMount/mounted、beforeUpdate/updated、actived/deadctived、beforeDestory/destoryed vue3setup、 beforeMount/mounted、 beforeUpdate/updated、 actived/deadctived、 beforeUnmount/unmounted、errorCapurted当捕获一个来自子孙组件的异常时激活 actived被包含在keep-alive中的组件会多出两个生命周期钩子函数被激活时执行 Deactivated比如从A组件切换到B组件A组件消失时执行 4. ## vue设计模式 mvvm设计模式 工厂模式传入参数即可创建实例虚拟dom根据参数的不同返回基础标签的vnode和组件vnode。单例模式整个程序有且只有一个实例。第二次使用同一个类创建新对象的时候应该得到与第一次创建的对象完全相同的对象。Vuex策略模式指对象有某个行为但是在不同的场景中该行为有不同的实现方案观察者模式响应式数据原理发布/订阅者模式vue事件机制核心就是一对多的关系一个发布者发起所有订阅者都会执行。代理模式它为目标对象创造了一个代理对象以控制对目标对象的访问。拦截器监听对象属性的增加或删除装饰模式装饰器的用法在不改变原对象的基础上通过对其添加属性或方法来进行包装扩展使得原有对象可以动态具有更多功能。 Actions是一个装饰器他包裹mutations使之可以异步使用。对于Store对象使用Action可以异步改变状态不用Actions也能使用mutations来同步改变状态使用actions也不会改变state、getter、mutation的用法、结构 适配器模式 作为两个不兼容的接口之间的桥梁 5. ## vue自定义指令怎么写 两种方式 全局指令通过Vue.directive()函数注册一个全局的指令 局部指令通过组建的directives属性对该组件添加一个局部的指令 创建全局指令 需要传入指令名称以及一个包含指令钩子函数的对象该对象的键即钩子函数的函数名值即函数体钩子函数可以有多个。 // 注册全局自定义指令
Vue.directive(my-directive, {// 在绑定元素的时候会被调用bind: function(el, binding, vnode) {// 操作DOMel.style.color red;// 访问指令的值和参数console.log(指令的值: , binding.value);console.log(指令的参数: , binding.arg);// 访问绑定元素的属性和内容console.log(绑定元素的属性: , el.getAttribute(title));console.log(绑定元素的内容: , el.innerHTML);},// 在绑定元素所在的组件的 VNode 更新时调用update: function(el, binding, vnode) {// 通过比较新旧值来避免不必要的更新if (binding.value ! binding.oldValue) {// 执行更新的操作}},// 在指令与元素解绑时调用unbind: function(el, binding, vnode) {// 清除元素的样式el.style.color ;}
})然后你可以在Vue模板中使用自定义指令 div v-my-directivedirectiveValue titleDirective ExampleCustom Directive Example/div创建局部指令通过在Vue实例中添加directives对象数据注册局部自定义指令。 directives: {focus: {inserted: function(el) {el.focus();}}
} 举例 图片懒加载有些网站图片的加载做的非常优雅在图片未完成加载之前用随机的背景色占位图片加载完成之后才直接渲染出来用自定义指令可以非常方便的实现这个功能。 div idapp v-image item v-foritem in imageList/div
script
Vue.directive(image, {inserted: function(elbinding){var color Math.floor(Math,random()*1000000)el.style.backgroundColor # colorvar img new Image()img.src binding.vauleimg.onload function(){ el.style.backgroundImage “url(” binding.vaule )}}})new Vue({el: #app,data: {imageList: [{url: http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-p10-plus.jpg},{url: http://consumer-img.huawei.com/content/dam/huawei-cbg-site/greate-china/cn/mkt/homepage/section4/home-s4-watch2-pro-banner.jpg},{url: http://consumer-img.huawei.com/content/dam/huawei-cbg-site/en/mkt/homepage/section4/home-s4-matebook-x.jpg}]}})/script 应用场景 防抖图片懒加载一键复制功能… 自定义指令的钩子函数均为可选 bind只调用一次指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 inserted被绑定元素插入父节点时调用保证父节点存在但不一定已被插入文档中。 update所有组件的VNode更新时调用但是可能发生在其子VNode更新之前。指令的值可能发生了改变也可能没有。但似乎你可以通过比较更新前后的值来忽略不必要的模板更新。 componentUpdated指令所在组件的VNode及其子VNode全部更新后调用。 unbind只调用一次指令与元素解绑时调用。 钩子函数参数(即 el、binding、vnode 和 oldVnode) el指令所绑定的元素可以用来直接操作 DOM。binding一个对象包含以下 property 6. v-show 和 v-if 指令的共同点和不同点 相同点都可以控制dom元素的显示和隐藏 不同点v-show只是改变display属性dom元素并未消失切换时不需要重新渲染页面 v-if直接将dom元素从页面删除再次切换需要重新渲染页面 区别点 v-if 是动态的向 DOM 树内添加或者删除 DOM 元素 v-show 是通过设置 DOM 元素的 display 样式属性控制显隐 v-if 切换有一个局部编译/卸载的过程切换过程中合适地销毁和重建内部的事件监听和子组件 v-show 只是简单的基于 css 切换 性能消耗 v-if 有更高的切换消耗 v-show 有更高的初始渲染消耗 使用场景 v-if 适合运营条件不大可能改变 v-show 适合频繁切换 7. ## 怎么封装一个良好可复用的组件 在vue中组件可以通过以下方式创建 Vue.component(my-component, {// options
}) 这是一种全局组件注册方式my-component是组件名称可以在Vue实例中的模板中使用。 在组建开发中我们要注意以下几点 设计良好的API一个良好的API应该遵循简洁性、一致性、可扩展性、易用性的原则。要保证组件的独立性这样才能更好的被复用。通过渲染函数和JSXjs的语法扩展 jsxml的方式创建组件要注意以下几点只在必要时使用渲染函数和JSX尽可能地简洁和易于理解使用模板字符串来定义字符串常量使用严格相等运算符通过v-bind来绑定属性。分离组件的结构、样式和行为使用slot分发内容使用props传递数据减少耦合使用scoped css 限制样式作用范围 8. ## Vue的v-for与v-if的优先级v-for和v-if的区别为什么不推荐在v-for中使用v-if如果出现这样的使用场景你推荐用什么方式取代 Vue的v-for与v-if的优先级 v-for优先于v-if这意味着当v-for和v-if同时存在于同一个元素上时v-for会优先执行然后在每一次迭代中才会应用v-if的条件。 v-for和v-if的区别 作用不同v-if指令用于条件渲染只有指令的表达式返回true时才会显示而v-for指令基于一个数组来渲染一个列表。优先级不同v-for高于v-if在进行if判断的时候v-for是比v-if先进行判断的。 不推荐在v-for中使用v-if的原因有以下几点 v-for和v-if同时使用容易带来性能方面的浪费每次渲染都会先循环再进行条件判断 也容易造成逻辑混乱在v-for中嵌套v-if会使得代码的逻辑变得复杂难以理解和维护。特别是v-for循环较大时会导致代码的可读性下降。 如果条件出现在循环外部当需要先v-if再v-for时可以在外层嵌套template在这一层进行v-if判断在内部进行v-for循环。 如果条件出现在循环内部可以通过计算属性computed提前过滤掉那些不需要显示的项。 9. 如何获取dom 给dom元素加 refrefname, 然后通过this.$refs.refname进行获取dom元素 10. 说出几种vue当中的指令和它的用法 v-model 实现数据的双向绑定可以实时修改数据 v-bind动态绑定及时对页面的数据进行更改常简写为 v-bind:class绑定一个属性v-on用于绑定事件多个事件绑定 v-on{事件名方法名事件名方法名,……}v-for遍历 循环数组或者json v-for字段名in(of)数组/jsonv-if条件渲染v-show条件渲染v-hide隐藏 v-else/v-else-if和if语句中else if的用法相同当v-if不成立时执行 v-text会把解析到为文本完全替换掉标签里的内容 v-html会将其当html标签解析后输出 v-once所在节点在初次动态渲染后就视为静态内容了。 以后数据的改变不会引起v-once所在结构的更新可以用于优化性能。 v-pre跳过Vue在有v-pre属性的所在节点的编译过程。 可利用它跳过没有使用指令语法、没有使用插值语法的节点会加快编译速度。 v-clock防止闪烁 11. vue-loader是什么它的用途是什么 vue文件的一个加载器将template/js/style转换为js模块 用途js可以写es6、style样式 12. 为什么用key 给每个dom元素加上key作为唯一标识diff算法可以正确的识别到这个节点使页面渲染更加迅速。 13. axios及安装 vue项目中使用ajax时需要axios插件 下载方式 cnpm install axios --save 14. 请说出vue.cli项目中src目录每个文件夹和文件的用法 components存放组件app.vue 主页面入口main.js 主文件入口assets 存放静态资源文件 15. Computed和Watch的区别分别简述computed和watch的使用场景 computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的 属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。 watch 侦听器 : 更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每 当监听的数据变化时都会执行回调进行后续操作。 用官网的一句话来说所有需要用到计算的都应该使用计算属性。多条数据影响一条数据时使用计算属性使用场景购物车。 如果是一条数据更改影响多条数据时使用watch使用场景搜索框。 16. ## $nextTick 的使用 在data()中的修改后页面中无法获取data修改后的数据使用$nextTick时当data中的数据修改后可以实时的渲染页面 17. vue组件中data为什么必须是一个函数 因为js的特性所导致在component中data必须以函数的形式存在不可以是对象。 组件中的data写成一个函数数据以函数返回值的形式定义这样每次复用组件的时候丢回返回一份新的data相当于每个组件实例都有自己私有的数据空间他们值负责各自维护数据不会造成混乱。而单纯的写成对象形式就是所有组件实例共用了一个data这样改一个全部都会修改。 18. 渐进式框架的理解 主张最少可以根据不同的需求选择不同的层级 19. vue在双向数据绑定是如何实现的 vue双向数据绑定是通过数据劫持、组合、发布订阅模式的方式来实现的也就是说数据和视图同步数据发生变化视图跟着变化视图变化数据也随之发生变化。 核心关于vue双向数据绑定其核心是Object.defineProprerty()方法。 20. 单页面应用和多页面应用的区别及缺点 单页面应用SPA)通俗地说就是只有一个主页面的应用浏览器一开始就加载所有的js、html、css。所有的页面内容都包含在这个主页面中但在写的时候还是分开写然后再加护的时候有路由程序动态载入单页面的页面跳转仅刷新局部资源。多用于pc端。 多页面应用MPA)就是一个应用中有多个页面页面跳转时整个页面刷新 单页面的优点用户体验好快内容的改变不需要重新加载整个页面基于这一点spa对服务器压力较小前后端分离页面效果会比较酷炫。 单页面的缺点不利于seo导航不可用如果一定要导航需要自行实现前进、后退。初次加载时耗时多页面不复杂度提高很多。 21. Vue项目中为什么要在列表组件中写key其作用是什么 key时给每个vnode的唯一id可以依靠key更准确更快的拿到oldVnode中对应的vnode节点。 更准确 因为带key就不是就地复用了在sameNode函数 a.key b.key 对比中可以避免就地复用的情况。所以会更加准确。 更快 利用key的唯一生成map对象来获取对应节点比遍历方式更快。 22. 父组件和子组件生命周期钩子函数的执行顺序是什么? 加载渲染过程 父 beforeUpdate - 父created - 父beforeMount - 子 beforeCreate - 子created - 子beforeMount - 子mounted - 父mounted 子组件更新过程 父beforeUpdate - 子beforeUpdate - 子updated - 父updated 父组件更新过程 父beforeUpdate - 父updated 销毁过程 父beforeDestory - 子beforeDestory - 子destroyed - 父destroyed 23. vue和jQuery的区别 jQuery是使用选择器$选取DOM对象对其进行赋值、取值、事件绑定等操作其实和原生的html的区别只在于可以更方便的选取和操作DOM对象而数据和界面是在一起的。比如需要获取label标签的内容$(label).val()它还是依赖DOM 元素的值。 Vue则是通过Vue对象将数据和View完全分离开来。对数据进行操作不再需要引用相应的DOM对象可以说数据和View是分离的他们通过Vue对象这个vm实现相互的绑定这就是传说的MVVM。 24. delete 和 Vue.delete 删除数组的区别 delete只是被删除的元素变成了empty/undefined 其他元素的键值还是不变。 Vue.delete直接删除了数组改变了数组的键值。 25. SPA首屏加载慢如何解决 安装动态懒加载所需的插件使用CDN资源。 26. vue项目是打包了一个js文件一个css文件还是有多个文件 根据vue-cli脚手架规范一个js文件一个css文件。 27. vue更新数组时触发视图更新的方法。 push() 尾部添加pop() 尾部删除shift() 头部删除unshift() 头部添加splice() 删除添加替换sort() 排序reserve() 翻转 28. 什么是vue的生命周期有什么作用 每个Vue实例在被创建时都要经过一系列的初始化过程——例如需要设置数据监听、编译模板、将实例挂在到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一下叫做生命周期钩子的函数这给了用户在不同阶段添加自己代码的机会。 29. 第一次页面加载会触发哪几个钩子 beforeCreate、Created、beforeMountmounted 30. vue获取数据一般在那个周期函数 created、beforeMount、mounted 31. Vue生命周期的理解 总共分为8个阶段创建前后载入前后更新前后销毁前后。 生命周期描述beforeCreate组件实例被创建之初组件的属性生效之前created组件实例已经完全创建属性也绑定但真实 dom 还没有生成$el 还不可用beforeMount在挂载开始之前被调用相关的 render 函数首次被调用mountedel 被新创建的 vm.$el 替换并挂载到实例上去之后调用该钩子beforeUpdate组件数据更新之前调用发生在虚拟 DOM 打补丁之前updated组件数据更新之后activitedkeep-alive 专属组件被激活时调用deadctivatedkeep-alive 专属组件被销毁时调用beforeDestory组件销毁前调用destoryed组件销毁后调用 32.vuex是什么 vue框架中状态管理。 33. ## vuex有哪几种属性 state、getter、mutation、action、module state基本数据数据源存放地 getter从基本数据派生出来的数据 mutation提交更改数据的方法同步 action像一个装饰器包裹mutations使之可以异步。 module模块化Vuex 34. ## Vue框架的原理打包知识项目构建 vue框架的原理 vue框架是一个基于mvvm模式的前端框架其核心思想是将视图和状态分离通过数据驱动的方式将模型和视图箭囊里关联。他的核心原理主要包括以下几个方面 响应式数据vue通过使用Object.defineProperty()方法来劫持数据的get和set操作从而实现了数据的响应式。当数据变化时vue会通知相关的视图进行更新。虚拟domvue通过使用虚拟dom来优化页面渲染性能。在组件更新时vue会先构建一个虚拟dom树然后通过比较新旧虚拟dom树的差异最终只对需要更新的部分进行真是dom操作提升页面渲染效率。组件化开发vue框架将页面拆分成独立的组件每个组件都有自己的状态和视图可以互相结合和嵌套。通过组件化开发可以提高代码的可复用性和可维护性。模板编译vue框架通过将vue组建的模板编译成渲染函数来实现数据和视图的关联。编译过程会将模板解析成AST抽象语法树然后将AST编译成渲染函数渲染函数会生成虚拟dom。 打包知识和项目构建 在开发项目时常常需要进行打包和构建以便将多个模块或者文件打包成一个或多个最终部署的静态资源文件常用的打包工具包括webpack和parcelvue3使用vite打包 配置文件打包工具会使用一个配置文件如webpack.config.js来定义项目的构建规则和需要处理的文件在配置文件中你可以设置入口文件entry、输出文件路径、使用的加载器loader和插件plugin、开发和生产模式mode。 entry入口文件 output文件输出的路径 chunk多个文件组成一个代码块可以将可执行的门票快和其他所依赖的模块组合成一个 chunk这就是打包 loader文件转换器例如把sass转换为css plugin扩展webpack功能的插件 35. ## 二次封装axios的想法和步骤 创建一个新的Axios实例对其进行定制化设置如添加默认的请求头设置超时时间等。 import axios from axios;const http axios.create({baseURL: https://api.example.com/, // 设置基本URLtimeout: 5000, // 设置请求超时时间headers: {Content-Type: application/json // 设置默认的请求头}
});export default http;添加拦截器通过添加请求拦截器和相应拦截器你可以在请求发送前和响应返回后对数据进行统一处理如添加认证信息、错误处理等。 import http from ./http;http.interceptors.request.use(config {// 在发送请求之前做些什么return config;},error {// 对请求错误做些什么return Promise.reject(error);}
);http.interceptors.response.use(response {// 对响应数据做些什么return response;},error {// 对响应错误做些什么return Promise.reject(error);}
);export default http;封装常用的请求方法基于新的Axios实例你可以封装一些常用的请求方法比如get、post等来简化代码编写。 import http from ./http;export const get (url, params) {return http.get(url, { params });
};export const post (url, data) {return http.post(url, data);
};你可以通过导入封装后的Axios实例或者封装后的请求方法来发送请求。 36. keep-alive/keep-alive 的作用是什么 主要是用于需要频繁切换的组件时 进行缓存不需要重新渲染页面 比如当你勾选了某一选项或填写了数据切换页面时数据不会消失 37. ## vue和react的区别 开发语言vue使用模板语法采用基于模板的开发方式而react使用JSX语法将组件的结构和逻辑写在JSX中采用更多的JS开发方式。学习曲线相对而言vue的学习曲线较为平缓上手相对容易尤其适合前端初学者而react的学习曲线较为陡峭需要更深入地理解JS和函数式编程的概念。生态系统react拥有更丰富和庞大的生态系统包括redux、react router等成熟的解决方案和插件。vue的生态系统虽然较为年轻但也逐渐发展壮大。社区支持react具有庞大的社区支持有很多活跃的开发者和社区贡献者能够提供丰富的资源和支持vue虽然社区规模相对较小但也有一批活跃的贡献者和社区活动也能够提供良好的支持。双向数据绑定vue具有直接的双向数据绑定视图更新时会自动同步数据的变化react则采用了单项数据流的原则数据通过props和state进行子组件向父组件的传递。组件化开发vue和react都支持组件化开发但vue更灵活多数情况下可以使用vue的选项对象来定义组件而react中的组件开发更加基于JS的类组件和函数式组件。 38. vue全家桶 vue-cli、vuex、vueRouter、Axios 39. vue-cli 工程常用的 npm 命令有哪些? npm install 下载 node_modules 资源包的命令 npm run dev 启动 vue-cli 开发环境的 npm 命令 npm run build vue-cli 生成 生产环境部署资源 的 npm 命令 npm run build–report 用于查看 vue-cli 生产环境部署资源文件大小的 npm 命令 40. 请说出 vue-cli 工程中每个文件夹和文件的用处? build 文件夹是保存一些 webpack 的初始化配置。 config 文件夹保存一些项目初始化的配置 node_modules 是 npm 加载的项目依赖的模块 src 目录是我们要开发的目录: assets 用来放置图片 components 用来放组件文件 app.vue 是项目入口文件 main.js 项目的核心文件 41. vue 常用的修饰符? 事件修饰符 .stop 阻止事件继续传播 .prevent 阻止标签默认行为 .capture 使用事件捕获模式即元素自身触发的事件先在此处处理然后才交由内部元素进行处理 .self 只当在 event.target 是当前元素自身时触发处理函数 .once 事件只会触发一次 .passive 告诉浏览器你不想阻止事件的默认行为v-model 的修饰符 .lazy 通过这个修饰符转变为在 change 事件再同步 .number 自动将用户输入值转化为数值类型 .trim 自动过滤用户输入的收尾空格键盘事件修饰符 .enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right系统修饰符 .ctrl .alt .shift .meta鼠标按钮修饰符 .left .right .middle 43. vue 事件中如何使用 event 对象? 获取事件对象方法参数传递 $event 。注意在事件中要使用 $ 符号 button clickEvent($event)事件对象/button 44. vue 中子组件调用父组件的方法? 直接在子组件中通过 this.$parent.event 来调用父组件的方法。 在子组件里用$emit()向父组件触发一个事件父组件监听这个事件就行了。 父组件把方法传入子组件中在子组件里直接调用这个方法。 45. vue路由跳转 (一)声明式导航router-link 不带参数 // 注意router-link中链接如果是/开始就是从根路由开始如果开始不带/则从当前路由开始。 router-link :to{name:home} router-link :to{path:/home} //name,path都行, 建议用name 带参数 router-link :to{name:home, params: {id:1}} router-link :to{name:home, query: {id:1}} router-link :to/home/:id //传递对象 router-link :to{name:detail, query: {item:JSON.stringify(obj)}}/router-link (二)this.$router.push() 不带参数 this.$router.push(/home) this.$router.push({name:home}) this.$router.push({path:/home})query传参 1.路由配置 name: home, path: /home 2.跳转 this.$router.push({name:home,query: {id:1}}) this.$router.push({path:/home,query: {id:1}}) 3.获取参数 html取参: $route.query.id script取参: this.$route.query.idparams传参 1.路由配置 name: home, path: /home/:id(或者path: /home:id) 2.跳转 this.$router.push({name:home,params: {id:1}}) 注意 // 只能用 name匹配路由不能用path // params传参数(类似post) 路由配置 path: /home/:id 或者 path: /home:id否则刷新参数消失 3.获取参数 html取参:$route.params.id script取参:this.$route.params.id 直接通过path传参 1.路由配置 name: home, path: /home/:id 2.跳转 this.$router.push({path:/home/123}) 或者 this.$router.push(/home/123) 3.获取参数 this.$route.params.idparams和query的区别 query类似 get跳转之后页面 url后面会拼接参数类似?id1。 非重要性的可以这样传密码之类还是用params刷新页面id还在。 params类似 post跳转之后页面 url后面不会拼接参数。 (三)this.$router.replace() 用法同上 (四)this.$router.go(n) 向前或者向后跳转n个页面n可为正整数或负整数 区别: this.$router.push 跳转到指定url路径并在history栈中添加一个记录点击后退会返回到上一个页面 this.$router.replace 跳转到指定url路径但是history栈中不会有记录点击返回会跳转到上上个页面 (就是直接替换了当前页面) this.$router.go(n) 向前或者向后跳转n个页面n可为正整数或负整数 46. Vue.js 双向绑定的原理 Vue.js 2.0 采用数据劫持Proxy 模式结合发布者-订阅者模式PubSub 模式的方式通过 Object.defineProperty()来劫持各个属性的 settergetter在数据变动时发布消息给订阅者触发相应的监听回调。 每个组件实例都有相应的watcher程序实例它会在组件渲染的过程中把属性记录为依赖之后当依赖项的setter被调用时会通知watcher重新计算从而致使它关联的组件得以更新。 Vue.js 3.0, 放弃了Object.defineProperty 使用更快的ES6原生 Proxy (访问对象拦截器, 也称代理器) 47. 过滤器 (Filter) 在Vue中使用filters来过滤(格式化)数据filters不会修改数据而是过滤(格式化)数据改变用户看到的输出计算属性 computed 方法 methods 都是通过修改数据来处理数据格式的输出显示。 使用场景 比如需要处理时间、数字等的的显示格式 48. Vue.js页面闪烁 Vue. js提供了一个v-cloak指令该指令一直保持在元素上直到关联实例结束编译。当和CSS一起使用时这个指令可以隐藏未编译的标签直到实例编译结束。用法如下。 [v-cloak]{ display:none; } div v-cloak{{ title }}/div 49. 如何解决数据层级结构太深的问题 在开发业务时经常会岀现异步获取数据的情况有时数据层次比较深如以下代码: span v-texta.b.c.d, 可以使用vm.$set手动定义一层数据: vm.$set(demoa.b.c.d) 50. $route和$router的区别 $route是“路由信息对象”包括pathparamshashqueryfullPathmatchedname等路由信息参数。 $router是“路由实例”对象包括了路由的跳转方法钩子函数等 51. 怎样理解 Vue 的单项数据流 数据总是从父组件传到子组件子组件没有权利修改父组件传过来的数据只能请求父组件对原始数据进行修改。这样会防止从子组件意外改变父组件的状态从而导致你的应用的数据流向难以理解。 注意在子组件直接用 v-model 绑定父组件传过来的 props 这样是不规范的写法开发环境会报警告。 如果实在要改变父组件的 props 值可以再data里面定义一个变量并用 prop 的值初始化它之后用$emit 通知父组件去修改。 52. 虚拟DOM是什么有什么优缺点 由于在浏览器中操作DOM是很昂贵的。频繁操作DOM会产生一定性能问题。这就是虚拟Dom的产生原因。Vue2的Virtual DOM 借鉴了开源库 snabbdom 的实现。Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点是对真实DOM的一层抽象。 优点 1、保证性能下限框架的虚拟DOM需要适配任何上层API可能产生的操作他的一些DOM操作的实现必须是普适的所以它的性能并不是最优的但是比起粗暴的DOM操作性能要好很多因此框架的虚拟DOM至少可以保证在你不需要手动优化的情况下依然可以提供还不错的性能既保证性能的下限。 2、无需手动操作DOM我们不需手动去操作DOM只需要写好 View-Model的 代码逻辑框架会根据虚拟DOM和数据双向绑定帮我们以可预期的方式更新视图极大提高我们的开发效率。 3、跨平台虚拟DOM本质上是JavaScript对象而DOM与平台强相关相比之下虚拟DOM可以进行更方便地跨平台操作例如服务器端渲染、weex开发等等。 缺点 1、无法进行极致优化虽然虚拟DOM 合理的优化足以应对大部分应用的性能需要但在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化。 2、首次渲染大量DOM时由于多了一层DOM计算会比innerHTML插入慢。 53. Vuex 页面刷新数据丢失怎么解决 需要做 vuex 数据持久化一般使用本地储存的方案来保存数据可以自己设计存储方案也可以使用第三方插件。 推荐使用 vuex-persist (脯肉赛斯特)插件它是为 Vuex 持久化储存而生的一个插件。不需要你手动存取 storage而是直接将状态保存至 cookie 或者 localStorage中。 54. Vuex 为什么要分模块并且加命名空间 模块 由于使用单一状态树应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时store 对象就有可能会变得相当臃肿。为了解决以上问题Vuex 允许我们将 store 分割成模块module。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。 命名空间 默认情况下模块内部的 action、mutation、getter是注册在全局命名空间的 — 这样使得多个模块能够对同一 mutation 或 action 做出响应。如果希望你的模块具有更高的封装度和复用性你可以通过添加 namespaced:true 的方式使其成为带命名的模块。当模块被注册后他所有 getter、action、及 mutation 都会自动根据模块注册的路径调整命名。 55. 你都做过哪些 Vue 的性能优化 这里只列举针对 Vue 的性能优化整个项目的性能优化是一个大工程。 对象层级不要过深否则性能就会差。 不需要响应式的数据不要放在 data 中可以使用 Object.freeze() 冻结数据 v-if 和 v-show 区分使用场景 computed 和 watch 区分场景使用 v-for 遍历必须加 keykey最好是id值且避免同时使用 v-if 大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格 防止内部泄露组件销毁后把全局变量和时间销毁 图片懒加载 路由懒加载 异步路由 第三方插件的按需加载 适当采用 keep-alive 缓存组件 防抖、节流的运用 服务端渲染 SSR or 预渲染 56. Vue.set 方法原理 在两种情况下修改 Vue 是不会触发视图更新的。 1、在实例创建之后添加新的属性到实例上给响应式对象新增属性 2、直接更改数组下标来修改数组的值。 Vue.set 或者说是 $set 原理如下 因为响应式数据 我们给对象和数组本身新增了__ob__属性代表的是 Observer 实例。当给对象新增不存在的属性首先会把新的属性进行响应式跟踪 然后会触发对象 ob 的dep收集到的 watcher 去更新当修改数组索引时我们调用数组本身的 splice 方法去更新数组。 57. 函数式组件使用场景和原理 函数式组件与普通组件的区别 1、函数式组件需要在声明组件时指定 functional:true 2、不需要实例化所以没有thisthis通过render函数的第二个参数context代替 3、没有生命周期钩子函数不能使用计算属性watch 4、不能通过$emit对外暴露事件调用事件只能通过context.listeners.click的方式调用外部传入的事件 5、因为函数组件时没有实例化的所以在外部通过ref去引用组件时实际引用的是HTMLElement 6、函数式组件的props可以不用显示声明所以没有在props里面声明的属性都会被自动隐式解析为prop而普通的组件所有未声明的属性都解析到$attrs里面并自动挂载到组件根元素上可以通过inheritAttrs属性禁止 优点1.由于函数组件不需要实例化无状态没有生命周期所以渲染性要好于普通组件2.函数组件结构比较简单代码结构更清晰 使用场景 一个简单的展示组件作为容器组件使用 比如 router-view 就是一个函数式组件。 “高阶组件”—用于接受一个组件为参数返回一个被包装过的组件。 相关代码如下 if (isTrue(Ctor.options.functional)) { // 带有functional的属性的就是函数式组件 return createFunctionalComponent(Ctor, propsData, data, context, children); } const listeners data.on; data.on data.nativeOn; installComponentHooks(data); // 安装组件相关钩子 函数式组件没有调用此方法从而性能高于普通组件 58. 子组件为何不可以修改父组件传递的 Prop 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定父级 prop 的更新会向下流动到子组件中但是反过来则不行。这样会防止从子组件意外改变父级组件的状态从而导致你的应用的数据流向难以理解。