vue3的基本使用方法

【 vue3实例 】

【 0 】对象、方法和属性

对象(Object):

  • 对象是编程中的一个数据结构,它可以包含多种数据类型,包括数字、字符串、布尔值、数组、其他对象等。
  • 对象通常由一系列属性和方法组成。
  • 在面向对象编程(OOP)中,对象是类的实例。类是对一组相关数据和方法的定义,而对象则是具体的数据实例。
  • 对象可以通过类来创建,也可以在一些语言中直接声明。

属性(Property):

  • 属性是对象中的一个数据成员,用于存储对象的状态或数据。
  • 属性可以是任何数据类型,如数字、字符串、布尔值、数组、对象等。
  • 在编程语言中,属性可以通过对象和点符号来访问,例如 obj.property

方法(Method):

  • 方法是对象中的一个函数,用于定义对象的行为。
  • 方法可以执行一些操作,例如改变对象的状态或对对象的数据进行处理。
  • 方法通常在对象的定义中声明,并通过对象和点符号来调用,例如 obj.method()

举例说明

以下是一个 JavaScript 示例,演示对象、属性和方法:

// 定义一个对象
const person = {// 属性:用于存储对象的数据name: 'Alice',age: 30,// 方法:用于定义对象的行为greet: function() {console.log(`Hello, my name is ${this.name}`);},// 属性:用于计算对象的状态birthday() {this.age += 1;}
};// 访问属性
console.log(person.name); // 输出:Alice
console.log(person.age); // 输出:30// 调用方法
person.greet(); // 输出:Hello, my name is Alice// 修改属性
person.birthday(); // 增加年龄
console.log(person.age); // 输出:31

在这个示例中:

  • person 是一个对象。
  • nameage 是对象 person 的属性。
  • greetbirthday 是对象 person 的方法。
  • 可以通过 person.name 访问 name 属性,通过 person.greet() 调用 greet 方法。

【 1 】创建vue3.x

// vue create 项目名
// vue create vue3
  1. app01 ([Vue 2] babel, router, vuex):
    • 这个选项代表一个使用 Vue 2 的预设。
    • 它包含了一些常见的开发工具和库,如 Babel、Vue Router 和 Vuex。
    • 这是一个较完整的 Vue 2 项目模板,适合需要使用路由和状态管理的项目。
  2. Default ([Vue 3] babel, eslint):
    • 这个选项代表一个默认的 Vue 3 项目。
    • 它包含了 Babel 和 ESLint,用于处理 JavaScript 代码的转换和静态代码分析。
    • 这个选项是较为基础的 Vue 3 项目模板,适合希望快速开始项目开发的用户。
  3. Default ([Vue 2] babel, eslint):
    • 这个选项代表一个默认的 Vue 2 项目。
    • 它也包含了 Babel 和 ESLint,类似于 Vue 3 的默认选项,但使用的是 Vue 2。
    • 这个选项适合希望在 Vue 2 环境下快速开始项目开发的用户。
  4. Manually select features:
    • 这个选项允许您手动选择要包含在项目中的功能。
    • 您可以根据自己的需求选择是否包含 Babel、Router、Vuex、ESLint、测试工具等。
    • 这种方式提供了更大的灵活性,适合对项目有特殊需求的用户。

image-20240507145412327

  • Babel: Babel 是一个 JavaScript 编译器,它可以将新版本的 JavaScript 代码转换为向后兼容的旧版本,以便在各种浏览器和环境中运行。
  • TypeScript: TypeScript 是 JavaScript 的一个超集,它添加了静态类型检查和其他一些特性,有助于提高代码的可维护性和安全性。
  • Progressive Web App (PWA) Support: 允许您将应用程序转换为渐进式 Web 应用程序,这样用户就可以在离线时访问它们,并享受其他 PWA 的优点。
  • Router: Vue Router 是 Vue.js 的官方路由器,它允许您在单页应用程序中实现导航和页面路由。
  • Vuex: Vuex 是 Vue.js 的官方状态管理库,用于管理应用程序中的共享状态。
  • CSS Pre-processors: 允许您选择在项目中使用的 CSS 预处理器,如 Sass、Less 或 Stylus。
  • Linter / Formatter: 允许您选择是否在项目中包含代码检查工具和格式化工具,如 ESLint 和 Prettier,以确保代码质量和一致性。
  • Unit Testing: 允许您选择是否在项目中包含单元测试工具,以确保代码的功能性正确性。
  • E2E Testing: 允许您选择是否在项目中包含端到端(E2E)测试工具,用于模拟用户操作并测试应用程序的完整性和正确性。

image-20240507145940253

  • 选择版本3.x还是2.x

image-20240507150010581

