• vue出镜率比较高的十大面试题


    1、vue的底层原理

    vue是M-V-VM模式,通过modelView作为中间层,进行双向数据的绑定和变化
    ①通过document.createDocumentFrament()方法建立虚拟Dom树
    ②一旦被检测到数据发生变化,会通过Object.defineProperty定义的数据拦截
    ③拦截到数据变化从而通过订阅-发布模式触发观察者,从而改变虚拟dom中具体数据
    ④最后通过更新虚拟Dom的元素值,从而改变最后dom树的值,完成双向绑定

    2、Vue Router 路由模式 hash 和 history 的实现原理,以及他们的特性

    hash模式实现原理:location.hash的值就是url中#后面的内容。
    以下几个特性:
    ① url中hash值只是客户端一种状态,向服务端发送请求时hash部分不会被发送
    ② hash值的改变,都会在浏览器增加一个历史记录,因此能通过浏览器回退、前进按钮控制hash的切换
    ③ 可以用hashchange事件去监听hash变化,从而对页面进行跳转(渲染)
    ④ 可以通过a标签设置href属性,当用户点击后hash值会发生变化,或者通过js对location.hash赋值改变url的hash值

    history模式实现原理:
    H5 提供了HistoryAPI 来实现URL的变化,history.pushState() 和 history.repalceState()两个API可以在不进行刷新情况下操作浏览器历史记录
    不同的是,前者是新增一个历史记录,后者是直接替换当前记录。

    以下几个特性:
    ① pushState和repalceState两个API来操作实现url的变化
    ② 可以用popstate事件来监听url变化,从而对页面进行跳转
    ③ pushState或repalceState不会触发popstate事件,这时需要手动触发页面跳转
    ④ history路由模式需要后台配置支持,需要在服务端增加一个覆盖所有情况的候选资源,如果url匹配不到静态资源,应该返回同一个app依赖的index.html页面

    3、什么是虚拟DOM,为什么他能提高性能? 说下diff算法

    虚拟dom也就是虚拟节点,是通过js的Object对象模拟dom中的节点,然后通过特定的render方法将其渲染成真正的DOM节点
    当改变元素的节点或者属性时候,并不是真正改变dom元素,而是做一次diff算法做一次对比,他会以最小的代价更新dom
    虚拟Dom相当于在js和真实Dom之间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能
    虚拟Dom工作的三个简单步骤:
    1)没当数据发生变化时候,整个页面将在虚拟dom中重新渲染
    2)然后计算之前的dom与新的dom中间差异
    3)完成计算后,将只用实际更改的内容更新真实dom

    diff算法:
    根据真实dom生成一个虚拟dom,当虚拟dom某个节点数据变化改变后会生成一个新的vnode,然后新的和旧的对比,一边对比一边打补丁
    发现有不一样的就直接修改在真实的dom上。
    当数据发生改变时,set方法会调用Dep.notify通知所有订阅者,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图

    4、vue如何实现组件和逻辑复用

    组件复用可以使用slot作用域插槽,让子组件暴露出属性 直接在父组件使用
    逻辑复用可以使用Mixin 混入模式,将一些逻辑封装,然后混入到需要该功能的组件中

    说说你对mixin的理解,以及应用场景 ?
    mixin,一个混入对象可以包含任意组件选项。多个实例引用了相同的方法或者属性,可将这些重复的内容抽取出来作为mixin的js
    export导出去,在需要引用vue文件通过mixin属性注入。他允许封装一块在应用的其他组件都可以使用的函数
    比如有两个非常相似的组件,基本功能一致,但个别地方又有差异,这时候可以使用mixin

    5、页面刷新后vuex的state数据为什么会丢失,如何解决

    原因:因为store里的数据是把保存在运行内存中,当页面刷新时,会重新加载vue实例,store里面的数值就会重新赋值初始化
    解决方法:在页面向后台请求数据,并且在页面刷新前,将vuex中数据存储到localStorage或sessionStorage中

    export default {
    name: 'App',
    created() {
    //在页面加载时读取sessionStorage里的状态信息
    if(sessionStorage.getItem('store')){
    this.$store.replaceState(Object.assign(
    {},
    this.$store.state,
    JSON.parse(sessionStorage.getItem('store'))
    ))
    }
    //在页面刷新时将vuex里的信息保存在sessionStorage中
    window.addEventListener('beforeunload', () => {
    sessionStorage.setItem('store', JSON.stringify(this.$store.state));
    })
    }
    }

    6、如何理解Vue中的Render渲染函数,他和JSX有什么不同

    Vue一般使用template来创建HTML,然后有时候,我们需要使用js来创建html,这时候我们需要使用render函数
    render函数return一个createElement组件中的子元素存储在组件实列中,createElement返回的是包含的信息会告诉VUE页面上需要渲染什么样的节点。
    一般用render函数封装东西会比较灵活,尤其是配置和模板分离。

    JSX是JavScript和XML结合一种的格式,Js在解析JSX时会先创建虚拟DOM,JSX最后会被编译为JavaScript代码执行
    JSX相当于createElement的语法糖,这种形式可以直接使用template模板格式在render函数里写

    7、Proxy代理与Object.defineProperty的优劣对比

    vue是基于数据劫持的双向绑定,数据劫持有两种,分别是Object.defineProperty和Proxy代理
    Vue3.0以Proxy来替代Object.defineProperty数据劫持
    Proxy优势:
    1)可以直接监听对象,而非属性
    2)可以直接监听数组的变化
    3)有很多拦截方法
    4)返回一个新对象,可以只操作新对象即可

    8、说一下formData上传表单的实现原理

    先创建一个formData对象,通过append向form对象添加数据(键值队)
    let formData = new FormData();
    formData.append(name,value)

    通过axios上传文件,配置添加请求头,添加上传进度监听事件
    let config = {
    header: {"Content-Type,multipart/form-data"},
    onUploadProgress: e =>{
    let percent = (progressEvent.loaded / progressEvent.total * 100) | 0
    //调用onProgress方法来显示进度条,需要传递个对象 percent为进度值
    params.onProgress({ percent: percent })
    }
    }
    上传成功 调用onSuccess方法,上传失败 调用onError方法
    axios.post().then((response) => {
    console.log(response)
    params.onSuccess(response.info)
    }).catch((error) =>{
    params.onError(error)
    })

    9、vue项目中做过哪些优化处理 ?

    ①v-if 、v-show区分使用场景
    v-if是真正的条件渲染,条件成立才会渲染,否则不会渲染,v-show只是操作display属性来控制元素,不管条件是否成立都会渲染。如果需要频繁切换使用v-show较为合适
    ②v-for遍历时给item添加key,并且避免同时使用v-if
    在数据进行遍历渲染时,需要为每一项item设置唯一的key值,方便vue内部机制准确查找该数据。当state更新时,新的状态值和旧的对比,可以更快的定位到diff
    ③事件的销毁
    如果是非组件本身的事件,比如addEventListener方式是不会自动销毁的,需要手动移除,以免造成内存泄漏
    created(){
    addEventListener('click','this.click',false)
    },
    beforeDestroy(){
    removeEventListener('click', this.click, false)
    }
    ④路由懒加载
    vue单页面应用,一次加载过多资源造成用时过长甚至会出现白屏情况
    运用懒加载可以当路由被访问时候才加载,
    import方式和require.ensure()方式
    {
    path: '/about',
    name: 'about',
    meta: {
    breadcrumb: "关于我们"
    },
    component: () => import('@/view/about')
    }
    ⑤图片懒加载
    对于图片过多的页面,为了提高加载速度,可以使用懒加载。将页面内未出现在可视区域的图片先不加载,等滚动到可视区域时再做加载
    可以使用vue-lazyload插件
    ⑥第三方插件的按需引入
    项目中引入第三方插件时,如果直接引入整个插件会造成项目提交过大
    可以借助babel-plugin-component插件只引入需要的组件,从而减小项目的体积
    ⑦webpack对图片进行压缩
    使用image-webpack-loader插件
    ⑧开启 gzip 压缩

    10、vue3.0新增了哪些东西,和2.0有什么区别 ?

    vue3.0采用了ts来编写
    vue3.0将组件的逻辑都写在了函数内部,setup()会取代之前的data()函数,返回一个对象,暴露给模板,而且只在初始化的时候调用一次
    相对2.0,压缩包体积更小
    1)双向绑定,3.0使用es6的proxy,相对于object.defineProperty有很多优势
    2)虚拟dom的对比更新,只更新vdom绑定的动态数据的部分
    3)2.0无论是否使用一些功能和方法都需要下下来,3.0将全局的API和内部的一些组件通过ES的模块进行导出webpack在打包时候就会更加的快捷

  • 相关阅读:
    ubuntu新的配置
    今天下午鼓捣android-studio的一些经验
    Sublime Text 3
    学Web前端开发,选择培训学校是关键--青岛思途
    让HTML5游戏来的更猛烈些吧!--青岛思途
    Java架构师和开发者实用工具推荐
    Java培训班4个月有用吗?
    Java培训机构如何选择才能避免被骗?
    Java跟JavaScript两者间的关系和区别
    浅谈java中的四个核心概念--思途青岛
  • 原文地址:https://www.cnblogs.com/theblogs/p/15990284.html
Copyright © 2020-2023  润新知