Vue3-初识Vue3、创建Vue3工程、vue3组合式API(setup、ref函数、reactive函数)、响应式原理、计算属性、监视属性

news2024/9/27 5:51:14

Vue3(1)

目录

  • Vue3(1)
    • 一、Vue3简介
    • 二、创建Vue3.0工程
      • 1、使用vue-cli创建
      • 2、使用vite创建
    • 三、常用的Composition API(组合式API)
      • 1、拉开序幕的setup
      • 2、ref函数
      • 3、reactive函数
      • 4、Vue3中响应式原理
        • (1)Vue2中响应式原理
        • (2)Vue3中的Proxy
        • (3)Vue3响应式原理总结⭐
      • 5、reactive和ref的对比
      • 6、setup的两个注意点
        • (1)执行时机
        • (2)setup的参数
    • 四、计算函数和监视函数
      • 1、计算函数(computed)
      • 2、监视函数(watch)
        • (1)第一个参数怎么写
        • (2)第一个参数到底写不写.value
      • 3、watchEffect函数

一、Vue3简介

2020年9月18日,Vue.js发布了3.0版本,代号:One Piece(海贼王)

耗时两年多,2600+次提交、30+个RFC、600+次PR、99位贡献者

Vue3带来了什么:

1、性能上的提升

  • 打包大小减少42%
  • 初次渲染块55%、更新渲染块133%
  • 内存减少54%

2、源码的升级

  • 使用Proxy代替defineProperty实现响应式
  • 重写虚拟DOM的实现和Tree-Sgaking

3、拥抱TypeScript

  • Vue3可以更好的支持TypeScript

4、新特性

(1)Composition API(组合API)

  • setup配置
  • ref与reactive
  • watch与watchEffect
  • provide与inject

(2)新的内置组件

  • Fragment
  • Teleport
  • Suspense

(3)其他改变

  • 新的生命周期钩子
  • data选项应始终被声明为一个函数
  • 移除keyCode支持作为v-on的修饰符

二、创建Vue3.0工程

1、使用vue-cli创建

官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create

// 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
// 安装或者升级你的@vue/cli
npm install -g @vue/cli
// 创建
vue create vue_test
// 启动
cd vue_test
npm run serve

2、使用vite创建

官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite
vite官网:https://vitejs.cn

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

  • 优势如下:

    1.开发环境中,无需打包操作,可快速冷启动

    2.轻量快速的热重载(HMR)

    3.真正的按需编译,不再等待整个应用编译完成

// 创建工程
npm init vite-app <project-name>
// 进入工程目录
cd <project-name>
// 安装依赖
npm install
// 运行
npm run dev

三、常用的Composition API(组合式API)

1、拉开序幕的setup

之前我们在vue2中都是多个配置项组合在一起(选项式API:data、method那些),在vue3中,换了一种方式,那就是Composition API(组合式API),而setup则是组合式API表演的舞台,组件中所有的数据和方法都写在setup函数中。

这个setup函数其实有两种返回值:

  1. 返回一个对象

  2. 返回一个渲染函数

用的最多的就是返回一个对象,把用到的所有属性、方法都返回出去,方便在模板中使用(当然,现在有了setup语法糖,后面再说)

<template>
  <h1>个人信息</h1>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <button @click="sayHello">打招呼</button>
</template>

<script>
import { h } from "vue";
export default {
  name: "App",
  // 此处只是测试一下setup,暂时不考虑响应式的问题
  setup() {
    // 数据
    let name = "potato";
    let age = 18;

    // 方法
    function sayHello() {
      alert(`我叫${name},我${age}岁了`);
    }
      
    // 返回一个对象
    return {
      name,
      age,
      sayHello,
    };

    // 返回一个渲染函数
    // return () => {return h('h1','哈哈哈哈')};
  },
};
</script>

注意:不要把setup和vue2中的选项式API混用,因为setup中访问不到vue2中的属性方法(但2可访问3),如果混用的话,有重名setup优先。

还有,setup前不要加async,因为返回值会变成promise,而不是我们return的那些属性和方法

