vue3的基本使用方法

news2024/11/26 16:46:05

【 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 = false
    
    new 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           ------->      vue3
 
beforeCreate   -------->      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 写在这里是就是beforeCreate
    console.log('beforeCreate')

    const age=ref(26)
    function addAge(){
      age.value++
    }

    //2 写在这里是就是created
    console.log('created',age.value)

    //3 beforeMount-->onBeforeMount
    // onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted
    onBeforeMount(()=>{
      console.log('onBeforeMount','组件挂载前')
    })
    //4 mounted-->onMounted
    onMounted(()=>{
      console.log('onMounted','组件挂载后')
    })
    //5 beforeUpdate-->onBeforeUpdate
    onBeforeUpdate(()=>{
      console.log('onBeforeUpdate','更新之前')
    })
    //6 updated-->onUpdated
    onUpdated(()=>{
      console.log('onUpdated','更新之后')
      console.log(age.value)
    })

    //7 beforeUnmount-->onBeforeUnmount
    onBeforeUnmount(()=>{
      console.log('onBeforeUnmount','销毁之前')
    })

    //8 unmounted-->onUnmounted
    onUnmounted(()=>{
      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.coloradmin.cn/o/1833607.html

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

相关文章

如何在纯内网环境下,将EasyCVR视频汇聚网关通过4G与第三方公网云平台级联?

EasyCVR视频汇聚网关是TSINGSEE青犀软硬一体的一款产品&#xff0c;可提供多协议的接入、音视频采集、处理&#xff0c;能实现海量前端设备的轻量化接入/转码/分发、视频直播、云端录像、云存储、检索回看、智能告警、平台级联等&#xff0c;兼容多种操作系统&#xff0c;轻松扩…

基于CentOS的全新Linux机器安装Jenkins并生成Allure报告

目录 一、安装Docker 二、安装Docker Compose 三、准备测试用例 四、配置docker-compose.yml 五、启动Jenkins 六、配置Jenkins和Allure插件 七、创建含pytest的Jenkins任务 一、安装Docker 在CentOS上&#xff0c;首先更新包管理工具并安装所需的包。 sudo yum update…

Python将字符串用特定字符分割并前面加序号

Python将字符串用特定字符分割并前面加序号 Python将字符串用特定字符分割并前面加序号&#xff0c;今天项目中就遇到&#xff0c;看着不难&#xff0c;得花点时间搞出来急用啊&#xff0c;在网上找了一圈&#xff0c;没发现有完整流程的文章。所以就搞出来并写了这个文章。仅…

02 - matlab m_map地学绘图工具基础函数 - m_proj

02 - matlab m_map地学绘图工具基础函数 - m_proj 0. 引言1. 查看所有投影方式3. 各投影方式绘图示例3.1 极射赤面投影法&#xff08;Stereographic &#xff09;3.2 Orthographic 正射投影示例3.3 Azimuthal Equal-area 方位等面积投影3.4 Azimuthal Equidistant 等距方位投影…

[C++][数据结构][哈希表]详细讲解

目录 1.哈希概念2.哈希冲突3.哈希函数4.哈希冲突解决5.闭散列1.何时扩容&#xff1f;如何扩容&#xff1f;2.线性探测3.二次探测 6.开散列(哈希桶)1.概念2.开散列增容3.开散列思考只能存储key为整形的元素&#xff0c;其他类型怎么解决&#xff1f;除留余数法&#xff0c;最好模…

新手如何入门Web3?

一、什么是Web3&#xff1f; Web3是指下一代互联网&#xff0c;它基于区块链技术&#xff0c;致力于将各种在线活动变得更加安全、透明和去中心化。Web3是一个广义的概念&#xff0c;涵盖了包括数字货币、去中心化应用、智能合约等在内的多个方面。它的主要特点包括去中心化、…

C++初学者指南第一步---5.介绍std::vector

C初学者指南第一步—5.介绍std::vector 目录 C初学者指南第一步---5.介绍std::vector1.初始化/访问2.添加元素3.Resizing调整大小4.在尾部删除元素5. 复制一直是深拷贝&#xff01; 注意std代表C标准库的命名空间&#xff0c;vector&#xff08;向量&#xff09;是标准库中的一…

Golang | Leetcode Golang题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; func findPeakElement(nums []int) int {n : len(nums)// 辅助函数&#xff0c;输入下标 i&#xff0c;返回 nums[i] 的值// 方便处理 nums[-1] 以及 nums[n] 的边界情况get : func(i int) int {if i -1 || i n {return math.MinInt64}re…

关于在word中使用Axmath的报错的解决

介绍 Axmath是数学公式编辑器软件。官网如下。 AxMath/AxGlyph/AxCells (amyxun.com) 支持正版。 在word中使用Axmath 点击word中的“文件”→“选项”。 选择“加载项” 选择“word加载项” 在Axmath默认的安装目录如下&#xff1a; C:\Program Files (x86)\AxMathhao&am…

GPTZero:引领AI内容检测

随着人工智能技术的飞速发展,AI生成内容(AIGC)正在迅速改变我们获取和消费信息的方式。然而,AIGC的激增也带来了一系列挑战,尤其是在内容真实性和版权方面。正是在这样的背景下,一家由00后团队创立的公司——GPTZero,以其独特的AI检测工具,迅速崛起为行业的领军者。 一…

AWS Lambda + Flask 应用示例

前言 AWS Lambda 本身是一个以事件驱动的 Serverless 服务, 最简单的应用就是在入口函数中对接收到的事件/请求进行处理并返回响应. 对于像 Flask 这样的 Web 框架, 并不能直接在 Lambda 上提供服务, 不过我们可以借助 AWS Lambda Web Adapter 实现一个基于 Flask 框架的 Web …

SpringBoot配置第三方专业缓存技术jetcache远程缓存方案和本地缓存方案

JetCache 是一个基于 Java 的分布式缓存解决方案&#xff0c;旨在提供高性能和可扩展性。它支持多种后端存储&#xff0c;如 Redis、Hazelcast、Tair 等&#xff0c;可以作为应用程序的缓存层&#xff0c;有效地提升数据访问性能和响应速度。 JetCache 的主要特点包括&#x…

Elasticsearch过滤器(filter):原理及使用

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

AWS——01篇(AWS入门 以及 AWS之EC2实例及简单实用)AWS

AWS——01篇&#xff08;AWS入门 以及 AWS之EC2实例及简单实用&#xff09; 1. 前言 2. 创建AWS账户 3. EC2 3.1 启动 EC2 新实例 3.1.1 入口 3.1.2 设置名称 选择服务 3.1.3 创建密钥对 3.1.4 网络设置——安全组 3.1.4.1 初始设置 3.1.4.2 添加安全组规则&#xff08;开放新…

【数据库编程-SQLite3(三)】Ubuntu下sqlite3的使用

学习分享 1、安装sqlite3命令2、sqlite3点命令3、在Linux命令行下&#xff0c;启动sqlite33.1、编写sql脚本3.2、脚本编写--DDL3.3、进入xxx.db数据库&#xff0c;读取脚本。3.4、再次查看数据库中的表。证明表创建成功。3.5、查看数据表中用户内容3.6、查看表结构3.7、在数据库…

Golang | Leetcode Golang题解之第164题最大间距

题目&#xff1a; 题解&#xff1a; type pair struct{ min, max int }func maximumGap(nums []int) (ans int) {n : len(nums)if n < 2 {return}minVal : min(nums...)maxVal : max(nums...)d : max(1, (maxVal-minVal)/(n-1))bucketSize : (maxVal-minVal)/d 1// 存储 (…

C#(C Sharp)学习笔记_多态【十九】

前言 个人觉得多态在面向对象编程中还比较重要的&#xff0c;而且不容易理解。也是学了一个下午&#xff0c;才把笔记写得相对比较完善&#xff0c;但仍欠缺一些内容。慢慢来吧…… 什么是多态&#xff1f; 基本概念 在编程语言和类型论中&#xff0c;多态&#xff08;Poly…

DAY3-力扣刷题

1.罗马数字转整数 13. 罗马数字转整数 - 力扣&#xff08;LeetCode&#xff09; 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L …

MySQL常见的命令

MySQL常见的命令 查看数据库&#xff08;注意添加分号&#xff09; show databases;进入到某个库 use 库; 例如&#xff1a;进入test use test;显示表格 show tables;直接展示某个库里面的表 show tables from 库&#xff1b; 例如&#xff1a;展示mysql中的表格 show tabl…

无广告、简单、实用的高性能 PDF 处理工具

一、简介 1、无广告、简单、实用的高性能 PDF 处理工具。它安装包大小在 240MB 左右&#xff0c;目前仅支持 Windows 平台。 二、下载 1、文末有下载链接,不明白可以私聊我哈&#xff08;麻烦咚咚咚&#xff0c;动动小手给个关注收藏小三连&#xff0c;我将继续努力为大家寻找以…