当前位置: 首页 > news >正文

vue3 和vue2 的比较

文章目录

  • 生命周期
  • 多根节点
  • Composition API组合式API
    • Options API与composition API对比
      • 优化逻辑组织
      • 优化逻辑复用
  • 异步组件(Suspense)
    • Suspense组件
  • 响应式原理
  • 性能
    • 体积优化
    • 编译优化
      • diff算法优化
      • 静态提升
      • 数据劫持(响应式系统)优化

生命周期

vue3在组合API中使用生命周期钩子时需要先引入,而vue2在选项API中可以直接调用钩子
在这里插入图片描述

setup是围绕beforeCreate和created生命周期钩子运行的,所以不需要显式地去定义

多根节点

vue2中,在模板中如果使用多个根节点时会报错,而vue3 支持多个根节点

Composition API组合式API

vue2 是选项式API(Options API),一个逻辑灰散乱在文件的不同位置(data、props、computed、watch、生命周期等),导致代码地可读性变差。
vue3组合式API(Composition PI)则很好地解决了这个问题,可将同一逻辑的内容写到一起,增强了代码的可读性、内聚性,其还提供了较为完美的逻辑复用性方案。

Options API与composition API对比

优化逻辑组织

Options API 碎片化使得理解和维护复杂组件变得困难, 选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块
Compositon API 将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去

function useCount() {let count = ref(10);let double = computed(() => {return count.value * 2;});const handleConut = () => {count.value = count.value * 2;};console.log(count);return {count,double,handleConut,};
}

组件上使用count

export default defineComponent({setup() {const { count, double, handleConut } = useCount();return {count,double,handleConut}},
});

优化逻辑复用

在vue2中,我们是通过mixin实现功能混合,如果多个mixin混合,会存在两个非常明显的问题:命名冲突和数据来源不清晰

而通过composition这种形式,可以将一些复用的代码抽离出来作为一个函数,只要的使用的地方直接进行调用即可

在vue2中,通过mixin实现功能混合的缺陷

1.命名冲突:如果多个 Mixin 中包含了相同的选项,会导致命名冲突,这可能会导致不可预期的行为。
2.隐式依赖:当多个 Mixin 依赖于相同的属性或方法时,可能会出现隐式的依赖关系,使得代码难以维护和理解。
3.耦合性增强:Mixin 可能会导致组件与多个不同的代码片段紧密耦合,这会增加代码的复杂度和维护难度。
4.全局污染:如果一个 Mixin 修改了全局对象或其他共享资源,可能会影响到整个应用程序。
5.不可追踪性:当一个组件使用了多个 Mixin 时,很难追踪每一个 Mixin 对组件行为的影响。
6.调试困难:当出现问题时,定位问题所在可能会比较困难,特别是当多个 Mixin 交叉影响时。
7.组件复用性:过度使用 Mixin 可能会导致组件的复用性降低,因为组件的功能散布在多个 Mixin 中。
8.组件难以理解:Mixin 可能会导致组件的行为变得复杂,特别是当多个 Mixin 互相影响时,会使得组件的行为难以理解。
因此,在使用 Vue 2 中的 Mixin 时,需要谨慎考虑,尽量避免上述问题的出现。同时,也可以考虑使用其他方式,如使用组件复合、插槽(slot)、高阶组件(Higher Order Component)等来达到类似的功能复用效果,但更加灵活和可控。vue3 的组合式API很好解决了这种问题