2、ref函数

还记得vue2的ref属性吗,vue2的ref类似于id。复习Vue2的ref属性

而Vue3的ref是一个函数。

作用:定义响应式的数据。

例:点击按钮修改信息

<template>
  <h1>个人信息</h1>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import { ref } from "vue";
export default {
  name: "App",
  setup() {
    // 数据
    let name = ref("potato");
    let age = ref(18);

    // 方法
    function changeInfo() {
      // 直接这样写的话是不行的,因为ref把数据包装成了对象,对其操作时要加上‘.value’
      // name= "李四";
      // age= 13;
      // console.log(name, age);
      name.value = "李四";
      age.value = 13;
    }

    // 返回一个对象
    return {
      name,
      age,
      changeInfo,
    };
  },
};
</script>

const xxx = ref(initValue)创建了一个包含响应式数据的引用对象(RefImp对象
在js中操作数据:count.value
在模板中读取数据:<div> {{count}} </div>(这里会自动读取value属性)

请添加图片描述

其实ref可以接受的数据不只是基本数据类型,复杂数据类型也可以,只不过比较麻烦,操作时都要.value

<template>
  <h1>个人信息</h1>
  <h3>职业:{{ job.type }}</h3>
  <h3>工作地点:{{ job.address }}</h3>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import { ref } from "vue";
export default {
  name: "App",
  setup() {
    // 数据
    let job = ref({
      type: "前端工程师",
      address: "广州",
    });

    // 方法
    function changeInfo() {;
      job.value.type = "后端工程师";
      job.value.address = "深圳";
    }

    // 返回一个对象
    return {
      job,
      changeInfo,
    };
  },
};
</script>

基本数据类型和对象数据类型实现响应式的方式不同,前者依然是Object.defineProperty()的get与set,后者则在内部求助了reactive函数

3、reactive函数

作用:定义一个对象类型的响应式数据(基本类型不要用reactive,要用ref)

<script>
import { ref, reactive } from "vue";
export default {
  name: "App",
  setup() {
    // 数据
    let job = reactive({
      type: "前端工程师",
      address: "广州",
    });
    // 数组也可以
    let hobby = reactive(["吃饭", "睡觉", "打豆豆"]);

    // 方法
    function changeInfo() {
      job.type = "后端工程师";
      job.address = "深圳";
      hobby[2] = "学习";
    }

    // 返回一个对象
    return {
      job,
      changeInfo,
      hobby,
    };
  },
};
</script>

const 代理对象 = reactive(源对象)接收一个对象或数组,返回一个代理对象(Proxy对象)

  • reactive定义的响应式数据时“深层次的”
  • 内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作

这里要注意,只有改变job中的某个属性,才可以实现响应式,如果直接改job,会报警告告诉你job是只读(read-only)的。如果要改job,需要Object.assign(job, newObj);或者job= { …job, …newProperties };

4、Vue3中响应式原理

(1)Vue2中响应式原理

在了解Vue3响应式原理之前,咱先来复习下vue2响应式。

我们知道vue2中是通过Object.defineProperty()对对象类型数据进行劫持并添加getter和setter来监视数据的,对于数组是重写了更新数组的方法。复习vue2监视数据的原理

vue2监视数据存在两个问题:

  1. 直接新增属性、删除属性, 界面不会更新。
  2. 直接通过下标修改数组, 界面不会自动更新。

这两个问题可以通过$set$deletesplice(数组变更方法)解决

(2)Vue3中的Proxy

在vue3中,解决了vue2中的两个问题。

<button @click="addSex">添加一个sex属性</button>
<button @click="deleteName">删除一个name属性</button>
    function addSex() {
      // 如果是vue2,要这样写this.$set(this.person, 'sex', '女');
      person.sex = "女";
    }
    function deleteName() {
      // 如果是vue2,要这样写this.$delete(this.person, 'name');
      delete person.name;
    }

下面是模拟实现vue3中响应式的原理:

<script>
  let person = {
    name: "potato",
    age: 18,
  };
  // 模拟Vue3实现响应式
  const p = new Proxy(person, {
    // 有人在读取p的某个属性时调用
    get(target, propName) {
      console.log(`有人读取了p身上的${propName}属性`);
      return target[propName];
    },
    // 有人在修改p的某个属性、或给p追加某个属性时调用
    set(target, propName, value) {
      console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`);
      target[propName] = value;
    },
    // 有人在删除p的某个属性时调用
    deleteProperty(target, propName) {
      console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`);
      return delete target[propName];
    },
  });
