当前位置: 首页 > news >正文

网站ico图标怎么用企业网页界面设计

网站ico图标怎么用,企业网页界面设计,网站做app的重要性,旅游模板网站大家好#xff0c;我是若川。持续组织了8个月源码共读活动#xff0c;感兴趣的可以 点此加我微信ruochuan12 参与#xff0c;每周大家一起学习200行左右的源码#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外… 大家好我是若川。持续组织了8个月源码共读活动感兴趣的可以 点此加我微信ruochuan12 参与每周大家一起学习200行左右的源码共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外目前建有江西|湖南|湖北籍前端群可加我微信进群。前言大家好我是村长一个爱分享的老前端。前一段时间有很多小伙伴找我做经典Vue面试题解析。我整整花了1个月时间找题写答案录视频。本来打算全部写完再来发一篇鸿篇巨制不过找我要学习材料的太多只好提前发布。这里是已经写完的前半部分大家务必点赞、收藏保存一下我后续还在这一篇更新下半部分希望大家多多支持村长。相关学习资源本系列有配套视频教程思维导图和开源项目大家学习同时千万不要忘了三连 关注 分享视频教程【Vue面试专题】金三银四必备56道经典Vue面试题详思维导图Vue面试专题配套代码vue-interview01-Vue组件之间通信方式有哪些vue是组件化开发框架所以对于vue应用来说组件间的数据通信非常重要。此题主要考查大家vue基本功对于vue基础api运用熟练度。另外一些边界知识如provide/inject/$attrs则提现了面试者的知识广度。组件传参的各种方式思路分析总述知道的所有方式按组件关系阐述使用场景回答范例组件通信常用方式有以下8种props$emit/$on$children/$parent$attrs/$listenersref$rooteventbusvuex注意vue3中废弃的几个APIhttps://v3-migration.vuejs.org/breaking-changes/children.htmlhttps://v3-migration.vuejs.org/breaking-changes/listeners-removed.htmlhttps://v3-migration.vuejs.org/breaking-changes/events-api.html#overview根据组件之间关系讨论组件通信最为清晰有效父子组件props/$emit/$parent/ref/$attrs兄弟组件$parent/$root/eventbus/vuex跨层级关系eventbus/vuex/provideinject02-v-if和v-for哪个优先级更高分析此题考查常识文档中曾有详细说明v2|v3也是一个很好的实践题目项目中经常会遇到能够看出面试者api熟悉程度和应用能力。思路分析先给出结论为什么是这样的说出细节哪些场景可能导致我们这样做该怎么处理总结拔高回答范例实践中不应该把v-for和v-if放一起在vue2中v-for的优先级是高于v-if把它们放在一起输出的渲染函数中可以看出会先执行循环再判断条件哪怕我们只渲染列表中一小部分元素也得在每次重渲染的时候遍历整个列表这会比较浪费另外需要注意的是在vue3中则完全相反v-if的优先级高于v-for所以v-if执行时它调用的变量还不存在就会导致异常通常有两种情况下导致我们这样做为了过滤列表中的项目 (比如 v-foruser in users v-ifuser.isActive)。此时定义一个计算属性 (比如 activeUsers)让其返回过滤后的列表即可比如users.filter(uu.isActive)。为了避免渲染本应该被隐藏的列表 (比如 v-foruser in users v-ifshouldShowUsers)。此时把 v-if 移动至容器元素上 (比如 ul、ol)或者外面包一层template即可。文档中明确指出永远不要把 v-if 和 v-for 同时用在同一个元素上显然这是一个重要的注意事项。源码里面关于代码生成的部分能够清晰的看到是先处理v-if还是v-for顺序上vue2和vue3正好相反因此产生了一些症状的不同但是不管怎样都是不能把它们写在一起的。知其所以然做个测试test.html两者同级时渲染函数如下ƒ anonymous( ) { with(this){return _c(div,{attrs:{id:app}},_l((items),function(item){return (item.isActive)?_c(div,{key:item.id},[_v(\n      _s(item.name)\n    )]):_e()}),0)} }做个测试test-v3.htmlimage-20220210104854185源码中找答案v2https://github1s.com/vuejs/vue/blob/HEAD/src/compiler/codegen/index.js#L65-L66v3https://github1s.com/vuejs/core/blob/HEAD/packages/compiler-core/src/codegen.ts#L586-L58703-简述 Vue 的生命周期以及每个阶段做的事必问题目考查vue基础知识。思路给出概念列举生命周期各阶段阐述整体流程结合实践扩展vue3变化回答范例1.每个Vue组件实例被创建后都会经过一系列初始化步骤比如它需要数据观测模板编译挂载实例到dom上以及数据变化时更新dom。这个过程中会运行叫做生命周期钩子的函数以便用户在特定阶段有机会添加他们自己的代码。2.Vue生命周期总共可以分为8个阶段创建前后, 载入前后, 更新前后, 销毁前后以及一些特殊场景的生命周期。vue3中新增了三个用于调试和服务端渲染场景。生命周期v2生命周期v3描述beforeCreatebeforeCreate组件实例被创建之初createdcreated组件实例已经完全创建beforeMountbeforeMount组件挂载之前mountedmounted组件挂载到实例上去之后beforeUpdatebeforeUpdate组件数据发生变化更新之前updatedupdated数据数据更新之后beforeDestroybeforeUnmount组件实例销毁之前destroyedunmounted组件实例销毁之后生命周期v2生命周期v3描述activatedactivatedkeep-alive 缓存的组件激活时deactivateddeactivatedkeep-alive 缓存的组件停用时调用errorCapturederrorCaptured捕获一个来自子孙组件的错误时被调用-renderTracked调试钩子响应式依赖被收集时调用-renderTriggered调试钩子响应式依赖被触发时调用-serverPrefetchssr only组件实例在服务器上被渲染前调用3.Vue生命周期流程图Component lifecycle diagram4.结合实践beforeCreate通常用于插件开发中执行一些初始化任务created组件初始化完毕可以访问各种数据获取接口数据等mounteddom已创建可用于获取访问数据和dom元素访问子组件等。beforeUpdate此时view层还未更新可用于获取更新前各种状态updated完成view层的更新更新后所有状态已是最新beforeunmount实例被销毁前调用可用于一些定时器或订阅的取消unmounted销毁一个实例。可清理它与其它实例的连接解绑它的全部指令及事件监听器可能的追问setup和created谁先执行setup中为什么没有beforeCreate和created知其所以然vue3中生命周期的派发时刻https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/componentOptions.ts#L554-L555vue2中声明周期的派发时刻https://github1s.com/vuejs/vue/blob/HEAD/src/core/instance/init.js#L55-L5604-能说一说双向绑定使用和原理吗题目分析双向绑定是vue的特色之一开发中必然会用到的知识点然而此题还问了实现原理升级为深度考查。思路分析给出双绑定义双绑带来的好处在哪使用双绑使用方式、使用细节、vue3变化原理实现描述回答范例vue中双向绑定是一个指令v-model可以绑定一个响应式数据到视图同时视图中变化能改变该值。v-model是语法糖默认情况下相当于:value和input。使用v-model可以减少大量繁琐的事件处理代码提高开发效率。通常在表单项上使用v-model还可以在自定义组件上使用表示某个值的输入和输出控制。通过input v-modelxxx的方式将xxx的值绑定到表单元素value上对于checkbox可以使用true-value和false-value指定特殊的值对于radio可以使用value指定特殊的值对于select可以通过options元素的value设置特殊的值还可以结合.lazy,.number,.trim对v-mode的行为做进一步限定v-model用在自定义组件上时又会有很大不同vue3中它类似于sync修饰符最终展开的结果是modelValue属性和update:modelValue事件vue3中我们甚至可以用参数形式指定多个不同的绑定例如v-model:foo和v-model:bar非常强大v-model是一个指令它的神奇魔法实际上是vue的编译器完成的。我做过测试包含v-model的模板转换为渲染函数之后实际上还是是value属性的绑定以及input事件监听事件回调函数中会做相应变量更新操作。编译器根据表单元素的不同会展开不同的DOM属性和事件对比如text类型的input和textarea会展开为value和input事件checkbox和radio类型的input会展开为checked和change事件select用value作为属性用change作为事件。可能的追问v-model和sync修饰符有什么区别自定义组件使用v-model如果想要改变事件名或者属性名应该怎么做知其所以然测试代码test.html观察输出的渲染函数// input typetext v-modelfoo _c(input, { directives: [{ name: model, rawName: v-model, value: (foo), expression: foo }], attrs: { type: text }, domProps: { value: (foo) }, on: { input: function ($event) { if ($event.target.composing) return; foo  $event.target.value } }  })// input typecheckbox v-modelbar _c(input, { directives: [{ name: model, rawName: v-model, value: (bar), expression: bar }], attrs: { type: checkbox }, domProps: { checked: Array.isArray(bar) ? _i(bar, null)  -1 : (bar) }, on: { change: function ($event) { var $$a  bar, $$el  $event.target, $$c  $$el.checked ? (true) : (false); if (Array.isArray($$a)) { var $$v  null, $$i  _i($$a, $$v); if ($$el.checked) { $$i  0  (bar  $$a.concat([$$v])) } else { $$i  -1  (bar  $$a.slice(0, $$i).concat($$a.slice($$i  1))) } } else { bar  $$c } } }  })// select v-modelbaz //     option valuevuevue/option //     option valuereactreact/option // /select _c(select, { directives: [{ name: model, rawName: v-model, value: (baz), expression: baz }], on: { change: function ($event) { var $$selectedVal  Array.prototype.filter.call($event.target.options, function (o) { return o.selected }).map(function (o) { var val  _value in o ? o._value : o.value; return val }); baz  $event.target.multiple ? $$selectedVal : $$selectedVal[0] } }  }, [_c(option, { attrs: { value: vue } }, [_v(vue)]), _v( ), _c(option, { attrs: { value: react } }, [_v(react)]) ])05-Vue中如何扩展一个组件此题属于实践题考察大家对vue常用api使用熟练度答题时不仅要列出这些解决方案同时最好说出他们异同。答题思路按照逻辑扩展和内容扩展来列举逻辑扩展有mixins、extends、composition api内容扩展有slots分别说出他们使用方法、场景差异和问题。作为扩展还可以说说vue3中新引入的composition api带来的变化回答范例常见的组件扩展方法有mixinsslotsextends等混入mixins是分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时所有混入对象的选项将被混入该组件本身的选项。// 复用代码它是一个配置对象选项和组件里面一样 const mymixin  {methods: {dosomething(){}} } // 全局混入将混入对象传入 Vue.mixin(mymixin)// 局部混入做数组项设置到mixins选项仅作用于当前组件 const Comp  {mixins: [mymixin] }插槽主要用于vue组件中的内容分发也可以用于组件扩展。子组件Childdivslot这个内容会被父组件传递的内容替换/slot /div父组件ParentdivChild来自老爹的内容/Child /div如果要精确分发到不同位置可以使用具名插槽如果要使用子组件中的数据可以使用作用域插槽。组件选项中还有一个不太常用的选项extends也可以起到扩展组件的目的// 扩展对象 const myextends  {methods: {dosomething(){}} } // 组件扩展做数组项设置到extends选项仅作用于当前组件 // 跟混入的不同是它只能扩展单个对象 // 另外如果和混入发生冲突该选项优先级较高优先起作用 const Comp  {extends: myextends }混入的数据和方法不能明确判断来源且可能和当前组件内变量产生命名冲突vue3中引入的composition api可以很好解决这些问题利用独立出来的响应式模块可以很方便的编写独立逻辑并提供响应式的数据然后在setup选项中组合使用增强代码的可读性和维护性。例如// 复用逻辑1 function useXX() {} // 复用逻辑2 function useYY() {} // 逻辑组合 const Comp  {setup() {const {xx}  useXX()const {yy}  useYY()return {xx, yy}} }可能的追问Vue.extend方法你用过吗它能用来做组件扩展吗知其所以然mixins原理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/apiCreateApp.ts#L232-L233https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/componentOptions.ts#L545slots原理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/componentSlots.ts#L129-L130https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1373-L1374https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/helpers/renderSlot.ts#L23-L2406-子组件可以直接改变父组件的数据么说明原因分析这是一个实践知识点组件化开发过程中有个单项数据流原则不在子组件中修改父组件是个常识问题。参考文档https://staging.vuejs.org/guide/components/props.html#one-way-data-flow思路讲讲单项数据流原则表明为何不能这么做举几个常见场景的例子说说解决方案结合实践讲讲如果需要修改父组件状态应该如何做回答范例所有的 prop 都使得其父子之间形成了一个单向下行绑定父级 prop 的更新会向下流动到子组件中但是反过来则不行。这样会防止从子组件意外变更父级组件的状态从而导致你的应用的数据流向难以理解。另外每次父级组件发生变更时子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了Vue 会在浏览器控制台中发出警告。const props  defineProps([foo]) // ❌ 下面行为会被警告, props是只读的! props.foo  bar实际开发过程中有两个场景会想要修改一个属性这个 prop 用来传递一个初始值这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下最好定义一个本地的 data并将这个 prop 用作其初始值const props  defineProps([initialCounter]) const counter  ref(props.initialCounter)这个 prop 以一种原始的值传入且需要进行转换。在这种情况下最好使用这个 prop 的值来定义一个计算属性const props  defineProps([size]) // prop变化计算属性自动更新 const normalizedSize  computed(()  props.size.trim().toLowerCase())实践中如果确实想要改变父组件属性应该emit一个事件让父组件去做这个变更。注意虽然我们不能直接修改一个传入的对象或者数组类型的prop但是我们还是能够直接改内嵌的对象或属性。07-Vue要做权限管理该怎么做控制到按钮级别的权限怎么做分析综合实践题目实际开发中经常需要面临权限管理的需求考查实际应用能力。权限管理一般需求是两个页面权限和按钮权限从这两个方面论述即可。思路权限管理需求分析页面和按钮权限权限管理的实现方案分后端方案和前端方案阐述说说各自的优缺点回答范例权限管理一般需求是页面权限和按钮权限的管理具体实现的时候分后端和前端两种方案前端方案会把所有路由信息在前端配置通过路由守卫要求用户登录用户登录后根据角色过滤出路由表。比如我会配置一个asyncRoutes数组需要认证的页面在其路由的meta中添加一个roles字段等获取用户角色之后取两者的交集若结果不为空则说明可以访问。此过滤过程结束剩下的路由就是该用户能访问的页面最后通过router.addRoutes(accessRoutes)方式动态添加路由即可。后端方案会把所有页面路由信息存在数据库中用户登录的时候根据其角色查询得到其能访问的所有页面路由信息返回给前端前端再通过addRoutes动态添加路由信息按钮权限的控制通常会实现一个指令例如v-permission将按钮要求角色通过值传给v-permission指令在指令的moutned钩子中可以判断当前用户角色和按钮是否存在交集有则保留按钮无则移除按钮。纯前端方案的优点是实现简单不需要额外权限管理页面但是维护起来问题比较大有新的页面和角色需求就要修改前端代码重新打包部署服务端方案就不存在这个问题通过专门的角色和权限管理页面配置页面和按钮权限信息到数据库应用每次登陆时获取的都是最新的路由信息可谓一劳永逸知其所以然路由守卫https://github1s.com/PanJiaChen/vue-element-admin/blob/HEAD/src/permission.js#L13-L14路由生成https://github1s.com/PanJiaChen/vue-element-admin/blob/HEAD/src/store/modules/permission.js#L50-L51动态追加路由https://github1s.com/PanJiaChen/vue-element-admin/blob/HEAD/src/permission.js#L43-L44可能的追问类似Tabs这类组件能不能使用v-permission指令实现按钮权限控制el-tabs el-tab-pane label⽤户管理 namefirst⽤户管理/el-tab-pane el-tab-pane label⻆⾊管理 namethird⻆⾊管理/el-tab-pane /el-tabs服务端返回的路由信息如何添加到路由器中// 前端组件名和组件映射表 const map  {//xx: require(/views/xx.vue).default // 同步的⽅式xx: ()  import(/views/xx.vue) // 异步的⽅式 } // 服务端返回的asyncRoutes const asyncRoutes  [{ path: /xx, component: xx,... } ] // 遍历asyncRoutes将component替换为map[component] function mapComponent(asyncRoutes) {asyncRoutes.forEach(route  {route.component  map[route.component];if(route.children) {route.children.map(child  mapComponent(child))}}) } mapComponent(asyncRoutes)08 - 说一说你对vue响应式理解分析这是一道必问题目但能回答到位的比较少。如果只是看看一些网文通常没什么底气经不住面试官推敲但像我们这样即看过源码还造过轮子的回答这个问题就会比较有底气啦。答题思路啥是响应式为什么vue需要响应式它能给我们带来什么好处vue的响应式是怎么实现的有哪些优缺点vue3中的响应式的新变化回答范例所谓数据响应式就是能够使数据变化可以被检测并对这种变化做出响应的机制。MVVM框架中要解决的一个核心问题是连接数据层和视图层通过数据驱动应用数据变化视图更新要做到这点的就需要对数据做响应式处理这样一旦数据发生变化就可以立即做出更新处理。以vue为例说明通过数据响应式加上虚拟DOM和patch算法开发人员只需要操作数据关心业务完全不用接触繁琐的DOM操作从而大大提升开发效率降低开发难度。vue2中的数据响应式会根据数据类型来做不同处理如果是对象则采用Object.defineProperty()的方式定义数据拦截当数据被访问或发生变化时我们感知并作出响应如果是数组则通过覆盖数组对象原型的7个变更方法使这些方法可以额外的做更新通知从而作出响应。这种机制很好的解决了数据响应化的问题但在实际使用中也存在一些缺点比如初始化时的递归遍历会造成性能损失新增或删除属性时需要用户使用Vue.set/delete这样特殊的api才能生效对于es6中新产生的Map、Set这些数据结构不支持等问题。为了解决这些问题vue3重新编写了这一部分的实现利用ES6的Proxy代理要响应化的数据它有很多好处编程体验是一致的不需要使用特殊api初始化性能和内存消耗都得到了大幅改善另外由于响应化的实现代码抽取为独立的reactivity包使得我们可以更灵活的使用它第三方的扩展开发起来更加灵活了。知其所以然vue2响应式https://github1s.com/vuejs/vue/blob/HEAD/src/core/observer/index.js#L135-L136vue3响应式https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/reactive.ts#L89-L90https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/ref.ts#L67-L6809 - 说说你对虚拟 DOM 的理解分析现有框架几乎都引入了虚拟 DOM 来对真实 DOM 进行抽象也就是现在大家所熟知的 VNode 和 VDOM那么为什么需要引入虚拟 DOM 呢围绕这个疑问来解答即可思路vdom是什么引入vdom的好处vdom如何生成又如何成为dom在后续的diff中的作用回答范例虚拟dom顾名思义就是虚拟的dom对象它本身就是一个 JavaScript 对象只不过它是通过不同的属性去描述一个视图结构。通过引入vdom我们可以获得如下好处将真实元素节点抽象成 VNode有效减少直接操作 dom 次数从而提高程序性能方便实现跨平台同一 VNode 节点可以渲染成不同平台上的对应的内容比如渲染在浏览器是 dom 元素节点渲染在 Native( iOS、Android) 变为对应的控件、可以实现 SSR 、渲染到 WebGL 中等等Vue3 中允许开发者基于 VNode 实现自定义渲染器renderer以便于针对不同平台进行渲染。直接操作 dom 是有限制的比如diff、clone 等操作一个真实元素上有许多的内容如果直接对其进行 diff 操作会去额外 diff 一些没有必要的内容同样的如果需要进行 clone 那么需要将其全部内容进行复制这也是没必要的。但是如果将这些操作转移到 JavaScript 对象上那么就会变得简单了。操作 dom 是比较昂贵的操作频繁的dom操作容易引起页面的重绘和回流但是通过抽象 VNode 进行中间处理可以有效减少直接操作dom的次数从而减少页面重绘和回流。vdom如何生成在vue中我们常常会为组件编写模板 - template 这个模板会被编译器 - compiler编译为渲染函数在接下来的挂载mount过程中会调用render函数返回的对象就是虚拟dom。但它们还不是真正的dom所以会在后续的patch过程中进一步转化为dom。image-20220209153820845挂载过程结束后vue程序进入更新流程。如果某些响应式数据发生变化将会引起组件重新render此时就会生成新的vdom和上一次的渲染结果diff就能得到变化的地方从而转换为最小量的dom操作高效更新视图。知其所以然vnode定义https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/vnode.ts#L127-L128观察渲染函数21-vdom/test-render-v3.html创建vnodecreateElementBlock:https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/vnode.ts#L291-L292createVnode:https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/vnode.ts#L486-L487首次调用时刻https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/apiCreateApp.ts#L283-L284mount:https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1171-L1172调试mount过程mountComponent21-vdom/test-render-v3.html10 - 你了解diff算法吗分析必问题目涉及vue更新原理比较考查理解深度。思路diff算法是干什么的它的必要性它何时执行具体执行方式拔高说一下vue3中的优化回答范例1.Vue中的diff算法称为patching算法它由Snabbdom修改而来虚拟DOM要想转化为真实DOM就需要通过patch方法转换。2.最初Vue1.x视图中每个依赖均有更新函数对应可以做到精准更新因此并不需要虚拟DOM和patching算法支持但是这样粒度过细导致Vue1.x无法承载较大应用Vue 2.x中为了降低Watcher粒度每个组件只有一个Watcher与之对应此时就需要引入patching算法才能精确找到发生变化的地方并高效更新。3.vue中diff执行的时刻是组件内响应式数据变更触发实例执行其更新函数时更新函数会再次执行render函数获得最新的虚拟DOM然后执行patch函数并传入新旧两次虚拟DOM通过比对两者找到变化的地方最后将其转化为对应的DOM操作。4.patch过程是一个递归过程遵循深度优先、同层比较的策略以vue3的patch为例首先判断两个节点是否为相同同类节点不同则删除重新创建如果双方都是文本则更新文本内容如果双方都是元素节点则递归更新子元素同时更新元素属性更新子节点时又分了几种情况新的子节点是文本老的子节点是数组则清空并设置文本新的子节点是文本老的子节点是文本则直接更新文本新的子节点是数组老的子节点是文本则清空文本并创建新子节点数组中的子元素新的子节点是数组老的子节点也是数组那么比较两组子节点更新细节blablavue3中引入的更新策略编译期优化patchFlags、block等知其所以然patch关键代码https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L354-L355调试 test-v3.html11 - 你知道哪些vue3新特性分析官网列举的最值得注意的新特性https://v3-migration.vuejs.org/image-20220210165307624也就是下面这些Composition APISFC Composition API语法糖Teleport传送门Fragments片段Emits选项自定义渲染器SFC CSS变量Suspense以上这些是api相关另外还有很多框架特性也不能落掉。回答范例api层面Vue3新特性主要包括Composition API、SFC Composition API语法糖、Teleport传送门、Fragments 片段、Emits选项、自定义渲染器、SFC CSS变量、Suspense另外Vue3.0在框架层面也有很多亮眼的改进更快虚拟DOM重写编译器优化静态提升、patchFlags、block等基于Proxy的响应式系统更小更好的摇树优化更容易维护TypeScript 模块化更容易扩展独立的响应化模块自定义渲染器知其所以然体验编译器优化https://sfc.vuejs.org/reactive实现https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/reactive.ts#L90-L9112 - 怎么定义动态路由怎么获取传过来的动态参数分析API题目考查基础能力不容有失尽可能说的详细。思路什么是动态路由什么时候使用动态路由怎么定义动态路由参数如何获取细节、注意事项回答范例很多时候我们需要将给定匹配模式的路由映射到同一个组件这种情况就需要定义动态路由。例如我们可能有一个 User 组件它应该对所有用户进行渲染但用户 ID 不同。在 Vue Router 中我们可以在路径中使用一个动态字段来实现例如{ path: /users/:id, component: User }其中:id就是路径参数路径参数 用冒号 : 表示。当一个路由被匹配时它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。参数还可以有多个例如/users/:username/posts/:postId除了 $route.params 之外$route 对象还公开了其他有用的信息如 $route.query、$route.hash 等。可能的追问如何响应动态路由参数的变化https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E5%93%8D%E5%BA%94%E8%B7%AF%E7%94%B1%E5%8F%82%E6%95%B0%E7%9A%84%E5%8F%98%E5%8C%96我们如何处理404 Not Found路由https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E6%8D%95%E8%8E%B7%E6%89%80%E6%9C%89%E8%B7%AF%E7%94%B1%E6%88%96-404-not-found-%E8%B7%AF%E7%94%B113-如果让你从零开始写一个vue路由说说你的思路思路分析首先思考vue路由要解决的问题用户点击跳转链接内容切换页面不刷新。借助hash或者history api实现url跳转页面不刷新同时监听hashchange事件或者popstate事件处理跳转根据hash值或者state值从routes表中匹配对应component并渲染之回答范例一个SPA应用的路由需要解决的问题是页面跳转内容改变同时不刷新同时路由还需要以插件形式存在所以首先我会定义一个createRouter函数返回路由器实例实例内部做几件事保存用户传入的配置项监听hash或者popstate事件回调里根据path匹配对应路由将router定义成一个Vue插件即实现install方法内部做两件事实现两个全局组件router-link和router-view分别实现页面跳转和内容显示定义两个全局变量和router组件内可以访问当前路由和路由器实例知其所以然createRouter如何创建实例https://github1s.com/vuejs/router/blob/HEAD/src/router.ts#L355-L356事件监听https://github1s.com/vuejs/router/blob/HEAD/src/history/html5.ts#L314-L315 RouterView页面跳转RouterLinkhttps://github1s.com/vuejs/router/blob/HEAD/src/RouterLink.ts#L184-L185内容显示RouterViewhttps://github1s.com/vuejs/router/blob/HEAD/src/RouterView.ts#L43-L4414-能说说key的作用吗分析这是一道特别常见的问题主要考查大家对虚拟DOM和patch细节的掌握程度能够反映面试者理解层次。思路分析给出结论key的作用是用于优化patch性能key的必要性实际使用方式总结可从源码层面描述一下vue如何判断两个节点是否相同回答范例key的作用主要是为了更高效的更新虚拟DOM。vue在patch过程中判断两个节点是否是相同节点是key是一个必要条件渲染一组列表时key往往是唯一标识所以如果不定义key的话vue只能认为比较的两个节点是同一个哪怕它们实际上不是这导致了频繁更新元素使得整个patch过程比较低效影响性能。实际使用中在渲染一组列表时key必须设置而且必须是唯一标识应该避免使用数组索引作为key这可能导致一些隐蔽的bugvue中在使用相同标签元素过渡切换时也会使用key属性其目的也是为了让vue可以区分它们否则vue只会替换其内部属性而不会触发过渡效果。从源码中可以知道vue判断两个节点是否相同时主要判断两者的key和元素类型等因此如果不设置key它的值就是undefined则可能永远认为这是两个相同节点只能去做更新操作这造成了大量的dom更新操作明显是不可取的。知其所以然测试代码test-v3.html上面案例重现的是以下过程不使用key如果使用key// 首次循环patch A A B C D E A B F C D E// 第2次循环patch B B C D E B F C D E// 第3次循环patch E C D E F C D E// 第4次循环patch D C D F C D// 第5次循环patch C C  F C// oldCh全部处理结束newCh中剩下的F创建F并插入到C前面源码中找答案判断是否为相同节点https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/vnode.ts#L342-L343更新时的处理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1752-L1753不使用key如果使用key// 首次循环patch A A B C D E A B F C D E// 第2次循环patch B B C D E B F C D E// 第3次循环patch E C D E F C D E// 第4次循环patch D C D F C D// 第5次循环patch C C  F C// oldCh全部处理结束newCh中剩下的F创建F并插入到C前面源码中找答案判断是否为相同节点https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/vnode.ts#L342-L343更新时的处理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1752-L175315-说说nextTick的使用和原理分析这道题及考察使用有考察原理nextTick在开发过程中应用的也较少原理上和vue异步更新有密切关系对于面试者考查很有区分度如果能够很好回答此题对面试效果有极大帮助。答题思路nextTick是做什么的为什么需要它呢开发时何时使用它抓抓头想想你在平时开发中使用它的地方下面介绍一下如何使用nextTick原理解读结合异步更新和nextTick生效方式会显得你格外优秀回答范例nextTick是等待下一次 DOM 更新刷新的工具方法。Vue有个异步更新策略意思是如果数据变化Vue不会立刻更新DOM而是开启一个队列把组件更新函数保存在队列中在同一事件循环中发生的所有数据变更会异步的批量更新。这一策略导致我们对数据的修改不会立刻体现在DOM上此时如果想要获取更新后的DOM状态就需要使用nextTick。开发时有两个场景我们会用到nextTickcreated中想要获取DOM时响应式数据变化后获取DOM更新后的状态比如希望获取列表更新后的高度。nextTick签名如下function nextTick(callback?: () void): Promisevoid所以我们只需要在传入的回调函数中访问最新DOM状态即可或者我们可以await nextTick()方法返回的Promise之后做这件事。在Vue内部nextTick之所以能够让我们看到DOM更新后的结果是因为我们传入的callback会被添加到队列刷新函数(flushSchedulerQueue)的后面这样等队列内部的更新函数都执行完毕所有DOM操作也就结束了callback自然能够获取到最新的DOM值。知其所以然源码解读:组件更新函数入队https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1547-L1548入队函数https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/scheduler.ts#L84-L85nextTick定义https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/scheduler.ts#L58-L59测试案例test-v3.html16-watch和computed的区别以及选择?两个重要API反应应聘者熟练程度。思路分析先看computed, watch两者定义列举使用上的差异列举使用场景上的差异如何选择使用细节、注意事项vue3变化computed特点具有响应式的返回值const count  ref(1) const plusOne  computed(()  count.value  1)watch特点侦测变化执行回调const state  reactive({ count: 0 }) watch(()  state.count,(count, prevCount)  {/* ... */} )回答范例计算属性可以从组件数据派生出新数据最常见的使用方式是设置一个函数返回计算之后的结果computed和methods的差异是它具备缓存性如果依赖项不变时不会重新计算。侦听器可以侦测某个响应式数据的变化并执行副作用常见用法是传递一个函数执行副作用watch没有返回值但可以执行异步操作等复杂逻辑。计算属性常用场景是简化行内模板中的复杂表达式模板中出现太多逻辑会是模板变得臃肿不易维护。侦听器常用场景是状态变化之后做一些额外的DOM操作或者异步操作。选择采用何用方案时首先看是否需要派生出新值基本能用计算属性实现的方式首选计算属性。使用过程中有一些细节比如计算属性也是可以传递对象成为既可读又可写的计算属性。watch可以传递对象设置deep、immediate等选项。vue3中watch选项发生了一些变化例如不再能侦测一个点操作符之外的字符串形式的表达式reactivity API中新出现了watch、watchEffect可以完全替代目前的watch选项且功能更加强大。回答范例计算属性可以从组件数据派生出新数据最常见的使用方式是设置一个函数返回计算之后的结果computed和methods的差异是它具备缓存性如果依赖项不变时不会重新计算。侦听器可以侦测某个响应式数据的变化并执行副作用常见用法是传递一个函数执行副作用watch没有返回值但可以执行异步操作等复杂逻辑。计算属性常用场景是简化行内模板中的复杂表达式模板中出现太多逻辑会是模板变得臃肿不易维护。侦听器常用场景是状态变化之后做一些额外的DOM操作或者异步操作。选择采用何用方案时首先看是否需要派生出新值基本能用计算属性实现的方式首选计算属性。使用过程中有一些细节比如计算属性也是可以传递对象成为既可读又可写的计算属性。watch可以传递对象设置deep、immediate等选项。vue3中watch选项发生了一些变化例如不再能侦测一个点操作符之外的字符串形式的表达式reactivity API中新出现了watch、watchEffect可以完全替代目前的watch选项且功能更加强大。可能追问watch会不会立即执行watch 和 watchEffect有什么差异知其所以然computed的实现https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/computed.ts#L79-L80ComputedRefImplhttps://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/computed.ts#L26-L27缓存性https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/computed.ts#L59-L60https://github1s.com/vuejs/core/blob/HEAD/packages/reactivity/src/computed.ts#L45-L46watch的实现https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/apiWatch.ts#L158-L15917-说一下 Vue 子组件和父组件创建和挂载顺序这题考查大家对创建过程的理解程度。思路分析给结论阐述理由回答范例创建过程自上而下挂载过程自下而上即parent createdchild createdchild mountedparent mounted之所以会这样是因为Vue创建过程是一个递归过程先创建父组件有子组件就会创建子组件因此创建时先有父组件再有子组件子组件首次创建时会添加mounted钩子到队列等到patch结束再执行它们可见子组件的mounted钩子是先进入到队列中的因此等到patch结束执行这些钩子时也先执行。知其所以然观察beforeCreated和created钩子的处理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/componentOptions.ts#L554-L555https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/componentOptions.ts#L741-L742观察beforeMount和mounted钩子的处理https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L1310-L1311测试代码test-v3.html18-怎么缓存当前的组件缓存后怎么更新缓存组件使用keep-alive组件这是一个非常常见且有用的优化手段vue3中keep-alive有比较大的更新能说的点比较多。思路缓存用keep-alive它的作用与用法使用细节例如缓存指定/排除、结合router和transition组件缓存后更新可以利用activated或者beforeRouteEnter原理阐述回答范例开发中缓存组件使用keep-alive组件keep-alive是vue内置组件keep-alive包裹动态组件component时会缓存不活动的组件实例而不是销毁它们这样在组件切换过程中将状态保留在内存中防止重复渲染DOM。keep-alivecomponent :isview/component /keep-alive结合属性include和exclude可以明确指定缓存哪些组件或排除缓存指定组件。vue3中结合vue-router时变化较大之前是keep-alive包裹router-view现在需要反过来用router-view包裹keep-aliverouter-view v-slot{ Component }keep-alivecomponent :isComponent/component/keep-alive /router-view缓存后如果要获取数据解决方案可以有以下两种beforeRouteEnter在有vue-router的项目每次进入路由的时候都会执行beforeRouteEnterbeforeRouteEnter(to, from, next){next(vm{console.log(vm)// 每次进入路由执行vm.getData()  // 获取数据}) },actived在keep-alive缓存的组件被激活的时候都会执行actived钩子activated(){this.getData() // 获取数据 },keep-alive是一个通用组件它内部定义了一个map缓存创建过的组件实例它返回的渲染函数内部会查找内嵌的component组件对应组件的vnode如果该组件在map中存在就直接返回它。由于component的is属性是个响应式数据因此只要它变化keep-alive的render函数就会重新执行。知其所以然KeepAlive定义https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/components/KeepAlive.ts#L73-L74缓存定义https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/components/KeepAlive.ts#L102-L103缓存组件https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/components/KeepAlive.ts#L215-L216获取缓存组件https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/components/KeepAlive.ts#L241-L242测试缓存特性test-v3.html19-从0到1自己构架一个vue项目说说有哪些步骤、哪些重要插件、目录结构你会怎么组织综合实践类题目考查实战能力。没有什么绝对的正确答案把平时工作的重点有条理的描述一下即可。思路构建项目创建项目基本结构引入必要的插件代码规范prettiereslint提交规范huskylint-staged其他常用svg-loadervueusenprogress常见目录结构回答范例从0创建一个项目我大致会做以下事情项目构建、引入必要插件、代码规范、提交规范、常用库和组件目前vue3项目我会用vite或者create-vue创建项目接下来引入必要插件路由插件vue-router、状态管理vuex/pinia、ui库我比较喜欢element-plus和antd-vue、http工具我会选axios其他比较常用的库有vueusenprogress图标可以使用vite-svg-loader下面是代码规范结合prettier和eslint即可最后是提交规范可以使用huskylint-stagedcommitlint目录结构我有如下习惯.vscode用来放项目中的 vscode 配置plugins用来放 vite 插件的 plugin 配置public用来放一些诸如 页头icon 之类的公共文件会被打包到dist根目录下src用来放项目代码文件api用来放http的一些接口配置assets用来放一些 CSS 之类的静态资源components用来放项目通用组件layout用来放项目的布局router用来放项目的路由配置store用来放状态管理Pinia的配置utils用来放项目中的工具方法类views用来放项目的页面文件20-实际工作中你总结的vue最佳实践有哪些看到这样的题目可以用以下图片来回答思路查看vue官方文档风格指南https://vuejs.org/style-guide/性能https://vuejs.org/guide/best-practices/performance.html#overview安全https://vuejs.org/guide/best-practices/security.html访问性https://vuejs.org/guide/best-practices/accessibility.html发布https://vuejs.org/guide/best-practices/production-deployment.html回答范例我从编码风格、性能、安全等方面说几条编码风格方面命名组件时使用“多词”风格避免和HTML元素冲突使用“细节化”方式定义属性而不是只有一个属性名属性名声明时使用“驼峰命名”模板或jsx中使用“肉串命名”使用v-for时务必加上key且不要跟v-if写在一起性能方面路由懒加载减少应用尺寸利用SSR减少首屏加载时间利用v-once渲染那些不需要更新的内容一些长列表可以利用虚拟滚动技术避免内存过度占用对于深层嵌套对象的大数组可以使用shallowRef或shallowReactive降低开销避免不必要的组件抽象安全不使用不可信模板例如使用用户输入拼接模板template: div userProvidedString /div小心使用v-html:url:style等避免html、url、样式等注入等等......21 - 简单说一说你对vuex理解思路给定义必要性阐述何时使用拓展一些个人思考、实践经验等范例Vuex 是一个专为 Vue.js 应用开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态并以相应的规则保证状态以一种可预测的方式发生变化。我们期待以一种简单的“单向数据流”的方式管理应用即状态 - 视图 - 操作单向循环的方式。但当我们的应用遇到多个组件共享状态时比如多个视图依赖于同一状态或者来自不同视图的行为需要变更同一状态。此时单向数据流的简洁性很容易被破坏。因此我们有必要把组件的共享状态抽取出来以一个全局单例模式管理。通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性我们的代码将会变得更结构化且易维护。这是vuex存在的必要性它和react生态中的redux之类是一个概念。Vuex 解决状态管理的同时引入了不少概念例如state、mutation、action等是否需要引入还需要根据应用的实际情况衡量一下如果不打算开发大型单页应用使用 Vuex 反而是繁琐冗余的一个简单的 store 模式就足够了。但是如果要构建一个中大型单页应用Vuex 基本是标配。我在使用vuex过程中感受到一些blabla可能的追问vuex有什么缺点吗你在开发过程中有遇到什么问题吗action和mutation的区别是什么为什么要区分它们22-说说从 template 到 render 处理过程分析问我们template到render过程其实是问vue编译器工作原理。思路引入vue编译器概念说明编译器的必要性阐述编译器工作流程回答范例Vue中有个独特的编译器模块称为“compiler”它的主要作用是将用户编写的template编译为js中可执行的render函数。之所以需要这个编译过程是为了便于前端程序员能高效的编写视图模板。相比而言我们还是更愿意用HTML来编写视图直观且高效。手写render函数不仅效率底下而且失去了编译期的优化能力。在Vue中编译器会先对template进行解析这一步称为parse结束之后会得到一个JS对象我们成为抽象语法树AST然后是对AST进行深加工的转换过程这一步成为transform最后将前面得到的AST生成为JS代码也就是render函数。知其所以然vue3编译过程窥探https://github1s.com/vuejs/core/blob/HEAD/packages/compiler-core/src/compile.ts#L61-L62测试test-v3.html可能的追问Vue中编译器何时执行react有没有编译器23-Vue实例挂载的过程中发生了什么?分析挂载过程完成了最重要的两件事初始化建立更新机制把这两件事说清楚即可回答范例挂载过程指的是app.mount()过程这个过程中整体上做了两件事初始化和建立更新机制初始化会创建组件实例、初始化组件状态创建各种响应式数据建立更新机制这一步会立即执行一次组件更新函数这会首次执行组件渲染函数并执行patch将前面获得vnode转换为dom同时首次执行渲染函数会创建它内部响应式数据之间和组件更新函数之间的依赖关系这使得以后数据变化时会执行对应的更新函数。知其所以然测试代码test-v3.html mount函数定义https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/apiCreateApp.ts#L277-L278首次render过程https://github1s.com/vuejs/core/blob/HEAD/packages/runtime-core/src/renderer.ts#L2303-L2304可能的追问响应式数据怎么创建依赖关系如何建立················· 若川简介 ·················你好我是若川毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇在知乎、掘金收获超百万阅读。从2014年起每年都会写一篇年度总结已经坚持写了8年点击查看年度总结。同时最近组织了源码共读活动帮助4000前端人学会看源码。公众号愿景帮助5年内前端人走向前列。扫码加我微信 ruochuan12、拉你进源码共读群今日话题目前建有江西|湖南|湖北 籍 前端群想进群的可以加我微信 ruochuan12 进群。分享、收藏、点赞、在看我的文章就是对我最大的支持~
http://www.zqtcl.cn/news/427602/