在 Vue 3 中,提供了 Composition API(组合式 API)作为一种新的组件组织方式,它可以更好地解决了在 Vue 2 中使用 Mixin 可能出现的一些问题:
命名冲突问题减少:Composition API 使用函数组合的方式,可以将相关的逻辑组织在一个函数内部,减少了命名冲突的可能性。
1.明确的依赖关系:Composition API 允许你在组件内部明确地声明你的依赖关系,这使得组件的依赖关系更加清晰。
2.提供了更强大的逻辑封装:通过 Composition API,可以更灵活地组合和封装逻辑,使得代码更易于理解和维护。
3.模块化和可组合性:Composition API 鼓励将逻辑以函数的形式封装,这使得逻辑可以更容易地进行模块化和复用。
4.代码的可追踪性:由于逻辑被封装在函数内部,所以在组件内部可以更容易地追踪逻辑的来源和影响。
5.更好的代码隔离:Composition API 允许你将逻辑按功能组织在不同的函数中,从而实现更好的代码隔离,减少了耦合性。
总的来说,Composition API 提供了一种更灵活、可组合、可控的方式来组织组件的逻辑,相比于 Vue 2 的 Mixin,可以更好地解决了命名冲突、依赖关系不清晰等问题,使得组件的代码更容易理解、维护和复用。

异步组件(Suspense)

Vue3提供Suspense组件,允许程序在等待异步组件加载完成前渲染兜底的内容,如loading,使用户的体验更加平滑。使用它,需要在模板中声明,并包括两个名命插槽:default和fallback。Suspense确保加载完异步内容时显示默认插槽,并将fallback插槽用作加载状态

<tempalte><suspense><template #default><List /></template><template #fallback><div>Loading...</div></template></suspense>
</template>

Suspense组件

vue3中增加了一个名为Suspense的内置组件,用于在异步组件加载完成前显示占位符,避免页面空白或显示错误信息,提高用户体验。
注意:是一项实验性功能,它不一定灰最终成为稳定功能,并且在稳定之前相关API也可能会发生变化。

<template><div><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense></div>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'))
</script>

注意事项:

  1. Suspense组件只能包含一个异步组件,否则会抛出错误
  2. fallback插槽中的内容只能是一个单独的元素,否则会抛出错误
  3. 异步组件必须通过defineAsynsComponent方法定义,否则无法使用Suspense组件。
  4. 为了提高用户体验,建议在fallback插槽中显示一个占位符,如Loading

响应式原理

Vue2 响应式原理的基础是Object.defineProperty
Vue3的响应式原理是Proxy

Object.defineProperty基本用法:直接在一个对象上定义新的属性或修改现有的属性,并返回对象

// 创建一个空对象
const person = {};// 使用 Object.defineProperty 定义属性
Object.defineProperty(person, 'name', {value: 'John',      // 属性值writable: false,     // 不可写enumerable: true,    // 可枚举configurable: false  // 不可配置
});// 尝试修改属性值会失败,因为属性是不可写的
person.name = 'Mike';// 遍历对象的属性
for (let key in person) {console.log(key); // 输出 'name',因为属性是可枚举的
}// 删除属性会失败,因为属性是不可配置的
delete person.name;// 重新定义属性为可配置
Object.defineProperty(person, 'name', {configurable: true
});// 现在可以成功删除属性
delete person.name;

vue2核心源码:

function defineReactive(obj, key, val) {
//创建一个依赖实例,每个属性对象一个依赖// 一 key 一个 depconst dep = new Dep()// 获取 key 的属性描述符,发现它是不可配置对象的话直接 returnconst property = Object.getOwnPropertyDescriptor(obj, key)if (property && property.configurable === false) { return }// 获取 getter 和 setter,并获取 val 值(以及初始化值)const getter = property && property.getconst setter = property && property.setif((!getter || setter) && arguments.length === 2) { val = obj[key] }// 递归处理,保证对象中所有 key 被观察let childOb = observe(val)Object.defineProperty(obj, key, {//属性可枚举enumerable: true,//属性可配置configurable: true,// get 劫持 obj[key] 的 进行依赖收集get: function reactiveGetter() {const value = getter ? getter.call(obj) : valif(Dep.target) {// 依赖收集,将当前依赖(观察者)添加到属性的依赖列表中dep.depend()if(childOb) {// 针对嵌套对象,依赖收集childOb.dep.depend()// 如果属性值是数组 还需要触发数组响应式if(Array.isArray(value)) {dependArray(value)}}}}//返回属性值return value})// set 派发更新 obj[key]set: function reactiveSetter(newVal) {//在这里实现属性的设置,包括触发响应式更新...if(setter) {setter.call(obj, newVal)} else {val = newVal}// 新值设置响应式childOb = observe(val)// 依赖通知更新dep.notify()}
}

