【前端面试3+1】19 Composition Api 与Options Api 的区别、为什么data属性是⼀个函数⽽不是⼀个对象、v-if和v-for的优先级、【翻转二叉树】

樊南 2024-09-13 08:33:02 阅读 87

一、Vue3.0 所采⽤的 Composition Api 与 Vue2.x 使⽤ 的 Options Api 有什么不同?

逻辑组织方式:Options API 通过组件选项如 <code>data、methodscomputedwatch 来组织代码逻辑,适用于大多数情况,但当组件变得复杂时,会导致组件难以阅读和理解 3。而 Composition API 允许根据逻辑功能来组织代码,将一个功能所定义的所有 API 放在一起,提高了代码的内聚性和可维护性 。如下图

Composition Api 如下图:

直观对比图如下:

组件生命周期钩子:在 Options API 中,生命周期钩子如 <code>created、mounted 等是组件的一部分。而在 Composition API 中,生命周期钩子通过函数如 onMountedonUpdated 等来实现,这些函数可以在 setup 函数中调用 。

响应式系统:Options API 使用 Vue.observable() 来创建响应式对象。Composition API 引入了新的响应式系统 API,如 reactiverefcomputed,提供了更灵活的响应式数据管理方式 。

模板使用:Options API 中,模板直接与组件的选项关联。Composition API 中,如果 setup 函数返回一个对象,则对象的属性将合并到组件模板的渲染上下文,且 setup 返回的 ref 在模板中会自动解开,不需要写 .value

逻辑复用:Options API 中逻辑复用通常通过 mixins 实现,但可能会引起命名冲突和数据来源不清晰的问题 3。Composition API 通过组合函数(Composable functions)来实现逻辑复用,避免了这些问题,并且整个数据来源更为清晰 。

类型推断:Composition API 由于其基于普通变量和函数的特性,可以享受完整的类型推断,而 Options API 在 TypeScript 中需要复杂的类型体操来实现类型推断 8。

打包体积和性能:Composition API 编写的代码在编译时更为高效,可以生成更小的打包体积,并且由于直接访问变量,减少了运行时的开销 。

this 的使用:在 Options API 中,this 关键字用于访问组件实例的属性和方法。而在 Composition API 中,thissetup() 函数中不可用,因为 setup() 在解析 2.x 选项前被调用,setup() 中的 this 将与 2.x 选项中的 this 完全不同 。

集成与兼容性:Vue 3 允许在同一个组件中同时使用 Options API 和 Composition API,但通常推荐仅在需要将现有 Options API 代码库与使用 Composition API 的新特性或外部库集成时这样做 。

二、为什么data属性是⼀个函数⽽不是⼀个对象?

根实例对象

data

可以是对象也可以是函数(根实例是单例),不会产⽣数据污染情况

组件实例对象

data

必须为函数,⽬的是为了防⽌多个组件实例对象之间共⽤⼀个

data

,产⽣

数据污染。采⽤函数的形式,

initData

时会将其作为⼯⼚函数都会返回全新

data

对象

三、v-if和v-for的优先级是什么?

v-for 优先级高于 v-if:当 v-ifv-for 同时作用于同一个元素时,v-for 有更高的优先级。这意味着 Vue 会先处理循环指令 v-for,然后是条件指令 v-if

v-forv-if 的结合使用:如果你想基于某个条件过滤列表中的项,你可以将 v-if 放在 v-for 的循环体内,对每个项应用条件判断。例如:

<ul>

<li v-for="item in items" :key="item.id">code>

<span v-if="item.isVisible">显示项:{ { item.text }}</span>code>

</li>

</ul>

        在这个例子中,v-for 首先迭代 items 数组,然后 v-if 检查每个 item 是否满足 isVisible 条件。

  3.v-if 作为 v-for 的条件:如果你想要在 v-for 的基础上添加一个额外的条件判断,你可以将 v-if 作为 v-for 的一部分,例如使用 v-for 的 filter 方法:

<ul>

<li v-for="item in filteredItems" :key="item.id">code>

{ { item.text }}

</li>

</ul>

在计算属性 filteredItems 中:

computed: {

filteredItems() {

return this.items.filter(item => item.isVisible);

}

}

这里,filteredItems 是根据 isVisible 条件过滤后的数组,v-for 将遍历这个已过滤的数组。

      4.避免同时使用:通常建议不要将 v-if 和 v-for 直接用在同一元素上,因为这可能会导致混淆和不可预期的结果。如果需要根据条件渲染列表中的某些项,最好是先在数据层面进行过滤,然后使用 v-for 来迭代过滤后的结果。

四、【算法】翻转二叉树

1.题目

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

<code>/**

* Definition for a binary tree node.

* struct TreeNode {

* int val;

* struct TreeNode *left;

* struct TreeNode *right;

* };

*/

struct TreeNode* invertTree(struct TreeNode* root) {

}

2.解题

/**

* Definition for a binary tree node.

* struct TreeNode {

* int val;

* struct TreeNode *left;

* struct TreeNode *right;

* };

*/

struct TreeNode* invertTree(struct TreeNode* root) {

if (root == NULL) {

return NULL;

}

// 递归翻转左子树

root->left = invertTree(root->left);

// 递归翻转右子树

root->right = invertTree(root->right);

// 交换左右子树

struct TreeNode* temp = root->left;

root->left = root->right;

root->right = temp;

return root;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。