关于Vue在面试中常常被提到的几点(持续更新……)(二)

简介: 现在Vue几乎公司里都用,所以掌握Vue至关重要,这里我总结了几点,希望对大家有用

3、Vue的computed与watch的区别在哪里?


我们先看一个例子:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
       <p>{{a}}</p>
       <p>{{b}}</p>
       <p>{{c}}</p>
       <button @click='change'>change</button>
    </div>
</body>
<script src="vue.js"></script>
<script>
    var vm =new Vue({
        el:'#app',
        data:{
            a:1,
            b:2
        },
        methods:{
            change(){
                this.a = 5;
            }
        },
        watch:{
            a(){
                console.log('watch');
            }
        },
        computed:{
            c(){
                console.log('computed');
                return this.a + this.b;
            }
        }
    })
</script>
</html>


一开始的时候,


微信截图_20220425183852.png


点击按钮时,


微信截图_20220425183913.png


我们可以看到一开始的时候,打印出了computed,当点击按钮时,data内的属性值a发生变化,打印出watch,接着我们不停点击按钮,并没有打印。(?查看总结4)

我们来总结一下,


  1. 最本质的区别,computed为计算属性,watch为监听属性。
  2. watch就是单纯的监听某个数据的变化,支持深度监听。computed是计算属性,是依赖于某个或者某些属性值,当依赖值发生变化时,也会发生变化。
  3. 计算属性不在data中,计算属性依赖值在data中。watch监听的数据在data中。(不一定在只是data,也可能是props
  4. watch用于观察和监听页面上的vue实例,当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,那么watch为最佳选择。computed可以关联多个实时计算的对象,当这些对象中的其中一个改变时都会触发这个属性,具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。
  5. computed是在Dep.update()执行之后,数据更新之前,对数据重新改造。watch是在set刚开始发生的时候添加的回调,可以监听数据的变化。


4、为什么在Vue3.0采用了Proxy,抛弃了Object.defineProperty?


Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。为了解决这个问题,经过Vue内部处理后可以使用以下几种方法来监听数组。


  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()


由于只针对以上八种方法进行了hack处理,所以其他数组的属性方法也是检测不到的,还是具有一定的局限性。


这里我们举个例子,可以看得更加明白:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for='item in watchArr'>{{item.name}}</li>
        </ul>
        <button @click='change'>change</button>
    </div>
</body>
<script src="vue.js"></script>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            watchArr: [{
                name: '1',
            },{
            name: '2',
            }],
        },
        methods: {
            change() {
                this.watchArr =[{
                name: '3',
                }];
                this.watchArr.splice(0, 1);
                this.watchArr[0].name = 'xiaoyue'; // 无法监听
                this.watchArr.length = 5; // 无法监听
            }
        },
        watch: {
            watchArr(newVal) {
                console.log('监听了');
            },
        }
    })
</script>
</html>


想必看到上面的例子我们会更加明白Object.defineProperty的局限性。接下来,我们接着说Object.defineProperty只能劫持对象的属性,因此,我们需要对每个对象的每个属性进行遍历。Vue2.0里,是通过递归+遍历data对象来实现对数据的监控的,如果属性值也是对象的话,那么需要深度遍历。显然如果能够劫持一个完整的对象才是更好的选择。


那么Proxy有以下两个优点:


  1. 可以劫持整个对象,并返回一个新对象
  2. 有13种劫持操作


摒弃 Object.defineProperty,基于Proxy的观察者机制探索


5、为什么Vuex的mutation不能做异步操作?


因为更改state的函数必须是纯函数,纯函数既是统一输入就会统一输出,没有任何副作用;如果是异步则会引起额外的副作用,导致更改后的state不可预测。


6、Vue中的computed是如何实现的?


实质是一个惰性的wather,在取值操作时根据自身标记dirty属性返回上一次计算结果或重新计算值在创建时就进行一次取值操作,收集依赖变动的对象或属性(将自身压入dep中),在依赖的对象或属性变动时,仅将自身标记dirty致为true


7、Vue的父组件和子组件的生命周期钩子函数执行顺序是什么?


  1. 加载渲染过程 (父)beforeCreate  (父)created  (父)beforeMount (子)beforeCreate (子)created (子)beforeMount (子)mounted (父)mounted
  2. 子组件更新过程 (父)beforeUpdate (子)beforeUpdate (子)Updated  (父)Updated
  3. 父组件更新过程 (父)beforeUpdate   (父)Updated
  4. 销魂过程 (父)beforeDestroy  (子)beforeDestory (子)destroyed   (父)destroyed


相关文章
|
2月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
2月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
26天前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
|
9天前
|
JavaScript
vue面试
vue面试
17 1
|
2月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
2月前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
2月前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
|
7天前
|
JavaScript
vue组件中的插槽
本文介绍了Vue中组件的插槽使用,包括单个插槽和多个具名插槽的定义及在父组件中的使用方法,展示了如何通过插槽将父组件的内容插入到子组件的指定位置。
|
5天前
|
JavaScript
vue消息订阅与发布
vue消息订阅与发布
|
2天前
|
JavaScript
理解 Vue 的 setup 应用程序钩子
【10月更文挑战第3天】`setup` 函数是 Vue 3 中的新组件选项,在组件创建前调用,作为初始化逻辑的入口。它接收 `props` 和 `context` 两个参数,内部定义的变量和函数需通过 `return` 暴露给模板。`props` 包含父组件传入的属性,`context` 包含组件上下文信息。`setup` 可替代 `beforeCreate` 和 `created` 钩子,并提供类似 `data`、`computed` 和 `methods` 的功能,支持逻辑复用和 TypeScript 类型定义。
20 11