这段代码的主要功能是将对象的属性变成响应式的,当属性的值来发生变化时,可以自动通通知相关的视图进行更新。它通过Object.defineProperty来定义属性的get和set方法,以及属性的特性(例如可枚举、可配置等)来实现这一功能。同时它还支持嵌套对象和数组的响应式处理。

性能

体积优化

相比于Vue2,Vue3整体体积变小了,移除了一些不常用的API,任何一个函数,比方说ref、reavived、computed等,仅仅在用到的时候才打包,没用到的模块都去掉,打包整体体积变小,最重要的是Tree shanking

Tree shanking是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫Dead code elimination

Tree shaking是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量

Tree shaking做了两件事:

  • 编译阶段利用ES6 Module判断哪些模块已经加载
  • 判断那些模块和变量未被使用或者引用,进而删除对应代码

编译优化

diff算法优化

vue3在diff算法中相比vue2增加了静态标记, 其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较,提高性能。

静态提升

Vue3对不参与更新的元素,会做静态提升只会被创建一次,在渲染时直接复用,这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用
没有做静态提升之前

export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_createVNode("span", null, "你好"),_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}

做了静态提升之后

const _hoisted_1 = /*#__PURE__*/_createVNode("span", null, "你好", -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_hoisted_1,_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST

静态内容_hoisted_1被放置在render 函数外,每次渲染的时候只要取 _hoisted_1 即可

同时 _hoisted_1 被打上了 PatchFlag ,静态标记值为 -1 ,特殊标志是负整数表示永远不会用于 Diff

数据劫持(响应式系统)优化

在Vue2 中,数据劫持就是通过Object.defineProperty,这个API有一些缺陷:检测不到对象属性的添加和删除
数组Api方法无法监听到,需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题

Object.defineProperty(data, 'a',{get(){// track},set(){// trigger}
})

Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的

function reactive(obj) {if (typeof obj !== 'object' && obj != null) {return obj}// Proxy相当于在对象外层加拦截const observed = new Proxy(obj, {get(target, key, receiver) {const res = Reflect.get(target, key, receiver)console.log(`获取${key}:${res}`)return isObject(res) ? reactive(res) : res}set(target, key, value, receiver) {const res = Reflect.set(target, key, value, receiver)console.log(`设置${key}:${value}`)return res},deleteProperty(target, key) {const res = Reflect.deleteProperty(target, key)console.log(`删除${key}:${res}`)return res}})return observed
}

同时Proxy 并不能监听到内部深层次的对象变化,而 Vue3 的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部对象才会变成响应式,而不是无脑递归
Proxy的作用
在vue中 Proxy主要用于监听对象的变化,以便在对象属性发生变化时,自动更新相关的视图。这是Vue实现响应式数据绑定的核心机制之一

  1. 实现响应式数据的绑定
    vue使Proxy对象来监听数据变化,当数据发生变化时,会自动触发相关视图更新。这使得开发者无需手动去追踪数据变化并更新视图,大大简化了前端开发工作
  2. 监听数据的读取和写入
    Proxy可以拦截对象属性的读取和写入操作。这意味着在读取或写入数据时可以执行自定义的逻辑,比如在写入时进行数据验证
  3. 递归监听对象嵌套
    Vue中的Proxy不仅可以监听对象本身,还可以递归地监听对象内部的所有属性和嵌套对象。这使得整个数据结构都可以实现响应式
  4. 数组变化的监听
    对于数组,Proxy 会拦截数组的变化操作(如 push、pop、splice 等),从而实现数组变化的响应式更新。
  5. 动态添加属性:
    使用 Proxy 可以动态地向对象添加属性,并且这个新属性也会被监听,从而保证了新添加的属性也能实现响应式。
  6. 防止非预期的属性访问:
    通过 Proxy 可以限制对象属性的访问,防止对某些属性的非法访问或修改。
  7. 监听对象的删除:
    Proxy 还可以监听对象属性的删除操作,当属性被删除时,可以执行相应的逻辑。

相关文章:

vue3 和vue2 的比较

文章目录 生命周期多根节点Composition API组合式APIOptions API与composition API对比优化逻辑组织优化逻辑复用 异步组件(Suspense)Suspense组件 响应式原理性能体积优化编译优化diff算法优化静态提升数据劫持&#xff08;响应式系统&#xff09;优化 生命周期 vue3在组合AP…...

算法通过村第八关-树(深度优先)黄金笔记|寻找祖先

文章目录 前言最近公共祖先问题总结 前言 提示&#xff1a;生活就是一场有很多规则&#xff0c;却没有裁判的比赛。 --约瑟夫布罗茨基《悲伤与理智》 最近公共祖先问题 参考题目地址&#xff1a;236. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; 如果将搜索…...

postgresql|数据库|数据库测试工具pgbench之使用

前言&#xff1a; 数据库是项目中的重要组件&#xff0c;也是一个基础的重要组件&#xff0c;其地位说是第一我想应该是没有什么太多问题的。 那么&#xff0c;数据库的设计这些方面是不用多说的&#xff0c;关键的第一步&#xff0c;主要是涉及数据库的部署方式&#xff0c;…...

代码随想录Day51 | 309.最佳买卖股票时机含冷冻期

309. 买卖股票的最佳时机含冷冻期 class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();if (n 0) return 0;vector<vector<int>> dp(n, vector<int>(4, 0));dp[0][0] - prices[0]; // 持股票for (int i 1; i &l…...

libopenssl 实现私钥加密公钥解密

在需要验证可信来源时&#xff0c;需要用到签名验签。因此&#xff0c;需要使用私钥加密&#xff0c;公钥解密&#xff0c;取得被加密的信息。这就会使用到私钥加密&#xff0c;公钥解密的场景了。 参考&#xff1a; https://github.com/openssl/openssl/issues/20493 https:/…...

代码随想录 Day - 51|#309 最佳买卖股票时机含冷冻期|#714 买卖股票的最佳时机含手续费

清单 ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 LeetCode #309 最佳买卖股票时机含冷冻期 1. 题目 给定一个整数数组&#xff0c;其中第 i 个元素代表了第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可…...

.net 使用IL生成代理类实现AOP对比Java Spring Boot的AOP

首先&#xff0c;我们需要定义一个接口&#xff0c;代表我们要代理的目标对象的功能&#xff1a; // 日志记录器接口 public interface ILogger {/// <summary>/// 记录日志/// </summary>/// <param name"message">日志消息</param>void L…...

美容店预约小程序搭建流程

随着科技的不断发展&#xff0c;小程序已经成为了人们生活中不可或缺的一部分。对于美容店来说&#xff0c;搭建一个预约小程序不仅可以提高工作效率&#xff0c;还可以增加客户数量、提高服务质量。那么&#xff0c;如何搭建一个美容店预约小程序呢&#xff1f;本文将为你详细…...

ppt 作图 如何生成eps格式

需求 ppt中画的图&#xff0c;按照eps格式导出。 环境 软件: ppt, Gsview(用来将ps格式转成eps), Adobe 操作系统&#xff1a; win11 思路 直接在ppt里选择adobe打印机&#xff0c;将图片以文件形式打印到ps格式的文件中&#xff0c;再由gsview转化成eps。 建议在本身就…...

渗透测试中的前端调试(上)

一、前言 前端调试是安全测试的重要组成部分。它能够帮助我们掌握网页的运行原理&#xff0c;包括js脚本的逻辑、加解密的方法、网络请求的参数等。利用这些信息&#xff0c;我们就可以更准确地发现网站的漏洞&#xff0c;制定出有效的攻击策略。前端知识对于安全来说&#xff…...

跨境电商引流之Reddit营销,入门保姆级攻略

在当今竞争激烈的在线市场中&#xff0c;企业不断寻求新的方法来加强其数字营销工作。Reddit 是最受欢迎的社交媒体平台之一&#xff0c;为企业提供了巨大的潜力&#xff0c;可以通过引人入胜且相关的内容来接触目标受众。然而&#xff0c;将 Reddit 用于营销目的需要仔细考虑某…...

Linux下虚拟网卡的基本命令

文章目录 创建虚拟网卡查看虚拟网卡删除虚拟网卡 创建虚拟网卡 # 创建tap模式的虚拟网卡tap0 sudo ip tuntap add mode tap tap0 # 开启网卡 sudo ip link set tap0 up # 设置网卡的ip地址和子网掩码 sudo ip addr add 192.168.1.1/24 dev tap0查看虚拟网卡 # 查看虚拟网卡ta…...

conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败

今天在尝试用conan 1.60.0使用aarch64-linux-gnu编译器交叉编译boost/1.81.0时报错了&#xff1a; conan install boost/1.81.0 -pr:h aarch64-linux-gnu.jinja -pr:b default --build boost输出如下&#xff1a; Configuration (profile_host): [settings] archarmv8 arch_b…...

BFS专题7 多终点迷宫问题

题目&#xff1a; 样例&#xff1a; 输入 3 3 0 0 0 1 0 0 0 1 0 输出 0 1 2 -1 2 3 -1 -1 4 思路&#xff1a; 单纯的 BFS 迷宫问题&#xff0c;只是标记一下每个点的 step&#xff0c;注意初始化答案数组都为 -1. 代码详解如下&#xff1a; #include <iostream> #…...

ES6中对象新增了哪些扩展?

一、属性的简写 当对象字面量的属性名与变量名相同时&#xff0c;可以省略属性名&#xff0c;直接使用变量名作为属性名。 const x 10; const y 20;// ES6之前 const obj1 { x: x, y: y };// ES6属性简写 const obj2 { x, y };注意&#xff1a;简写的对象方法不能用作构造…...

蓝桥杯每日一题2023.9.22

4960. 子串简写 - AcWing题库 题目描述 题目分析 原本为纯暴力但是发现会超时&#xff0c;可以加入前缀和&#xff0c;从前往后先记录一下每个位置c1出现的次数 再从前往后扫一遍&#xff0c;如果遇到c2就将答案加上此位置前的所有c1的个数&#xff08;直接加上此位置的前缀…...

vscode左键无法跳转到定义的文件

之前用vscode的时候&#xff0c;明明是可以ctrl键鼠标左键跳转到定义文件的&#xff0c;突然之间就不行了&#xff0c;鼠标移到引入上根本都没有下划线&#xff0c;无法跳转 解决方法&#xff1a; 项目的根目录新建 jsconfig.json 文件&#xff0c;代码如下 {"compiler…...

c、c++排序的相关知识(归并排序、计数排序、稳定性等)

排序&#xff0c;是对给定的一组数&#xff0c;按照某种逻辑关系&#xff0c;进行位置上的移动。由于排序至少需要将所有数过一遍&#xff08;正常情况下&#xff0c;非特殊数组&#xff09;&#xff0c;因此排序的时间复杂度一定不能小于O&#xff08;N&#xff09;。 归并排…...

oracle定时任务的使用

常见错误&#xff1a; PLS-00225: subprogram or cursor xxx reference is out of scope # job名字太长PLS-00201: identifier COUNT_JOB.SUBMIT must be declared # DBMS_JOB.SUBMIT是固定写法创建存储过程 -- 建表 CREATE TABLE TEST_A(TEST_ADD_DATA DATE); -- 存储过程 C…...

VSCode 配置 Lua 开发环境(清晰明了)

概述 由于 AutoJS 学得已经差不多了&#xff0c;基本都会了&#xff0c;现在开始向其他游戏脚本框架进发&#xff0c; Lua 语言很强大&#xff0c;就不多说&#xff0c; 按键精灵、触动精灵等等都是用该语言编程脚本的&#xff0c;由于按键精灵、触动精灵 和 AutoJS 类似,不是…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...