在这里插入图片描述

  • Check the features needed for your project: 这是您选择项目所需功能的部分。您已选择了 Babel、Router 和 Vuex,这意味着您的项目将包含这三个功能:Babel 用于 JavaScript 编译,Router 用于页面导航,Vuex 用于状态管理。
  • Choose a version of Vue.js that you want to start the project with: 这是选择您想要使用的 Vue.js 版本的部分。您选择了 3.x,表示您希望从 Vue.js 3.x 版本开始项目开发。
  • Use history mode for router? (Requires proper server setup for index fallback in production): 这个选项询问您是否要在路由器中使用历史模式。选择 “Yes” 意味着您希望在路由器中启用历史模式。历史模式使用 HTML5 History API 来管理路由,使 URL 更加美观,并且不带有 # 符号。但是,需要在生产环境中正确配置服务器以处理路由的后备。如果选择 “No”,则将使用默认的哈希模式。
  • Where do you prefer placing config for Babel, ESLint, etc.?: 这个选项询问您偏好将 Babel、ESLint 等配置放在哪里。您选择了将配置放在 package.json 文件中。这意味着相关的配置将作为 package.json 文件的一部分,并且不会创建额外的配置文件。这种方式可以使项目更加简洁,但也可能会导致 package.json 文件变得臃肿,取决于配置的复杂程度。如果选择 “In dedicated config files”,则会为每个配置项创建单独的配置文件,使项目结构更清晰,但可能会增加一些文件数量。

在这里插入图片描述

image-20240507150233743

全过

image-20240507150419258

image-20240507150451555

【 2 】Vue2跟Vue3的区别

​ 先来说说当下市场开发使用的问题,目前2021年使用vue3开发的企业还是少,基本上都还是以vue2的形式进行开发,vue3的开发模式跟react很像,这时候有人就会想那我学vue3有用么,淦,他喵的,先别激动,冷静听我说说,vue3对于现在企业来说都在慢慢的把一些vue2的东西进行升级,这个非常关键,因为vue2中可以使用vue3的方法,vue3不能使用vue2,你连vue2都没有搞定,还拿个锤子去搞vue3,我们先来看看vue3和vue2的一些区别

image-20240507151338959

【 1 】webpack和vite

vue2使用的是webpack形式去构建项目
webpack是一开始是入口文件,然后分析路由,然后模块,最后进行打包,然后告诉你,服务器准备好了可以开始干了

vue create vue3
注意选择vue3,其他都一样
  • ​ webstorm打开–》配置启动
//配置npm 镜像站
// npm config set registry https://registry.npmmirror.com
// npm config get registry

vue3使用vite构建项目
先告诉你服务器准备完成,然后等你发送HTTP请求,然后是入口文件,Dynamic import(动态导入)code split point(代码分割)

​ 最大的好处和区别就是为了让项目中一些代码文件多了以后去保存更新数据时更快能够看到实际效果,也就是所谓的(热更新)

什么是vite?— 新一代前端构建工具。

  • 优势如下:
  • 开发环境中,无需打包操作,可快速的冷启动。
  • 轻量快速的热重载(HMR)。
  • 真正的按需编译,不再等待整个应用编译完成。
  • 传统构建 与 vite构建对比图

兼容性注意

  • Vite 需要 Node.js 版本 18+,20+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本
  • 官网:https://cn.vitejs.dev/

创建工程

  • 不指定名字创建:npm create vite@latest

    • 配置npm镜像站:npm config set registry https://registry.npmmirror.com
    • 查看镜像站:npm config get registry
  • 指定名字创建

    • # 创建项目方式一
      npm create vite@latest
      # 创建项目方式二:指定名字
      npm create vite@latest vue3_demo002
      # 创建项目方式三
      cnpm create vite@latest vue3_demo002
      # 创建项目方式四
      cnpm create vite vue3_demo002
      
  • 使用编辑器打开vue项目

  • npm的配置

    • 在这里插入图片描述
  • 安装依赖

    npm install

  • 运行项目

    npm run dev

【 2 】main.js文件

  • vue2中我们可以使用pototype(原型)的形式去进行操作,引入的是构造函数

  • import Vue from 'vue'
    import App from './App.vue'Vue.config.productionTip = falsenew Vue({render: h => h(App),
    }).$mount('#app')
    
  • vue3中需要使用结构的形式进行操作,引入的是工厂函数

    • import { createApp } from 'vue'
      import App from './App.vue'createApp(App).mount('#app')
      
  • vue3app组件中可以没有根标签

  • <template><!-- Vue3组件中的模板结构可以没有根标签 --><img alt="Vue logo" src="./assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/>
    </template>
    

【 3 】API风格

API 风格

​ Vue 的组件可以按两种不同的风格书写:选项式 API组合式 API

选项式 API (Options API)

​ 使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 datamethodsmounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。

<script>
export default {// data() 返回的属性将会成为响应式的状态// 并且暴露在 `this` 上 data() {return {count: 0}},// methods 是一些用来更改状态与触发更新的函数// 它们可以在模板中作为事件处理器绑定methods: {increment() {this.count++}},// 生命周期钩子会在组件生命周期的各个不同阶段被调用// 例如这个函数就会在组件挂载完成后被调用mounted() {console.log(`The initial count is ${this.count}.`)}
}
</script><template><button @click="increment">Count is: {{ count }}</button>
</template>

​ 通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 `` 搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。

​ 下面是使用了组合式 API 与 <script setup> 改造后和上面的模板完全一样的组件:

