VUE面试题

作者: 北冥有鱼_425c | 来源:发表于2019-11-03 13:14 被阅读0次

    **1、组件间怎么传值,具体说说代码怎样实现 **

    • 子传父:子向父是通过 events($emit);通过父链 / 子链也可以通信($parent / $children);ref 也可以访问组件实例;provide / inject API;$attrs/$listeners

    • 父传子:父向子传递数据是通过 props,

    • 兄弟组件传值:bus,vuex

    • 跨级父子通信:Bus;Vuex;provide / inject API、$attrs/$listeners

    以上传值示列文档

    2、Vue双向绑定原理

    采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

    1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
    2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
    3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

    3、Vue的生命周期和钩子函数

    [图片上传失败...(image-3b3215-1572758078510)]

    beforecreate : 举个栗子:可以在这加个loading事件
    created :在这结束loading,还做一些初始化,实现函数自执行
    mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情

    beforeUpdate: 更新之前

    beforeMount: 挂载之前

    updeted: 更新之后

    beforeDestroy: 你确认删除XX吗?

    destroyed:当前组件已被删除,清空相关内容

    4、应该在vue的生命周期的什么阶段发出ajax请求,为什么

    看实际情况,一般在 created 里面就可以,如果涉及到需要页面加载完成之后的话就用 mounted

    5、vuex是什么?怎么使用?哪种功能场景使用它?

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事务; 异步逻辑应该封装在action中。
    在main.js引入store,注入。新建了一个目录store,….. [ export default new Vuex.Store(config) ]。
    场景有:单页应用中,组件之间的状态同步、音乐播放、登录状态、加入购物车
    [图片上传失败...(image-52473e-1572758078510)]

    state
    Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
    mutations
    mutations定义的方法动态修改Vuex 的 store 中的状态或数据。
    getters
    类似vue的计算属性,主要用来过滤一些数据。
    action
    actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

    const store = new Vuex.Store({ //store实例
          state: {
             count: 0
                 },
          mutations: {                
             increment (state) {
              state.count++
             }
              },
          actions: { 
             increment (context) {
              context.commit('increment')
       }
     }
    })
    

    modules
    项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
     }
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
     }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
    })
    

    6、Vue路由守卫

    路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫。

    全局守卫

    你可以使用 router.beforeEach 注册一个全局前置守卫:

    const router = new VueRouter({ ... })
    
    router.beforeEach((to, from, next) => {
      // ...
    })
    

    每个守卫方法接收三个参数:

    • to: Route: 即将要进入的目标 路由对象
    • from: Route: 当前导航正要离开的路由
    • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数,确保要调用 next 方法,否则钩子就不会被 resolved

    举一个例子:

    1. 列举需要判断登录状态的“路由集合”,当跳转至集合中的路由时,如果“未登录状态”,则跳转到登录页面LoginPage;
    2. 当直接进入登录页面LoginPage时,如果“已登录状态”,则跳转到首页HomePage;

    7、常用的vue指令,Vue的自定义指令怎么做

    常用的vue指令有v-if、v-show,v-for,v-model, v-bind等等

    • 创建局部指令
    var app = new Vue({
        el: '#app',
        data: {    
        },
        // 创建指令(可以多个)
        directives: {
            // 指令名称
            drag: {
                inserted(el) {
                    // 指令中第一个参数是当前使用指令的DOM
                    console.log(el);
                    console.log(arguments);
                    // 对DOM进行操作
                    el.style.width = '200px';
                    el.style.height = '200px';
                    el.style.background = '#000';
                }
            }
        }
    })
    
    • 全局指令
    Vue.directive('dir2', {
        inserted(el) {
            console.log(el);
        }
    })
    
    • 指令的使用
    <div id="app">
        <div v-dir1></div>
        <div v-dir2></div>
    </div>
    

    8、Vue登录流程?需要做什么验证

    在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:

    • 第一次登录的时候,前端调后端的登陆接口,发送用户名和密码

    • 后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token

    • 前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面

    • 前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面

    • 每次调后端接口,都要在请求头中加token,我们常用axios的请求库中,添加全局拦截器,将token设置在请求头中。

    • 后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401

    • 如果前端拿到状态码为401,就清除token信息并跳转到登录页面

    // http request 拦截器
    axios.interceptors.request.use(
        config => {
            if (store.state.token) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
                config.headers.Authorization = `token ${store.state.token}`;
            }
            return config;
        },
        err => {
            return Promise.reject(err);
        });
     
    // http response 拦截器
    axios.interceptors.response.use(
        response => {
            return response;
        },
        error => {
            if (error.response) {
                switch (error.response.status) {
                    case 401:
                        // 返回 401 清除token信息并跳转到登录页面
                        store.commit(types.LOGOUT);
                        router.replace({
                            path: 'login',
                            query: {redirect: router.currentRoute.fullPath}
                        })
                }
            }
            return Promise.reject(error.response.data)   // 返回接口返回的错误信息
    });
    

    9、讲一下MVVM中的vm工作流程

    MVVM 是 Model-View-ViewModel 的缩写。
    Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
    View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
    ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
    在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
    ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

    10、Vue和react的区别?

    • react和vue都是做组件化的,整体的功能都类似,但是他们的设计思路是有很多不同的。使用react和vue,主要是理解他们的设计思路的不同

    • react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,

    • 而vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom

    • react的性能优化需要手动去做,而vue的性能优化是自动的,但是vue的响应式机制也有问题,就是当state特别多的时候,Watcher也会很多,会导致卡顿

    • react是类式的写法,api很少,而vue是声明式的写法,通过传入各种options,api和参数都很多

    • react可以通过高阶组件(Higher Order Components--HOC)来扩展,而vue需要通过mixins来扩展

    总结:react整体的思路就是函数式,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以做到,比如结合redux-form,而vue是基于可变数据的,支持双向绑定。react组件的扩展一般是通过高阶组件,而vue组件会使用mixin。vue内置了很多功能,而react做的很少,很多都是由社区来完成的,vue追求的是开发的简单,而react更在乎方式是否正确。

    11、Vue里面的插槽

    <slot>

    是组件的一块HTML模板,父组件决定这块模板显不显示以及怎么显示。

    位置由子组件自身决定(slot现在组件template的什么位置,父组件传过来的模板将来就显示在什么位置)

    匿名插槽:只能有一个,可以放在组件的任何位置

    <v-xx><h1></h1></v-xx>

    12、Vue-cli2.0和Vue-cli3.0的区别

    用vue-cli3.0版本创建的项目与2.0版本相比较,我们会发现,文件目录少了很多 eg:build、config,那么如何像vue-cli 2.* 之前关于端口号的配置、打包之后的路径的配置、图片的配置等,到哪里配置呢??vue-cli 3.0 可以在项目的根目录下新建一个 vue.config.js 文件,之前繁琐的配置都可以在这里直接配置

    3.0能直接运行单个组件

    3.0有一个UI管理界面

    安装了2.0版本,要先卸载

    **13、Vue的路由实现 || vue-router的原理 **

    hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
    特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
    hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

    history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
    history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”

    14、vue路由的钩子函数

    首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
    
    beforeEach主要有3个参数to,from,next:
    
    to:route即将进入的目标路由对象,
    
    from:route当前导航正要离开的路由
    
    next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
    

    15、对keep-alive 的了解

    <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

    <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

    <keep-alive><transition>相似,只是一个抽象组件,它不会在DOM树中渲染(真实或者虚拟都不会),也不在父组件链中存在,比如:你永远在 this.$parent 中找不到 keep-alive

    keep-alive生命周期钩子函数:activated、deactivated

    使用<keep-alive>会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在activated阶段获取数据,承担原来created钩子中获取数据的任务。

    被包含在 <keep-alive> 中创建的组件,会多出两个生命周期的钩子: activateddeactivated

    activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。

    deactivated:在组件被停用时调用。

    注意:只有组件被 keep-alive 包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。

    什么时候获取数据?

    当引入keep-alive 的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。

    16、DOM 和虚拟DOM的区别 以及你对于他们了解

    Document Object Model(文档对象模型)

    DOM的本质:DOM是浏览器概念,浏览器从服务器端读取html页面,浏览器将html解析成一棵元素嵌套关系的dom树,用对象来表示页面上的元素,并提供操作dom对象的api。

    虚拟DOM:框架概念,程序员用js对象来模拟页面上dom元素的嵌套关系( 本质 ),为了实现页面元素的高效更新( 目的 )

    虚拟DOM是真实DOM结构的映射,即一个数据集合

    // 对于这个Html 文件
    <div class="">
        <p>
            <span>
                Hello, the world!
            </span>
            <span>
                Hello, the code!
            </span>
        </p>
    
    </div>
    
    // 它对应的虚拟DOM就是
    let nodesData = {
        tag: 'div',
        attr: []
        children: [
          {
            tag: 'p',
            children: [
              {
                tag: 'span',
                children: [
                  {
                    tag: '#text',
                    text: 'Hello, the world!'
                  }
                ]
              }
            ]
          },
          {
            tag: 'span',
              children: [
                {
                  tag: '#text',
                  text: 'Hello, the code!'
                }
              ]
          }
        ]
      }
     //  或这种写法
     let vNodes = v('div', [
          v('p', [
            v('span', [ v('#text', 'Hello, the world!') ] )
            ]
          ),
          v('span', [
            v('#text',  'Hello, the code!')
            ])
        ]
      )
     虚拟DOM的核心就是一个diff算法:使用一个render()方法就可以将上面vNodes还原成真实的Html页面
    

    17、vue指令的生命周期

    自定义指令有五个生命周期(也叫钩子函数),分别是 bind,inserted,update,componentUpdated,unbind

    • bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
    • inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
    • update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
    • componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
    • unbind:只调用一次,指令与元素解绑时调用。

    18、vue封装公共组件(通用组件)需要考虑到什么

    开发通用组件是很基础且重要的工作,通用组件必须具备高性能、低耦合的特性

    一、数据从父组件传入

    为了解耦,子组件本身就不能生成数据。即使生成了,也只能在组件内部运作,不能传递出去。

    父对子传参,就需要用到 props,但是通用组件的的应用场景比较复杂,对 props 传递的参数应该添加一些验证规则

    二、在父组件处理事件

    在通用组件中,通常会需要有各种事件,

    比如复选框的 change 事件,或者组件中某个按钮的 click 事件

    这些事件的处理方法应当尽量放到父组件中,通用组件本身只作为一个中转

    三、记得留一个 slot

    一个通用组件,往往不能够完美的适应所有应用场景

    所以在封装组件的时候,只需要完成组件 80% 的功能,剩下的 20% 让父组件通过 solt 解决

    四、不要依赖 Vuex

    父子组件之间是通过 props 和 自定义事件 来传参,非父子组件通常会采用 Vuex 传参

    但是 Vuex 的设计初衷是用来管理组件状态,虽然可以用来传参,但并不推荐

    因为 Vuex 类似于一个全局变量,会一直占用内存

    在写入数据庞大的 state 的时候,就会产生内存泄露

    五、合理运用 scoped 编写 CSS

    在编写组件的时候,可以在 <style> 标签中添加 scoped,让标签中的样式只对当前组件生效

    但是一味的使用 scoped,肯定会产生大量的重复代码

    所以在开发的时候,应该避免在组件中写样式

    当全局样式写好之后,再针对每个组件,通过 scoped 属性添加组件样式

    19、父组件怎么调用子组件里的方法

    • 在父组件中:首先要引入子组件 import Child from './child';

    • <child ref="mychild"></child>是在父组件中为子组件添加一个占位,ref="mychild"是子组件在父组件中的名字

    • 父组件中 components: {  是声明子组件在父组件中的名字}

    • 在父组件的方法中调用子组件的方法,很重要 this.$refs.mychild.parentHandleclick("嘿嘿嘿"); parentHandleclick是子组件中的方法

    20、css只在当前组件起作用

    答:在style标签中写入scoped即可 例如:<style scoped></style>

    21、v-if 和 v-show 区别

    答:v-if按照条件是否渲染,v-show是display的block或none;

    22、route和router的区别

    答:route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

    23、vue.js的两个核心是什么?

    答:数据驱动、组件系统

    24、vue常用的修饰符?

    答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

    25、v-on 可以绑定多个方法吗?

    答:可以

    26、vue中 key 值的作用?

    答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

    27、什么是vue的计算属性?

    答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

    计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动更新。
    <body>
        <div id="app">
             <input type="text" v-model="msg">
             <p>原始字符:{{msg}}</p>
             <p>计算属性翻转字符:{{reverseMsg}}</p>
        </div>
        <script>
             new Vue({
                 el:'#app',
                 data:{
                     msg:'Hello'
                 },
                 //vue的计算属性
                 computed:{
                     reverseMsg(){
                         //返回翻转后的字符串,当msg变化后reverseMsg会跟着变化
                         return this.msg.split('').reverse().join('')
                     }
                 }
             })
        </script>
    </body>
    

    28、vue等单页面应用及其优缺点

    MVVM是Model-View-ViewModel的简写。

    答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
    缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

    29、路由之间跳转

    声明式(标签跳转) 编程式( js跳转)

    通过router-link实现跳转

    [图片上传失败...(image-3276d6-1572758078510)]

    通过js的编程的方式

    img

    30、Vue中怎么实现跨域

    使用http-proxy-middleware 代理解决(项目使用vue-cli脚手架搭建)

    例如请求的url:“http://aa.com/demo.json“

    1、打开config/index.js,在proxyTable中添写如下代码:

    proxyTable: { 
      '/api': {  //使用"/api"来代替"http://aa.com" 
        target: 'http://aa.com', //源地址 
        changeOrigin: true, //改变源 
        secure:false // 是否使用https
        pathRewrite: { 
          '^/api': '/api' //路径重写 
          } 
      } 
    }
    

    2、使用axios请求数据时直接使用“/api”

    getData () { 
     axios.get('/api/demo.json', function (res) { 
       console.log(res) 
    })
    

    以上配置只是在开发环境(dev)中解决跨域。要解决生产环境的跨域问题,则在config/dev.env.jsconfig/prod.env.js里也就是开发/生产环境下分别配置一下请求的地址API_HOST,开发环境中我们用上面配置的代理地址api,生产环境下用正常的接口地址

    module.exports = merge(prodEnv, {
        NODE_ENV: '"development"',
        API_HOST:"/api/"
    })
    
    'use strict'
    module.exports = {
        NODE_ENV: '"production"',
        API_HOST:"http://aa.com"
    }
    

    31、Vue首屏加载过慢的解决方法有哪些

    vue首屏加载过慢的原因

    • 网速慢肯定会导致首屏加载过慢,但是在这里我们不做讨论
    • vue项目作为一个单页面应用,如果不对路由进行处理,在加载首页的时候,就会将所有组件全部加载,并向服务器请求数据,这必将拖慢加载速度;
    • 通过查看Network,发现整个网站加载试讲长达10几秒,加载时间最长的就是js、css文件和媒体文件及图片

    解决方案

    • vue-router 路由懒加载

    • 在项目开发中,我们会用到很多第三方库,如果可以按需引入,我们可以只引入自己需要的组件,来减少所占空间,但也会有一些不能按需引入,我们可以采用CDN外部加载,在index.html中从CDN引入组件,去掉其他页面的组件import,

    • 关闭sourcemap,sourcemap是为了方便线上调试用的,因为线上代码都是压缩过的,导致调试极为不便,而有了sourcemap,就等于加了个索引字典,出了问题可以定位到源代码的位置。
      但是,这个玩意是每个js都带一个sourcemap,有时sourcemap会很大,拖累了整个项目加载速度,为了节省加载时间,我们将其关闭掉

    • 开启gzip压缩,这个优化是两方面的,前端将文件打包成.gz文件,然后通过nginx的配置,让浏览器直接解析.gz文件。

    • 加个loading效果:首页加个好看的loading阻塞一下,让用户别等的那么心焦。

    • 如果首页真的有瓶颈,可以考虑用node单独做服务端渲染,而下面的子页面仍用spa单页的方式交互。

    32、vue如何实现按需加载组件

    https://www.cnblogs.com/-roc/p/9983177.html

    33、 请说下封装 vue 插件封装过程

    https://www.jb51.net/article/157120.htm

    34、vue项目的多语言处理

    Vue已经有了这个多语种的插件,vue-i18n

    35、vue中的watch介绍和场景

    监听并处理data属性的更新,对data属性的监听,说明属性是在data中声明过的
    属性更新时调用监听函数,可选参数分别为新值和旧值,对属性重新设置值,只要跟原来的值相等就不会触发函数调用,这一点跟计算属性是相似的,

    // 基础用法
    watch: {
            activeTab(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.getList();
            }
    }
    // 函数体调用Vue实例的方法可简写
    watch: {
            activeTab: 'getList'
    }
    

    属性初始化的值默认不会触发监听,解决办法添加说明immediate:true,表示监听初始值,此时使用handler写法

    watch: {
            activeTab: {
                handler(newValue, oldValue) {
                    console.log(newValue, oldValue);
                    this.getList();
                },
                // 立即执行handler函数
                immediate: true
            }
        }
    

    当被监听的属性为对象时,默认不会监听对象内部属性的变化,而是只监听属性被赋值时的变化,解决办法添加说明deep:true(默认为false),此时监听器会深度遍历给对象的每一个属性都带上监听器,更新写法

    // 监听对象的所有属性
    watch: {
            activeTab: {
                handler(newValue, oldValue) {
                    console.log(newValue, oldValue);
                    this.getList();
                },
                // 深度监听
                deep: true
            }
        }
    // 监听对象的某些属性
    watch: {
            'activeTab.index': {
                handler(newValue, oldValue) {
                    console.log(newValue, oldValue);
                    this.getList();
                }
            }
        }
    

    另外组件中的监听器会随组建的注销而注销,不会造成内存溢出,但如果使用命令式的( vm.$watch)全局的监听器需要手动注销才行

    相关文章

      网友评论

        本文标题:VUE面试题

        本文链接:https://www.haomeiwen.com/subject/uywkbctx.html