</script>

请添加图片描述

再严谨一些,用Reflect(反射)来进行增删改查,这也是框架的做法,其实本质上没什么太大的区别,只是Reflect可以更好捕捉错误,避免一些报错吧,不然还要用try-catch去捕获。这里不用太纠结,其实就是为了让框架更加的友好(少一些报错)

  • Proxy(代理)+Reflect(反射)
<script>
  let person = {
    name: "potato",
    age: 18,
  };
  // 模拟Vue3实现响应式
  const p = new Proxy(person, {
    // 有人在读取p的某个属性时调用
    get(target, propName) {
      console.log(`有人读取了p身上的${propName}属性`);
      return Reflect.get(target, propName);
    },
    // 有人在修改p的某个属性、或给p追加某个属性时调用
    set(target, propName, value) {
      console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`);
      Reflate.set(target, propName, value);
    },
    // 有人在删除p的某个属性时调用
    deleteProperty(target, propName) {
      console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`);
      return Reflate.deleteProperty(target, propName);
    },
  });
</script>
(3)Vue3响应式原理总结⭐

对于refreactive是不一样的

ref简单类型是通过:Object.defineProperty()的get与set,当然啊,ref定义的复杂类型是通过:reactive的Proxy

reactive是通过Proxy来实现响应式的(上文提到了),并通过Reflect来操作源数据

不管怎么样,总结来说,vue3中新增的就是对于复杂数据类型通过Proxy实现响应式,也就是两个点:

  1. 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性的增删、属性值的读写等。
  2. 通过Reflect(反射): 对源对象的属性进行上述操作。
new Proxy(person, {
    // 拦截读取属性值
    get(target, propName) {
      return Reflect.get(target, propName);
    },
    // 拦截设置属性值或添加属性值
    set(target, propName, value) {
      Reflate.set(target, propName, value);
    },
    // 拦截删除属性
    deleteProperty(target, propName) {
      return Reflate.deleteProperty(target, propName);
    },
});

5、reactive和ref的对比

(1)定义数据类别不同

  • ref用于定义基本类型数据
  • reactive用于定义对象或数组类型数据
  • 备注:ref也可以定义对象或数组类型数据,它内部会自动通过reactive转为代理对象

(2)原理不同

  • ref是通过:Object.defineProperty()getset,当然啊,复杂类型是通过reactive的Proxy
  • reactive是通过Proxy来实现响应式的(上文提到了),并通过Reflect来操作源数据

(3)使用方式不同

  • ref定义的数据,操作时需要.value模板读取不需要.value
  • reactive定义的数据,操作和读取都不需要.value

6、setup的两个注意点

(1)执行时机

setup函数的执行时机是beforeCreate之前,也就是所有生命周期的最前面,此时this是undefined,也就是说在setup中是绝对不能通过this访问组件实例的

