zoukankan      html  css  js  c++  java
  • Vue面试题

    1.Vue的双向数据绑定原理是什么?

    答案:vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()

    来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

     

    具体步骤:

    第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter,getter

    这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化.

     

    第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个

    指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图.

     

    第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:

    1.在自身实例化时往属性订阅器(dep)里面添加自己

    2.自身必须有一个update()方法

    3.待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,

    则功成身退。

     

    第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来

    监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和

    Compile之间的通信桥梁,达到数据变化->视图更新:视图交互变化(input)->数据model变更的双向绑定效果.

     

    2.请详细说下你对vue生命周期的理解

    答案:总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前后。

    创建前/后:beforeCreated阶段,vue实例的挂载元素$el和数据对象data

    都为undefined,还未初始化。在created阶段,Vue实例的数据对象data有了,

    $el还没有。

     

    载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前

    为虚拟DOM节点,data.message还未替换。在mounted阶段,vue实例挂载完成,

    data.message成功渲染。

     

    销毁前/后:在执行destory方法后,对data的改变不会再触发周期函数,说明此时vue

    实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在.

     

    3.封装vue组件的过程.

    答案:首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,

    解决了我们传统项目开发:效率低、难维护、复用性性等问题。

    然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。

    子组件需要数据,可以在props中接收定义。而子组件修改好数据后,想把数据传递给父组件。

    可以采用emit方法。

     

    4.mvc和mvvm

    答案:

    MVC   模型-视图-控制器(Model-View-Controller) Model和View永远不能相互通信,

    只能通过Controller传递。

    Controller可以直接与Model对话(读写调用Model),Model通过Nottification和KVO机制

    与Controller间接通信。

    Controller可以直接与View对话,通过outlet,直接操作View,outlet直接对应到View中的控件,

    View通过action向Controller报告事件的发生(如用户Touch我了)

    Controller是View的直接数据源(数据很可能是Controller从Model中取得并经过加工了)。

    Controller是View的代理(delegate),以同步View与Controller。

          MVVM

    Model  - ViewModel  -  View

    什么是MVVM:一个MVC的增强版,我们正式连接了视图和控制器,并将表示逻辑从Controller移

    出放到一个新的对象里,即ViewModel。MVVM听起来很复杂,但它本质上就是一个精心优化的

    MVC架构。

       Model层是少不了的了,我们得有东西充当DTO(数据传输对象),当然,用字典也是可以的,

    编程么,要灵活一些。Model层是比较薄的一层,如果学过Java的小伙伴的话,对JavaBean应该不陌生.

       ViewModel层,就是View和Model层的粘合剂,他是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求

    和其他各种各样的代码的极好的地方。说白了,就是把原来ViewController层的业务逻辑和页面逻辑

    等剥离出来放到ViewModel层。

       View层,就是ViewController层,他的任务就是从ViewModel层获取数据,然后显示。

     

    5.Vue首屏加载非常慢,如何解决?

    答案:Vue首屏加载非常慢.

    原因:当打包应用时,将所有JavaSript代码打包在一个文件中,导致js代码非常庞大,严重影响了页面加载速度。

    1.配置打包工具,将组件分别打包到不同的js代码块中

    build/webpack.base.config.js

           output:{   

                path:config.bulid.assetsRoot,

                filename:'[name].js',

               //新增

            chunkFilename:"[name].js",

            publicPath:process.env.NODE_ENV=="production"

                  ?config.bulid.assetsPublicPath

                  :config.dev.assetsPublicPath

         }

    2.当路由请求到该组件时,才动态加载组件的内容

    路由字典中,路由配置和以前完全一样

    但是在引入组件对象时:

    import Index  from  '@/views/Index.vue'

    改为

    const Index=()=>import('@/views/Index.vue')//仅定义函数暂未执行

    //暂时不引人Index.vue

       当用户在Vue中请求当前组件对应的路由地址时,由vue-router自动调用加载函数,

    动态请求Index.vue组件对象

     

    6.实现订阅/发布者模式?

    答案:

    var  ublisher={ };

    //定义发布者

    publish.list=[];

    //缓存列表  存放订阅者回调函数

    // 增加订阅者

    publisher.listen =function(fn){

        publisher.list.push(fn);

    // 订阅消息添加到缓存列表

    }

    // 发布消息

    publisher.trigger =function(){    

    for(vari = 0,fn; fn = this.list[i++];){

            var that =this

         fn.apply(null,arguments);

    }

    }

    7. 什么是虚拟DOM树:

      答案:

    什么是: 仅包含可能变化的节点和可能变化的属性的树结构

     <body>

    <div id=”app”>

         <img src=”logo.png”> alt  title id  ….

         <h1>{{uname}}</h1>id   class     title    name

         <hr>

         <h2>{{score}}</h2>

       </div>

    {

      el:”#app”,

      children:[

    {el:”h1”, innerText:uname},

    {el:”h2”,innerText:score}

    ]

    }

    为什么: 内容少,便于快速遍历比较不同

    如何发挥作用: 

    当data中模型变量改变时,会通知虚拟DOM树

     虚拟DOM树先缓存本次的修改在元素对象上

     将一批修改生成新的DOM子树和原虚拟DOM树做对比。

     一旦发现不同的元素或内容,就只更新有修改的元素

     虚拟DOM树中,封装了传统DOM API: createElement() appendChild()  .innerHTML,避免了程序员编写大量重复的代码。

     

    8. Vue 如何去除url中的 #

    答案:

    vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 url 会自带 #。如果不想使用 #, 可以使用 vue-router 的另一种模式 history

     

    new Router({

      mode: 'history',

      routes: [ ]

    })

    需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所以在路由跳转的时候,就会出现访问不到静态资源而出现 404 的情况,这时候就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面

    9. Vue组件间如何通信

     答案:

    组件通信

    父组件向子组件通信

     

    子组件通过 props 属性,绑定父组件数据,实现双方通信

    子组件向父组件通信

     

    将父组件的事件在子组件中通过 $emit 触发

     

    非父子组件、兄弟组件之间的数据传递

     

    /*新建一个Vue实例作为中央事件总嫌*/

    let event = new Vue();

     

    /*监听事件*/

    event.$on('eventName', (val) => {

        //......do something

    });

     

    /*触发事件*/

    event.$emit('eventName', 'this is a message.')

     

  • 相关阅读:
    如何将数组初始化为全0?
    什么是优先级队列(priority queue)?
    C语言中指针的指针是如何工作的?
    什么是队列(Queue)?
    理解*ptr++
    【Luogu】P4172水管局长(LCT)
    【Luogu】P4159迷路(矩阵优化)
    【Luogu】P3971Alice And Bob(贪心)
    【Luogu】P3211XOR和路径(高斯消元)
    【Luogu】P2445动物园(最大流)
  • 原文地址:https://www.cnblogs.com/sna-ling/p/12458432.html
Copyright © 2011-2022 走看看