<script setup>
import { ref, onMounted } from 'vue'// 响应式状态
const count = ref(0)// 用来修改状态、触发更新的函数
function increment() {count.value++
}// 生命周期钩子
onMounted(() => {console.log(`The initial count is ${count.value}.`)
})
</script><template><button @click="increment">Count is: {{ count }}</button>
</template>

【 4 】箭头函数

  1. 匿名函数: 使用function关键字定义的普通匿名函数。

    var f = function(name) {console.log(name);
    };
    f('jing');
    
  2. 无参数无返回值的箭头函数:

    var f1 = () => {console.log('这个就是箭头函数');
    };
    f1();
    
  3. 有多个参数无返回值的箭头函数:

    var f2 = (name, age) => {console.log(name, age);
    };
    f2();
    
  4. 有一个参数无返回值的箭头函数:

    var f3 = name => {console.log(name);
    };
    f3('jingyexiao');var f3 = () => {};
    f3();
    
  5. 有一个参数,一个返回值的箭头函数:

    var f4 = name => {return name + '_nb';
    };
    f4('jianshu');
    

    这个可以简写成:

    var f5 = name => name + '_nb';
    var res = f5('jianshu');
    console.log(res);
    
  6. 箭头函数内部的this 箭头函数内部没有自己的this,会继承外层作用域的this