注意这里的beforeCreate是写在setup外面的,如果在setup里面,是没有beforeCreate和created这两个钩子的,因为setup的执行时机就相当于这两个钩子(setup会先于所有的钩子执行,把想在这两个钩子里写的代码写到steup中最前面就行了

(2)setup的参数

setup接收两个参数:(props,context)

  1. props是一个对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
  2. context是一个对象,包含三个属性,分别是attrs、slots、emit
  • 第一个attrs相当于this.$attrs,值为对象,包含组件外部传递过来,但没有在props配置中声明的属性
  • 第二个slots相当于this.$slots,包含收到的插槽的内容。
  • 第三个emit相当于this.$emit,用来触发组件的自定义事件。
props: ['name', 'age']
setup(props, context) {
  console.log(props) // Proxy{name:'potato',age:18}:组件外部传递过来,且组件内部声明接收了的属性。
  console.log(context.attrs)//相当于this.$attrs
  console.log(context.slots)相当于this.$slots
  console.log(context.emit)//相当于this.$emit
}

四、计算函数和监视函数

1、计算函数(computed)

和vue2中功能是一样的,只不过变成了一个函数,而且要手动引入。默认写法是传一个回调

如果我们只使用简写的话,当我们去修改计算属性值的时候,控制台会有警告,告诉我们这个属性值是只读的。

这是因为计算属性默认是只读的,当它所依赖的值改变的时候,它自己会变。如果要想改计算属性,需要用下面的完整写法,传一个对象,里面有gettersettersetter中参数是修改后的新值

<template>
  <h1>个人信息</h1>
  姓:<input type="text" v-model="person.firstName" />
  <br />
  名:<input type="text" v-model="person.lastName" />
  <br />
  全名:<input type="text" v-model="person.fullName" />
  <br />
  <span>全名:{{ person.fullName }}</span>
</template>

<script>
import { computed, reactive } from "vue";
export default {
  setup() {
    let person = reactive({
      firstName: "张",
      lastName: "三",
    });

    // 计算属性-简写(没有考虑计算属性被修改的情况)
    // person.fullName = computed(function () {
    //   return person.firstName + "-" + person.lastName;
    // });

    // 计算属性-完整(包括读和写)
    person.fullName = computed({
      get() {
        return person.firstName + "-" + person.lastName;
      },
      set(value) {
        const nameArr = value.split("-");
        person.firstName = nameArr[0];
        person.lastName = nameArr[1];
      },
    });

    return {
      person,
    };
  },
};
</script>

2、监视函数(watch)

其实watch在vue3中和vue2中功能是一样的,就是写法不一样。

vue2的监听函数写法点此复习vue2监听函数

先准备一些数据吧:

import { ref, reactive } from 'vue'
const sum = ref(0)
const msg = ref('hello')
const person = reactive({
	name: 'potato'
	age: 18
	job: {
		type: 'code'
		salary: 10
	}
})
(1)第一个参数怎么写
  • 情况一:vue3监视ref所定义的一个响应式数据
watch(sum, (newVal, oldVal) => {
	console.log("sum的值变了", newVal, oldVal);
});

请添加图片描述

  • 情况二:vue3监视ref所定义的多个响应式数据
watch([sum, msg], (newVal, oldVal) => {
	console.log("sum或msg变化了", newVal, oldVal);//new和old也是监听值构成的数组
});

请添加图片描述

  • 情况三:监视reactive定义的响应式数据
    这里有两个坑,第一个是reactive定义的数据,监视时回调中无法获得oldValue!oldValue和newValue一样
    第二个坑是,监视reactive定义的数据,默认开启的deep:true,且deep不能改成false
watch(person, (newVal, oldVal) => {
	console.log("person变化了");
},{immediate:true,deep:false});
  • 情况四:监视reactive定义的响应式数据中的某个属性
    这里要注意,第一个参数必须写成箭头函数,如果直接写person.job,那么就相当于写了个死的值,这样是监视不到的。还有就是如果job是一个对象,那么默认deep是false的,如果要深度监视需要手动开启deep:true(deep配置有效)
watch(()=>person.job,(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true}) 
  • 情况五:监视reactive定义的响应式数据中的某些属性
    如果这种情况的话和上面类似,不同的是第一个参数写成数组,且每个元素是箭头函数,返回的new和old值也是相对应的值构成的数组。
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})
(2)第一个参数到底写不写.value

如果我们把person换成是一个ref定义的呢?那么监视的时候写不写.value

import { ref, reactive } from 'vue'
const sum = ref(0)
const msg = ref('hello')
const person = ref({
	name: 'dantin'
	age: 18
	job: {
		type: 'code'
		salary: 10
	}
})