相关文章:

  • 网站建设排名的公司江东seo做关键词优化
  • 学习网站开发培训网站内链是什么
  • 中文 域名的网站用wordpress做的网站有哪些
  • 网站建设中需要注意的问题唐山自助建站模板
  • 网站建设捌金手指下拉一重庆 网站定制
  • 网站建设需求调研方法自己做网站要多少钱
  • 北流网站建设公众号开发 表格
  • 做教育类网站一般流程苏宁易购网站风格
  • 兼职网站推广如何做如何用ps做网站
  • 济南外贸网站建设软件公司网站
  • 衡阳做网站注册网站流程
  • 关于网站建设的申请报告wordpress花园网站
  • jsp网站 iis免费企业信息查询
  • 泊头市网站建设公司只有企业自己建立网站平台进行
  • 有阿里云服务器 怎么做网站找广告设计
  • 网站建设 ui设计公司素材网站源码
  • 网站响应式布局wordpress代码混乱
  • 免费建设个人网站四川建设人员信息查询
  • 做国际网站有哪些专门做拼花网站
  • eclipse sdk做网站小程序开发报价明细
  • 网站开发源码售卖合同百度广告投诉电话
  • wordpress读法鄂州seo
  • 网站建设方案的写作方法媒体发稿推广
  • 免费的网站空间注册空壳公司判几年
  • 网站怎么运营推广达美网站建设
  • 江苏建设人才网网站中国最新时事新闻
  • 网站建立时间毕节地seo
  • 央企网站建设意义长沙网约车
  • 广告联盟怎么建设网站做贸易 公司网站放哪里
  • 北京建设局网站首页开发游戏用什么软件