// 在全局作用域下定义一个对象
const obj = {name: 'Alice',getNameRegular: function() {return this.name; // 正常函数中的this指向当前对象obj},getNameArrow: () => {return this.name; // 箭头函数中的this继承自外层作用域,在这里指向全局作用域的this(通常是window对象)}
};console.log(obj.getNameRegular()); // 输出: "Alice",正常函数中的this指向obj对象
console.log(obj.getNameArrow()); // 输出: undefined,箭头函数继承外层作用域的this,在全局作用域中找不到name属性,返回undefined

如果在外部写一个let name = 'yun'

结果就会输出console.log(obj.getNameRegular()); // 输出: "Alice",正常函数中的this指向obj对象
console.log(obj.getNameArrow()); // 输出: yun,

总结

原始的函数声明方式:

var f = function(name) {console.log(name);
};
f('jing');

使用箭头函数:

这里function= =>

var f3 = (name) => {console.log(name);
};
f3('jing');
let f=()=>{}

【 5 】响应式

  • 可以说响应式系统能够保持数据和视图之间的同步,从而实现数据变化的自动渲染。
【 1 】什么是响应式

​ 响应式是指数据在变化时,可以自动同步更新视图和逻辑之间的状态。在前端框架(如Vue.js)中,响应式系统使得数据的变化会自动触发视图的更新,从而保持数据和界面的一致。

具体来说:

  • 数据绑定:响应式数据可以绑定到模板中的HTML元素。当数据变化时,相关的HTML元素会自动更新以反映最新的状态。这就是所谓的视图更新。
  • 双向绑定:前端框架通常提供双向绑定机制,让数据的变化能够自动反映到界面上,而用户在界面上输入或修改数据时,也会自动更新数据。这是响应式的一部分。
  • 监控数据变化:响应式系统通过监控数据的变化(通常是通过访问或设置对象属性),在数据发生改变时触发相应的更新操作。这些更新可以是界面上的元素、其他数据、或者是逻辑处理。

​ 因此,可以说响应式系统能够保持数据和视图之间的同步,从而实现数据变化的自动渲染。

【 2 】vue3的响应式原理
  • Vue 的响应式系统设计思路

​ 虽然 Vue 2 与 Vue 3 实现响应式系统的方式不同,但是他们的核心思想还是一致的,都是通过 发布-订阅模式 来实现(因为发布者和观察者之间多了一个 dependence 依赖收集者,与传统观察者模式不同)。

个人理解,观察者模式发布-订阅模式 都是 消息传递的一种实现方式,用来实现 对象间的通信(消息传递),只是发布订阅模式可以看做是观察者模式的 升级版,避免了 被观察对象与观察者之间的直接联系

​ 观察者模式:一个被观察对象对应多个观察者,两者直接联系;被观察这改变时直接向所有观察者发送消息(调用观察者的更新方法)

  • Vue 3 的响应式实现

​ 碍于 Object.defineProperty 的局限性,Vue 3 采用了全新的 Proxy 对象来实现整个响应式系统基础。

  • 什么是 Object.defineProperty

Object.defineProperty 是 JavaScript 中用于在对象上定义或修改属性的方法。它可以让你对对象的属性进行精确的控制,包括可写性、可枚举性、可配置性等。Object.defineProperty 提供了一种更详细和灵活的方式来控制对象属性的行为,而不仅仅是简单地赋值。

基本用法:

const person = {};// 使用 Object.defineProperty 定义一个属性
Object.defineProperty(person, 'name', {value: 'John',writable: false, // 该属性是否可写enumerable: true, // 该属性是否可枚举configurable: false // 该属性是否可重新定义或删除
});console.log(person.name); // 输出 "John"// 尝试修改属性值
person.name = 'Jane';
console.log(person.name); // 仍然输出 "John",因为 writable 设置为 false// 尝试删除属性
delete person.name;
console.log(person.name); // 仍然输出 "John",因为 configurable 设置为 false

通过 Object.defineProperty,你可以设置以下属性选项:

  • value: 属性的初始值。
  • writable: 如果设置为 true,则该属性可以被修改;否则不可修改。
  • enumerable: 如果设置为 true,则该属性可以在循环遍历中显示;否则不会显示在循环中。
  • configurable: 如果设置为 true,则该属性可以被删除或更改其特性;否则不可更改。

​ Vue 2 使用 Object.defineProperty 来实现响应式系统。它通过为对象的每个属性设置 getter 和 setter,以检测和响应属性的变化。这样,当你更改某个属性时,Vue 2 的响应式系统就可以检测到,并触发相关的更新。

  • 什么是 Proxy

ProxyES6 新增的一个构造函数,用来创建一个 目标对象的代理对象,拦截对原对象的所有操作;用户可以通过注册相应的拦截方法来实现对象操作时的自定义行为

​ 目前 Proxy 支持的拦截方法包含一下内容:

  • get(target, propKey, receiver):拦截对象属性的读取操作;
  • set(target, propKey, value, receiver):拦截对象属性的赋值操作;
  • apply(target, thisArg, argArray):拦截函数的调用操作;
  • construct(target, argArray, newTarget):拦截对象的实例化操作;
  • has(target, propKey):拦截 in 操作符;
  • deleteProperty(target, propKey):拦截 delete 操作符;
  • defineProperty(target, propKey, propDesc):拦截 Object.defineProperty 方法;
  • getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor 方法;
  • getPrototypeOf(target):拦截 Object.getPrototypeOf 方法;
  • setPrototypeOf(target, proto):拦截 Object.setPrototypeOf 方法;
  • isExtensible(target):拦截 Object.isExtensible 方法;
  • preventExtensions(target):拦截 Object.preventExtensions 方法;
  • enumerate(target):拦截 for...in 循环;
  • ownKeys(target):拦截 Object.getOwnPropertyNamesObject.getOwnPropertySymbolsObject.keysJSON.stringify 方法。

我们基本上用上的就是set、get这两种方法

  • Vue3跟Vue2的响应式的区别

  1. Proxy 替代 Object.defineProperty:
    • 在 Vue 2 中,使用了 Object.defineProperty 来劫持对象的属性,实现响应式。
    • 而在 Vue 3 中,利用了 JavaScript 的 Proxy 对象来完成相同的任务。Proxy 提供了更强大和灵活的拦截能力,相较于 Object.defineProperty,Proxy 更容易追踪对象的变化。
  2. 性能优化:
    • Vue 3 在响应式系统的内部做了很多性能优化,包括更好的缓存策略和剪枝优化,以提高大型应用程序的性能表现。
    • 由于 Proxy 的使用,Vue 3 的响应式系统在某些情况下可能比 Vue 2 更快。
  3. Composition API:
    • Vue 3 引入了 Composition API,它提供了一种新的组织组件代码的方式。与 Vue 2 的选项 API 相比,Composition API 允许更灵活地组合和重用逻辑,同时也更容易测试和维护。
  4. Tree-shaking 支持:
    • Vue 3 的响应式系统被设计成更容易进行 tree-shaking,使得在构建时能更有效地剔除未使用的代码,减小应用程序的体积。

​ 总的来说,Vue 3 的响应式实现相较于 Vue 2 在性能、灵活性和易用性上都有所提升,这些改进使得 Vue 3 更适合构建大型和高性能的应用程序。

总结:

'''
vue2 用data中定义在用this响应出来
vue3就是用setup 中使用  导入	import {ref,reactive} from "vue"; 用let name = ref('JIng');或者是recative'''

悟吧!!!

【 6 】ref跟reactive

  • ref 包裹值类型[数字,字符串,布尔],做成响应式

  • reactive包裹引用类型[对象,数组],做成响应式

  • 使用reactive包裹的对象,直接通过 . [] 取值赋值就是响应式的

    • ref包裹的对象,需要使用 对象.value 修改值
  • 使用ref包裹的,在template中,不许用使用 变量.value

【 1 】ref与reactive区别
  • ref定义的是基本数据类型

  • ref通过Object.defineProperty()的get和set实现数据劫持

  • ref操作数据.value,读取时不需要。value

  • reactive定义对象或数组数据类型

  • reactive通过Proxy实现数据劫持

  • reactive操作和读取数据不需要.value

【 2 】两者的使用方法
<script>
import { reactive } from "vue";export default {setup() {const state = reactive({name: 'Jing',age: 25,email: 'jing@example.com'});return {state};}
};
</script>
<script>
import { ref } from "vue";export default {setup() {// 使用ref函数创建一个响应式引用const name = ref('Jing');// 将响应式引用返回,使其在模板中可用return {name};}
};
</script>

【 7 】setup函数

  1. setup函数必须要return返回出去

  2. setup为Vue3.0中一个新的配置项,值为一个函数

  3. setup是所有Composition API(组合API)编写的位置

  4. 组件中所用到的:数据、方法等等,均要配置在setup中

  5. setup函数的返回值:返回一个对象,对象中的属性、方法, 在模板中均可以直接使用

  6. 注意:

    尽量不要与Vue2.x配置混用

    • Vue2.x配置(data、methos、computed…)中可以访问到setup中的属性、方法。

    • 但在setup中不能访问到Vue2.x配置(data、methos、computed…)。

    • 如果有重名, setup优先。

    • ref的使用方法

<template><div class="about"><h1>姓名:{{ name }}</h1><h1>年龄:{{ age }}</h1><button @click="handadd">点击加年龄</button><button @click="handname">点击田女士</button></div>
</template><script>
import {ref,reactive} from "vue";export default {name: 'AboutView',setup() {let name = ref('JIng');let age = ref(26);const handadd = () => {age.value++;};const handname = () => {name.value = '你好我好大家好!!!';};return {name,age,handadd,handname};}}</script>

image-20240507170603634

  • recative的使用方法

    • 注意就是返回的响应格式跟渲染方法

      return {rec,handadd,handname};
      
    • <h1>姓名:{{ rec.name }}</h1>
      <h1>年龄:{{ rec.age }}</h1>
      
<template><div class="about"><h1>姓名:{{ rec.name }}</h1><h1>年龄:{{ rec.age }}</h1><button @click="handadd">点击加年龄</button><button @click="handname">点击修改姓名</button></div>
</template><script>
import { reactive } from "vue";export default {name: 'AboutView',setup() {// 使用reactive创建包含姓名和年龄的响应式对象const rec = reactive({name: 'Jing', // 直接赋值age: 25 // 直接赋值});// 定义增加年龄的方法const handadd = () => {console.log(rec.name);console.log(rec.age);rec.age++; // 递增年龄console.log(rec.age); // 打印递增后的年龄};// 定义修改姓名的方法const handname = () => {rec.name = '你好我好大家好!!!'; // 修改姓名};// 将响应式对象和方法返回,使其在模板中可用return {rec,handadd,handname};}
}
</script>

在这里插入图片描述

【 8 】计算属性

  • 缓存: 计算属性默认是有缓存的,只有当依赖的响应式属性发生改变时,它们才会重新计算。这样可以避免不必要的重复计算,提高性能。
  • 响应式: 计算属性会自动响应其依赖的响应式属性的变化,当依赖的属性发生改变时,计算属性会重新计算其值。

计算属性中重要的就是它的缓存机制

vue中的计算属性的好处就是我比如在设置了一个input标签里写了计算属性之后 别的组件发生改变我的input标签也不会发生改变

<template><div><h2>购物车</h2><ul><li v-for="(item, index) in cart" :key="index">{{ item.name }} - 单价: {{ item.price }}元 - 数量: {{ item.quantity }}</li></ul><p>总价格: {{ total }}</p><button @click="addItem">添加商品</button></div>
</template><script>
import { reactive, computed } from 'vue';export default {setup() {const cart = reactive([{name: '商品1', price: 10, quantity: 2},{name: '商品2', price: 20, quantity: 1},{name: '商品3', price: 30, quantity: 3}]);// 计算总价格的计算属性const total = computed(() => {console.log('重新计算总价格');let totalPrice = 0;cart.forEach(item => {totalPrice += item.price * item.quantity;});return totalPrice;});// 添加商品的方法const addItem = () => {cart.push({name: '新商品', price: 50, quantity: 1});};return {cart,total,addItem};}
};
</script>

image-20240507190357084

【 9 】监听属性

  1. 监听普通属性变化:
    • setup 函数中,使用 reactive 创建一个响应式对象,例如:const rec = reactive({ age: 266 })
    • 使用 watch 函数监听该普通属性的变化,例如:watch(() => rec.age, (newValue, oldValue) => { /* 处理变化 */ })
    • 在监听函数中,可以访问新旧值来执行相应的操作。
  2. 监听对象属性变化:
    • 使用 refreactive 来创建一个包含对象的响应式引用或响应式对象,例如:const person = ref({ name: "jing", age: 25 })const person = reactive({ name: "jing", age: 25 })
    • 在监听对象属性变化时,确保使用 person.value 来访问对象的属性,例如:watch(() => person.value.name, (newValue, oldValue) => { /* 处理变化 */ })
    • 监听函数将在对象属性的值变化时被调用。
  3. 监听多个属性变化:
    • setup 函数中,创建一个包含多个属性的响应式对象,例如:const res = reactive({ sum: 250, msg: "你很好!!" })
    • 使用 watch 函数来同时监听多个属性的变化,例如:watch([() => res.sum, () => res.msg], ([newSum, newMsg], [oldSum, oldMsg]) => { /* 处理变化 */ })
    • 监听函数将在任一被监听属性的值变化时被调用,传递新旧值作为参数。
  • 原始的写法

<template><div><!-- 显示普通属性的值 --><p>年龄:{{ rec.age }}</p><button @click="handadd">点击加年龄</button><!-- 显示对象属性的值 --><p>姓名:{{ person.name }}</p><button @click="handname">点我</button><!-- 显示多个属性的值 --><p>总和:{{ res.sum }}, 消息:{{ res.msg }}</p><button @click="handsum">点我</button></div></template><script>
import { ref, reactive, watch } from "vue";export default {name: "JianView",setup() {// 监听普通属性const rec = reactive({age: 266,});const handadd = () => {console.log(rec.age);rec.age++; // 递增年龄console.log(rec.age); // 打印递增后的年龄};// 监听 rec.age 的变化watch(() => rec.age, (newValue, oldValue) => {console.log('age这个值变化了', newValue, oldValue);});// 监听对象属性const person = ref({name: "jing",age: 25,});const handname = () => {console.log(person.value.name);person.value.name = '云';console.log(person.value.name);};watch( () =>person.value.name, (newValue, oldValue) => {console.log('注意观察person.value.name变化了', newValue,oldValue);});//监听多个属性const res = reactive({sum: 250,msg: "你很好!!"});const handsum = () => {console.log(res.sum);console.log(res.msg);res.sum = 2555; // 递增年龄res.msg = '九日'; // 递增年龄console.log(res.sum); // 打印递增后的年龄console.log(res.msg);};watch([() => res.sum, () => res.msg], ([newSum, newMsg], [oldSum, oldMsg]) =>  {console.log("sum或者msg变化了", newSum, newMsg,oldMsg,oldSum);});return {rec,person,res,handadd,handname,handsum}}
}
</script><style></style>

在这里插入图片描述

image-20240507202952501

  • watchEffect方法

watch 不同,watchEffect 没有明确的监听目标,而是会自动追踪其内部使用的所有响应式变量,这使得它在处理一些复杂场景时非常方便。

export default {name: "JianView",setup() {// 监听普通属性const rec = reactive({age: 266,});const handadd = () => {console.log(rec.age);rec.age++; // 递增年龄console.log(rec.age); // 打印递增后的年龄};// 使用 watchEffect 监听 rec.age 的变化watchEffect(() => {console.log('age 这个值变化了', rec.age);});// 监听对象属性const person = ref({name: "jing",age: 25,});const handname = () => {console.log(person.value.name);person.value.name = '云';console.log(person.value.name);};// 使用 watchEffect 监听 person.value.name 的变化watchEffect(() => {console.log('注意观察 person.value.name 变化了', person.value.name);});//监听多个属性const res = reactive({sum: 250,msg: "你很好!!"});const handsum = () => {console.log(res.sum);console.log(res.msg);res.sum = 2555; // 递增年龄res.msg = '九日'; // 递增年龄console.log(res.sum); // 打印递增后的年龄console.log(res.msg);};// 使用 watchEffect 监听 res.sum 和 res.msg 的变化watchEffect(() => {console.log("sum 或者 msg 变化了", res.sum, res.msg);});return {rec,person,res,handadd,handname,handsum};}
};

image-20240507203607615

【 10 】生命周期

image-20240507192128297

vue2           ------->      vue3beforeCreate   -------->      setup(()=>{})
created        -------->      setup(()=>{})
beforeMount    -------->      onBeforeMount(()=>{})
mounted        -------->      onMounted(()=>{})
beforeUpdate   -------->      onBeforeUpdate(()=>{})
updated        -------->      onUpdated(()=>{})
beforeDestroy  -------->      onBeforeUnmount(()=>{})
destroyed      -------->      onUnmounted(()=>{})
activated      -------->      onActivated(()=>{})
deactivated    -------->      onDeactivated(()=>{})
errorCaptured  -------->      onErrorCaptured(()=>{})

总结: Vue2和Vue3钩子变化不大,beforeCreate 、created 两个钩子被setup()钩子来替代。

<template><div class="home"><h1>生命周期</h1><h3>年龄是:{{ age }}</h3><button @click="addAge">点击age+1</button></div>
</template><script>import {ref, reactive, watch, watchEffect,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'export default {name: 'HomeView',setup() {// 生命周期钩子// 1 写在这里是就是beforeCreateconsole.log('beforeCreate')const age=ref(26)function addAge(){age.value++}//2 写在这里是就是createdconsole.log('created',age.value)//3 beforeMount-->onBeforeMount// onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmountedonBeforeMount(()=>{console.log('onBeforeMount','组件挂载前')})//4 mounted-->onMountedonMounted(()=>{console.log('onMounted','组件挂载后')})//5 beforeUpdate-->onBeforeUpdateonBeforeUpdate(()=>{console.log('onBeforeUpdate','更新之前')})//6 updated-->onUpdatedonUpdated(()=>{console.log('onUpdated','更新之后')console.log(age.value)})//7 beforeUnmount-->onBeforeUnmountonBeforeUnmount(()=>{console.log('onBeforeUnmount','销毁之前')})//8 unmounted-->onUnmountedonUnmounted(()=>{console.log('onUnmounted','销毁后')})return {age,addAge}},}
</script>

image-20240507192522354

【 11 】toRef

  • 作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
  • 语法:const name = toRef(person,'name')
  • 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
  • 扩展:toRefstoRef功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)

toRef是将原始对象中的指定属性创建为一个新的 ref 对象。这个 ref 对象会保持响应性,即当原始对象的属性发生变化时,这个 ref 对象的值也会相应地更新。

  • 基本使用

就是要先定义一个响应对象

import { reactive, toRef } from 'vue';
const person = reactive({name: 'Alice',age: 30,
});

在使用toRef 创建一个指向 person.name 的 ref 对象

const nameRef = toRef(person, 'name');

​ 现在,你可以在其他组件或函数中使用 nameRef当 person.name 变化时,nameRef 的值也会随之更新。

具体示例

  • toRef的使用方法

  • import { ref,reactive,toRef } from "vue";  
    ...
    const nameRef = toRef(rec,"name");
    
<template><div class="about"><h1>姓名:{{ rec.name }}</h1><button @click="handadd">更改年龄</button><br><hr>
</template><script>
import { ref,reactive,toRef } from "vue";export default {name: 'AboutView',setup() {// 使用reactive创建包含姓名和年龄的响应式对象const rec = reactive({name: 'Jing', // 直接赋值age: 25 // 直接赋值});const nameRef = toRef(rec,"name");const handadd = () => {console.log(rec.name);console.log(nameRef.value);nameRef.value = '宠物小精灵!!!';console.log(nameRef.value);};// 将响应式对象和方法返回,使其在模板中可用return {rec,handadd,};}
}
</script>

image-20240507212620565

  • toRefs的使用方法

    import { ref,reactive,toRefs } from "vue"; ...
    const {name,age} = toRefs(rec);
    
<template><div class="about"><h1>姓名:{{ rec.name }}</h1><button @click="handadd">更改年龄</button><br><hr><h1>年龄:{{ rec.age }}</h1><button @click="handage">修改年龄</button></div>
</template><script>
import { ref,reactive,toRefs } from "vue";export default {name: 'AboutView',setup() {// 使用reactive创建包含姓名和年龄的响应式对象const rec = reactive({name: 'Jing', // 直接赋值age: 25 // 直接赋值});// 使用toRefs创建对rec的引用对象const {name,age} = toRefs(rec);const handadd = () => {console.log(rec.name);console.log(name.value);name.value = '宠物小精灵!!!';console.log(name.value);};const handage = () => {console.log(age.value);age.value = 266;console.log(age.value);};// 将响应式对象和方法返回,使其在模板中可用return {rec,handadd,handage};}
}
</script>

image-20240507212452517

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/29225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超高清图像生成新SOTA!清华唐杰教授团队提出Inf-DiT:生成4096图像比UNet节省5倍内存。

清华大学唐杰教授团队最近在生成超高清图像方面的新工作&#xff1a;Inf-DiT&#xff0c;通过提出一种单向块注意力机制&#xff0c;能够在推理过程中自适应调整内存开销并处理全局依赖关系。基于此模块&#xff0c;该模型采用了 DiT 结构进行上采样&#xff0c;并开发了一种能…

【Linux】进程_8

文章目录 五、进程10. 进程等待阻塞等待和非阻塞等待 11. 进程程序替换 未完待续 五、进程 10. 进程等待 上一篇我们知道了 wait 和 waitpid 函数都有一个 status 参数&#xff0c;这个参数是什么呢&#xff1f;这个参数其实就是进程的返回结果&#xff0c;当子进程结束的时候…

MySQL-----JOIN语句之内连接

在我们使用MySQL进行项目的开发过程中&#xff0c;仅仅对一张表进行操作是远远不够的&#xff0c;真正的应用中经常需要从多个数据表中读取数据。我们在使用的过程中&#xff0c;尝尝通过 SELECT, UPDATE 和 DELETE 语句配合使用 JOIN 来联合多表查询。 JOIN 分类 INNER JOIN…

【5.x】ELK日志分析、集群部署

ELK日志分析 一、ELK概述 1、ELK简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将ElasticSearch、Logstash和Kiabana三个开源工具配合使用&#xff0c;完成更强大的用户对日志的查询、排序、统计需求。 一个完整的集中式日志系统&#xff0c;需要包含以下几个主…

中国星网时空信息集团春招Offer面经

本文介绍2024届春招中&#xff0c;中国卫星网络集团有限公司下属中国时空信息集团有限公司中&#xff0c;业务助理岗位1场面试的基本情况、提问问题等。 2024年04月投递了中国卫星网络集团有限公司下属中国时空信息集团有限公司中的业务助理岗位&#xff0c;所属部门为运营中心…

基于jeecgboot-vue3的Flowable流程-所有任务

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 这个部分主要讲所有任务的功能 1、主要列表界面如下&#xff1a; <template><div class"p-2"><!--查询区域--><div class"jeecg-basic-table-form-…

艾伦脑图谱(Allen Brain Atlas)

文章目录 一、艾伦研究所&#xff08;Allen Institute&#xff09;1.1、艾伦脑图谱&#xff08;Allen Brain Map&#xff09;1.1.1、艾伦&#xff08;小鼠大脑&#xff09;通用坐标框架&#xff08;Allen Mouse Brain Common Coordinate Framework&#xff0c;CCFv3&#xff09…

Elasticsearch-使用Logstash同步Mysql

1.安装logstash es服务器版本必须和logstash版本一致 7.9.2 在/usr/local/src/下新建logstash文件夹&#xff0c;解压 下载logstash后查看是否安装成功&#xff0c;在logstash的bin目录下输入指令&#xff1a; ./logstash -e input { stdin { } } output { stdout {} }2.my…

NAND闪存市场彻底复苏

在全球内存市场逐渐走出阴霾、迎来复苏曙光之际&#xff0c;日本存储巨头铠侠&#xff08;Kioxia&#xff09;凭借敏锐的市场洞察力和及时的战略调整&#xff0c;成功实现了从生产紧缩到全面复苏的华丽转身。这一转变不仅彰显了企业在逆境中的生存智慧&#xff0c;也为全球半导…

OSPF 动态路由协议(思科、华为)

#交换设备 OSPF 动态路由协议 一、基本概念 1.中文翻译&#xff1a;开放式最短路径优先路由协议&#xff08;open shortest path first&#xff09;&#xff0c;是一个内部网关路由协议&#xff08;一个自治系统内&#xff09;2.也称为&#xff1a;链路状态路由协议&#xf…

VirtualBox 安装UOS统信服务器操作系统

1、准备 1.1安装VirtualBox 由于过程简单&#xff0c;不做赘述&#xff01; 1.2下载UOS服务器版本 下载免费版本即可 服务器与云计算操作系统-统信软件 (uniontech.com)https://uniontech.com/os-serverCloud.html 2、安装 2.1新建虚拟机 2.2选择虚拟机模式&#xff0c;这…

船舶行业信息安全解决方案介绍

船舶行业信息安全背景&#xff1a; 近年来随着经济复苏、疫情与国际形势影响国内外船舶海运业务蓬勃发展&#xff0c;在业务量激增的背景下出现多类信息安全事件。其中2017年&#xff0c;马士基集团遭到勒索软件攻击&#xff0c;内部业务系统和码头操作系统均受到严重影响&…

spring注解驱动系列-- spring容器创建原理

从源码开始探究spring容器的创建原理&#xff0c;下面是源码总步骤 Override public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subc…

利用反向代理编写HTTP抓包工具——可视化界面

手写HTTP抓包工具——可视化界面 项目描述语言golang可视化fynev2功能代理抓包、重发、记录 目录 1. 示例1.1 主界面1.2 开启反向代理1.3 抓包1.4 历史记录1.5 重发 2. 核心代码2.1 GUI2.1 抓包 3. 结语3.1 传送门 1. 示例 1.1 主界面 1.2 开启反向代理 1.3 抓包 1.4 历史记录…

两行css 实现瀑布流

html <ul ><li><a href"" ><img src"05094532gc6w.jpg" alt"111" /><p>传奇</p></a></li><li><a href"" ><img src"05094532gc6w.jpg" alt"111"…

汽车EDI:波森Boysen EDI项目案例

企业A作为Boysen 的供应商&#xff0c;为了响应Boysen的号召&#xff0c;需要与其实现EDI对接。由于企业A此前并没有EDI项目的实施经验&#xff0c;对EDI项目的实施流程、技术要求等内容不知道应该从何下手。 为了实现EDI对接意味着企业A需要具备自己的EDI系统&#xff0c;从而…

佑友FHQ backup 后台任意文件读取漏洞复现

0x01 产品简介 佑友FHQ是一款专业的网络安全设备,用于保护企业网络免受各种网络威胁和攻击。其功能包括流量过滤、入侵检测与阻断、应用程序控制、虚拟专用网络(VPN)支持等。通过深度包检测和实时流量分析,佑友防火墙能够及时识别和阻止潜在的威胁,提供全面的安全保护。同…

vue中axios从content-disposition响应头获取中文名

在Vue中使用axios请求文件时&#xff0c;服务器可能会返回带有Content-Disposition响应头的文件&#xff0c;其中可能包含文件名的编码信息。如果你需要解码这个文件名&#xff0c;可以使用JavaScript的内置URL API来处理。 Java中用于设置HTTP响应头的&#xff0c;通常在Web开…

浏览器开发公司Brave 将自己的搜索结果与其 Leo AI 助手集成

Brave Software是一家开发浏览器的公司&#xff0c;其主要产品是Brave浏览器。Brave浏览器基于Chromium项目开发&#xff0c;具有高性能和隐私保护的特点。此外&#xff0c;Brave浏览器还提供了“off record”模式&#xff0c;允许用户在不记录浏览历史的情况下使用浏览器。关于…

C# Secs源码 HsmsSecs测试

包含客户端和服务端 启动客户端和服务端即可互相模拟sece 通讯 也可使用secs仿真器进行测试 开启后进行相关操作&#xff0c;创建客户端连接仿真器进行操作 仿真器显示日志 相关文件&#xff0c;源码 4.9 私信即可或者看我博客描述那个地址 我是狗子&#xff0c;希望你幸…