答案是:要写的,因为ref对于复杂数据类型,内部是借助reactiveProxy实现响应式的,所以这么写的话就相当于是写了一个reactive定义的响应式数据,在监视时也就具有了对应的坑(见上文情况三)

watch(person.value,(newValue,oldValue)=>{
	console.log('person变化了',newValue,oldValue)
},{immediate:true,deep:false}) //此处的deep配置不奏效

除此之外还有一种办法,那就是深度监视person(它是一个RefImpl对象),这样就能监视到其中的value及更深层的变化。这是因为如果直接监视person不读取.value,那么监视的是RefImpl对象,只有其中value的地址变的时候才能监视到,value里面的东西变化是监视不到的,所以要开deep

watch(person,(newValue,oldValue)=>{
	console.log('person变化了',newValue,oldValue)
},{immediate:true,deep:true}) 

那为什么简单数据类型不需要.value呢?其实和上面的情况四是一样的,如果简单数据类型直接.value,那么监视的就是一个写死的值。不.value的话,监视的是一个响应式的RefImpl对象,当里面value变化的时候是可以监视到的

watch(sum,(newValue,oldValue)=>{
	console.log('sum变化了',newValue,oldValue)
})

如果非要.value,请使用箭头函数动态读取,每次sum变化都会执行回调读取最新的值

watch(() => sum.value,(newValue,oldValue)=>{
	console.log('sum变化了',newValue,oldValue)
})

3、watchEffect函数

  • watch的套路是:既要指明监视的属性,也要指明监视的回调
  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

watchEffect有点像computed,但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

//watchEffect的回调一上来会先执行一次
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(() => {
  const x1 = sum.value;
  const x2 = person.job.salary;
  console.log("watchEffect所指定的回调执行了");
});

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

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

相关文章

Django:五、登录界面实现动态图片验证码

一、下载包 pip install pillow 二、代码 这是一个函数&#xff0c;无输入&#xff0c;返回两个值。一个值是图片&#xff0c;一个值是图片中的数字及字母。 需要注意&#xff1a;font_fileMonaco.ttf 是一个验证码字体文件&#xff0c;如有需要&#xff0c;可三连私信。 …

缓存之缓存简介

目录 一.缓存的作用二.缓存的使用1.适用缓存的数据场景2.读取缓存流程图 三.本地缓存和分布式缓存 一.缓存的作用 Java缓存技术是在应用程序和数据库之间的一种中间层,用于存储暂时性数据,尤其是读取频繁但更新较少的数据。它的作用是减轻应用程序和数据库之间的负担,提高应用程…

WhatsApp营销:避免封禁账号的关键策略

首先&#xff0c;我们需要明白&#xff0c;WhatsApp官方明确反对群发为&#xff0c;随时可能导致账号被封禁的风险存在。因此&#xff0c;我们应该避免避免群发&#xff0c;而更多地采用单一发单的方式。当找到目标客户后&#xff0c;应先仔细研究客户的主页&#xff0c;例如他…

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

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

基于SpringBoot的在线题库管理系统的设计与实现(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

mysql odbc驱动安装

到官网下载对应版本的驱动包 可以选择对应版本&#xff0c;建议使用最新版本即可 查看powerDesigner对应的位数&#xff0c;位数对应不上的话&#xff0c;会找不到 powerDesigner 可以参考&#xff1a;powerDesigner安装 我这里装的是32位的 下载对应版本的即可 下载完成&a…

数据结构与算法基础-(1)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

代码审计——任意文件下载详解(二)

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 网站可能提供文件查看或下载的功能&#xff0c;如果对用户查看或下载的文件不做限制&#xff0c;就能够查看或下载任意的文件&…

windows系统安装python教程,以及PyCharm安装,新手入门详细

最近需要给新电脑安装python&#xff0c;记录一下安装过程。 到python的官网进行下载&#xff1a;https://www.python.org/ 选择下载的系统&#xff0c;这边是Windows 然后选择最新的Release版本&#xff0c;点进去 然后滑到最下边&#xff0c;选择适合自己系统的&#xff0c;…

Mybatis 中 SQL 注入攻击的 3 种方式

SQL注入漏洞作为WEB安全的最常见的漏洞之一&#xff0c;在java中随着预编译与各种ORM框架的使用&#xff0c;注入问题也越来越少。往往对Java Web应用的多个框架组合而心生畏惧&#xff0c;不知如何下手&#xff0c;希望通过Mybatis框架使用不当导致的SQL注入问题为例&#xff…

基于Java自习室预订座位管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

卓越领先!安全狗入选2023年福建省互联网综合实力50强

近日&#xff0c;福建省互联网协会在2023年东南科技论坛——智能算力助力数字经济产业融合发展论坛上正式发布2023年福建省互联网综合实力前50家企业最终评定结果。 作为国内云原生安全领导厂商&#xff0c;安全狗凭借突出的竞争力和市场表现入选综合实力50强。 厦门服云信息科…

任正非“苹果是华为的老师”;音频编解码标准 L2HC 发布;GNU 和自由软件运动四十周年丨RTE开发者日报 Vol.53

开发者朋友们大家好&#xff1a; 这里是「RTE 开发者日报」&#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

虚拟机如何扩容麒麟操作系统的根文件系统

在工作中&#xff0c;经常会面临服务器磁盘空间不足的问题&#xff0c;特别是根文件系统&#xff08;/&#xff09;快满了。本文将介绍如何扩容Linux服务器的根文件系统&#xff0c;以解决这个常见的问题。 步骤一&#xff1a;关机后扩容磁盘 步骤二&#xff1a;打开磁盘实用工…

QSFP-DD800光模块:未来数据中心的新一代解决方案

什么是QSFP-DD800光模块&#xff1f; QSFP-DD800是Quad Small Form-factor Pluggable Double Density的缩写&#xff0c;是由QSFP-DD MSA定义的高速热插拔封装模式。与现有的光纤网络设备兼容性较强&#xff0c;方便数据中心的升级和扩展。 关于传输距离 在传输距离方面&#x…

React 全栈体系(十一)

第五章 React 路由 五、向路由组件传递参数数据 1. 效果 2. 代码 - 传递 params 参数 2.1 Message /* src/pages/Home/Message/index.jsx */ import React, { Component } from "react"; import {Link, Route} from react-router-dom import Detail from ./Detai…

别再盯着40系,这些才是目前性价比最高的显卡

有人说&#xff0c;当前畸形的显卡市场成了咱们升级电脑配置的最大阻碍。 在小忆看来这话说得还真没啥毛病&#xff01; CPU、主板、内存、硬盘、电源&#xff0c;哪个不是一台电脑中的重要核心硬件&#xff1b; 它们飘了吗&#xff1f;没有&#xff0c;各个品牌在竞争中相互…

知识库系统推荐,强大的全文检索与文档分类管理功能

在我们日常企业运营管理过程中&#xff0c;会积累大量的文档资料&#xff0c;对于我们全体成员来说&#xff0c;这些知识文档都是巨大的财富&#xff0c;所以整合并搭建一套知识库系统是非常有必要的。 知识库系统推荐 我们日常工作中产生大量的文档&#xff0c;随着存储技术的…

金融和大模型的“两层皮”问题

几年前&#xff0c;我采访一位产业专家&#xff0c;他提到了一个高科技到产业落地的主要困惑&#xff1a;两层皮。 一些特别牛的技术成果在论文上发表了&#xff0c;这是一层皮。企业的技术人员&#xff0c;将这些成果产品化、商品化的时候&#xff0c;可能出于工程化的原因&am…

【JAVA-Day32】精通Java函数:定义、调用和主函数的完整指南

精通Java函数&#xff1a;定义、调用和主函数的完整指南 精通Java函数&#xff1a;定义、调用和主函数的完整指南摘要引言1. Java函数基础什么是Java函数&#xff1f;函数的定义和命名规则参数和返回值的概念 2. 函数的定义与语法如何声明和定义函数&#xff1f;函数的参数和参…