Vue2进阶之Vue3高级用法

news2024/11/25 16:54:03

Vue3高级用法

  • 响应式
    • Vue2:Object.defineProperty
      • Object.defineProperty
      • this.$set设置响应式
    • Vue3:Proxy
  • composition API
    • Vue2 option API和Vue3 compositionAPI
    • reactive和shallowReactive
    • readonly效果
    • toRefs效果
  • 生命周期
    • main.js
    • index.html
    • LifeCycle.vue
  • 异步组件元素节点
    • 正常写
    • index.html
    • main.js
    • Async.vue
    • AsyncComp.vue
    • 使用异步
      • main.js
  • teleport 传送门—createPortal React
    • index.html
    • main.js
    • Dialog.vue
  • 自定义hooks
    • index.html
    • main.js
    • useMousePosition.js
    • MouseMove.vue

作业:Vue3官网所有内容过一遍 Vue3

响应式

  • Vue2:Object.defineProperty
  • Vue3:Proxy

Vue2:Object.defineProperty

Object.defineProperty

//Vue2:Object.defineProperty

const initData={
  value:1
}

const data={}

Object.keys(initData).forEach(key=>{
  Object.defineProperty(data,key,{
    // getter setter
    get(){
      console.log("访问",key)
      return initData[key]
    },
    set(val){
      console.log("设置值",key)
      initData[key]=val
    }
  })
})

请添加图片描述

this.$set设置响应式

set给目的对象添加响应式属性后,并触发事件更新

this.$set(data,a,1)

请添加图片描述
请添加图片描述

Vue3:Proxy

// Vue3:Proxy
const person={
  name:"张三"
}

let proxy=new Proxy(
  person,
  {
    get:function(target,key){
      if(key in target){
        return target[key]
      }
      throw new Error(`${key} is not defined`)
    },
    set(target,key,val){
      console.log("设置值",key)
      target[key]=val
    }
  }
)
let obj=Object.create(proxy)

请添加图片描述
proxy的正规写法:

// Proxy正规写法
const initData={
  value:1
}
let proxy=new Proxy(
  initData,
  {
    get:function(target,key,receiver){
      console.log("访问",key)
      return Reflect.get(target,key,receiver)
    },
    set:function(target,key,val,receiver){
      console.log("修改",key)
      return Reflect.set(target,key,val,receiver)
    }
  }
)

请添加图片描述

拓展
怎么将esNext转换为es5写法?
通过babel,国外主流的swc转换

composition API

Vue2 option API和Vue3 compositionAPI

Vue3的compositionAPI和Vue2的optionsAPI的最大的区别是:更加倾向于函数式编程以及Vue3支持多个根节点
Vue2:

<template>
   <!--XXXX-->
</template>
<script>
  export default {
     data(){
       return{ XXXX }
     },
     methods:{},
     computed:{}
  }
</script>
<style></style>

Vue2最容易产生的问题是:写一个文件一开始还好,写着写着就发现这个文件内容非常非常多,非常非常繁琐。
OptionAPI非常非常容易导致一个文件内容非常非常多,越往后越难改,非常非常容易出bug
Rect相对于Vue不容易写出那么夸张的效果
Vue2的mixin将组件单一内容拆解到一个文件,太灵活了,对多人协作不友好

=>Vue3主要解决的就是这个问题,将明确的逻辑抽象到一起

React=>自定义hook,将一部分的逻辑功能放到单一组件里去维护

App.vue

<template>
  <div class="mine"></div>
</template>

<script>
import {defineComponent,ref,isRef} from 'vue'
export default defineComponent({
  // 相当于Vue2生命周期中的beforeCreate,created
  setup(){
    const count=ref(10)
    const user="张三"

    console.log("count,user",count,count.value,user)
    console.log("count is ref?",isRef(count))
    console.log("user is ref?",isRef(user))
  }
})
</script>

请添加图片描述

reactive和shallowReactive

<template>
  <div class="mine"></div>
</template>

<script>
import {defineComponent,reactive,shallowReactive} from 'vue'
export default defineComponent({
  // 相当于Vue2生命周期中的beforeCreate,created
  setup(){
    const person={
      name:"张三",
      age:18,
      contacts:{
        phone:12345
      }
    }

    const personReactive=reactive(person)
    console.log("person reactive",personReactive)
    console.log("person reactive name",personReactive.name)
    console.log("person reactive contacts",personReactive.contacts)

    console.log("--------------分割线------------------------")

    const shallowPersonReactive=shallowReactive(person)
    console.log("shallow person reactive",shallowPersonReactive)
    console.log("shallow person reactive name",shallowPersonReactive.name)
    console.log("shallow person reactive contacts",shallowPersonReactive.contacts)

    
  }
})
</script>

请添加图片描述

readonly效果

<template>
  <div class="mine"></div>
</template>

<script>
import {defineComponent,ref,reactive,readonly} from 'vue'
export default defineComponent({
  // 相当于Vue2生命周期中的beforeCreate,created
  setup(){
    const count=ref(10)
    const obj=reactive({
      abc:18,
      count,
      userInfo:{
        age:66
      }
    })

    console.log("reactive obj:",obj)
    // 在Proxy的set中,是不允许做修改的
    const objOnly=readonly(obj)  

    console.log("readonly obj:",objOnly)
    objOnly.abc=100
    console.log("readonly obj:",objOnly)
    
  }
})
</script>

请添加图片描述

toRefs效果

<template>
  <div class="mine"></div>
</template>

<script>
import {defineComponent,ref,isRef,reactive,shallowReactive,readonly, toRefs} from 'vue'
export default defineComponent({
  // 相当于Vue2生命周期中的beforeCreate,created
  setup(){
    const count=ref(10)
    const obj=reactive({
      abc:18,
      count,
      userInfo:{
        age:66
      }
    })

    console.log("reactive obj:",obj)

    console.log("toRefs obj",toRefs(obj))
    
  }
})
</script>

请添加图片描述
如果是通过ref创建出来的,一般是RefImpl,如果是通过toRefs创建出来的,一般把toRefs视为一个对象,针对对象里的所有属性,全部转换为toRefs的效果

生命周期

经常应用的场景:
1.初始化 mount
2.数据变化 update
3.卸载 unmount

加入LiftCycle组件

main.js

import { createApp } from 'vue'
import App from './App.vue'

import LifeCycle from './LifeCycle.vue'

createApp(App).mount('#app')

createApp(LifeCycle).mount('#lifeCycle')

index.html

<div id="lifeCycle"></div>

全部:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
     <div id="lifeCycle"></div>
  </body>
</html>

LifeCycle.vue

<template>
    <div>
      {{ count }}
      {{ name }}
    </div>
    <button @click="addNumber">+1</button>
    <button @click="updateName">update name</button>
</template>
<script>
export default {
   data() {
      return {
        count:0,
        name:"张三"
      }
   },
   methods:{
    addNumber(){
      this.count++
    },
    updateName(){
      this.name = "李四"
    }
   },
  //  1.初始化,data还不能用
   beforeCreate(){
    console.log("beforeCreate")
   },
  //   data可以用,dom不可用
   created(){
    console.log("created")
   },
  //   挂载之前,DOM还没有生成
   beforeMount(){
    console.log("beforeMount")
   },
  //   在VNode(初次渲染/更新)渲染时调用
   renderTracked({key,target,type}){
    console.log("renderTracked",key,target,type)
   },
  //  挂载之后,DOM已经生成
   mounted(){
    console.log("mounted")
    console.log("-------------------------------------------------------------")
   },
   

   //  2.update
  renderTriggered({key,target,type}){
    console.log("renderTriggered",key,target,type)
  },
  beforeUpdate(){
    console.log("beforeUpdate")
  },
  renderTracked({key,target,type}){
    console.log("renderTriggered",key,target,type)
  },
  updated(){
    console.log("updated")
  },

  // 3.卸载
  beforeUnmount(){
    console.log("beforeUnmount")
  },
  unmounted(){
    console.log("unmounted")
  }
}
</script>
<style scoped>

</style>

请添加图片描述

异步组件元素节点

正常写

  • src
    • Async.vue
    • components
      • AsyncComp.vue

index.html

<!-- 3.异步组件元素节点 -->
<div id="async"></div>
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <!-- 1.composition 元素节点 -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
     <!-- 2.生命周期元素节点 -->
     <div id="lifeCycle"></div>
     <!-- 3.异步组件元素节点 -->
      <div id="async"></div>
  </body>
</html>

main.js

import { createApp } from 'vue'
import App from './App.vue'

import LifeCycle from './LifeCycle.vue'

import Async from './Async.vue'
import AsyncComp from './components/AsyncComp.vue'

createApp(App).mount('#app')

createApp(LifeCycle).mount('#lifeCycle')

const async=createApp(Async)
async.component("async-comp",AsyncComp)
async.mount('#async')

Async.vue

<template>
  ASYNC
  <async-comp></async-comp>
</template>

<script setup lang="ts">

</script>

<style scoped>

</style>

AsyncComp.vue

<template>
  <div>async defineComponent</div>
</template>

<script setup lang="ts">

</script>

<style scoped>

</style>

在这里插入图片描述
但是这样执行

pnpm run build

打包后,只会生成一个js文件
在这里插入图片描述

使用异步

main.js

const AsyncComp=defineAsyncComponent(()=>import('./components/AsyncComp.vue'))

async.component("async-comp",AsyncComp)

全部代码:

import { createApp,defineAsyncComponent } from 'vue'
import App from './App.vue'

import LifeCycle from './LifeCycle.vue'

import Async from './Async.vue'
// import AsyncComp from './components/AsyncComp.vue'

createApp(App).mount('#app')

createApp(LifeCycle).mount('#lifeCycle')

const async=createApp(Async)

const AsyncComp=defineAsyncComponent(()=>import('./components/AsyncComp.vue'))

async.component("async-comp",AsyncComp)
async.mount('#async')

再执行

pnpm run build

会生成两个js文件

在这里插入图片描述
这两个文件是将我们异步的组件给单独拿出来,将异步组件单独拿出来的效果是,因为要做的是异步组件的动态引入,一般是额外使用或之后去用,就没有必要跟原先代码单独一起打包。

对应的是React.lazy和React中的suspense

const myComponent=React.lazy(()=>import('./Component'))

function MyComponent(){
    return (
        <div>
            <Suspense fallback={<Loading />}>
              <Component />
            </Suspense>
        </div>
    )
}

teleport 传送门—createPortal React

将子节点渲染到父节点以外的DOM的方式

  • src
  • Dialog.vue

index.html

<!-- 4.teleport 元素节点 -->
<div id="dialog"></div>

全部代码:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <!-- 1.composition 元素节点 -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
     <!-- 2.生命周期元素节点 -->
     <div id="lifeCycle"></div>
     <!-- 3.异步组件元素节点 -->
      <div id="async"></div>
      <!-- 4.teleport 元素节点 -->
       <div id="dialog"></div>
  </body>
</html>

main.js

const dialog=createApp(Dialog)
dialog.mount('#dialog')

全部代码:

import { createApp,defineAsyncComponent } from 'vue'
import App from './App.vue'

import LifeCycle from './LifeCycle.vue'

import Async from './Async.vue'
import Dialog from './Dialog.vue'
// import AsyncComp from './components/AsyncComp.vue'

createApp(App).mount('#app')

createApp(LifeCycle).mount('#lifeCycle')

const async=createApp(Async)

const AsyncComp=defineAsyncComponent(()=>import('./components/AsyncComp.vue'))

async.component("async-comp",AsyncComp)
async.mount('#async')

const dialog=createApp(Dialog)
dialog.mount('#dialog')

Dialog.vue

<template>
  <div class="portals">
    <button @click="showNotification">切换弹窗</button>
    <teleport to="#dialog">
      <div v-if="isOpen" class="notification">
        这是一个弹窗
      </div>
    </teleport>
  </div>
</template>
<script>
import { ref } from 'vue';

export default {
    setup(){
        const isOpen=ref(false)
        let closePopup
        const showNotification=()=>{
            isOpen.value=true

            clearTimeout(closePopup)

            closePopup=setTimeout(()=>{
                isOpen.value=false
            },20000)
        }

        return {
            isOpen,
            showNotification
        }
    }
}
</script>
<style scoped>
.notification{
    position: fixed;
    bottom: 20px;
    background-color: #fff;
    border: 1px solid #ccc;
    width: 300px;
    padding:30px;
}
</style>

弹窗是挂载在dialog下的,而不是protals下
在这里插入图片描述

自定义hooks

hooks最重要的特点:对于我们来说,不需要关心内部的逻辑,而且与Vue2相比,提供了一个非常合理的方式,使用Vue2的option API很容易写出三五千行的代码,但是对于函数式编程来说,按照逻辑功能拆分下来,一个文件至少包含一个功能,其他功能引用即可。

  • public
    • index.html
  • src
    • hooks
      • useMousePosition.js
    • MouseMove.vue
    • main.js

index.html

<!-- 5.自定义hook -->
<div id="mousemove"></div>

全部代码:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <!-- 1.composition 元素节点 -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <!-- 2.生命周期元素节点 -->
    <div id="lifeCycle"></div>
    <!-- 3.异步组件元素节点 -->
    <div id="async"></div>
    <!-- 4.teleport 元素节点 -->
    <div id="dialog"></div>
    <!-- 5.自定义hook -->
    <div id="mousemove"></div>
  </body>
</html>

main.js

import MouseMove from './MouseMove.vue'

const mousemove=createApp(MouseMove)
mousemove.mount('#mousemove')

全部代码:

import { createApp,defineAsyncComponent } from 'vue'
import App from './App.vue'

import LifeCycle from './LifeCycle.vue'

import Async from './Async.vue'
import Dialog from './Dialog.vue'
// import AsyncComp from './components/AsyncComp.vue'
import MouseMove from './MouseMove.vue'


// createApp(App).mount('#app')

// createApp(LifeCycle).mount('#lifeCycle')

// const async=createApp(Async)

// const AsyncComp=defineAsyncComponent(()=>import('./components/AsyncComp.vue'))

// async.component("async-comp",AsyncComp)
// async.mount('#async')

// const dialog=createApp(Dialog)
// dialog.mount('#dialog')

const mousemove=createApp(MouseMove)
mousemove.mount('#mousemove')

useMousePosition.js

import { onMounted, onUnmounted, ref } from "vue";

function useMousePosition() {
  const x=ref(0)
  const y=ref(0)


  const updateMouse=e=>{
    x.value=e.pageX
    y.value=e.pageY
  }

  onMounted(()=>{
    document.addEventListener('click',updateMouse)
  }) 

  onUnmounted(()=>{
    document.removeEventListener('click',updateMouse)
  })

  return{
    x,
    y
  }
}

export default useMousePosition

MouseMove.vue

<!-- 提供鼠标位置自定义hooks -->
<template>
  <div>
    <p>X:{{x}}</p>
    <p>Y:{{y}}</p>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import useMousePosition from './hooks/useMousePosition';

export default defineComponent({
  setup(){
    const {x,y}=useMousePosition()
    return {
      x,y
    }
  }
})
</script>

<style scoped>

</style>

请添加图片描述

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

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

相关文章

Unity3D学习FPS游戏(10)子弹攻击敌人掉血(碰撞检测)

前言&#xff1a;前面最然创造出带有血条的敌人&#xff0c;但子弹打中敌人并没有效果。所以本篇将实现子弹攻击敌人&#xff0c;并让敌人掉血。 子弹攻击敌人掉血 整体思路目标补充知识-碰撞检测 准备工作刚体和碰撞器添加添加刚体后子弹代码优化补充知识-标签系统Tag添加 碰…

AMD显卡低负载看视频掉驱动(chrome edge浏览器) 高负载玩游戏却稳定 解决方法——关闭MPO

问题 折磨的开始是天下苦黄狗久矣&#xff0c;为了不再被讨乞丐的显存恶心&#xff0c;一怒之下购入了AMD显卡&#xff08;20GB显存确实爽 头一天就跑了3dmark验机&#xff0c;完美通过&#xff0c;玩游戏也没毛病 但是呢这厮是一点不省心&#xff0c;玩游戏没问题&#xff0c…

服装品牌零售业态融合中的创新发展:以开源 AI 智能名片 S2B2C 商城小程序为视角

摘要&#xff1a;本文以服装品牌零售业态融合为背景&#xff0c;探讨信息流优化和资金流创新的重要作用&#xff0c;并结合开源 AI 智能名片 S2B2C 商城小程序&#xff0c;分析其如何进一步推动服装品牌在零售领域的发展&#xff0c;提高运营效率和用户体验&#xff0c;实现商业…

【数据库】elasticsearch

1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片&#xff08;Shard&#xff09;&#xff1a; 将索引数据分割成多个部分&#xff0c;每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理&#xff0c;从而提高系统的扩展性和性能。 在创建索…

语言模型的评测

语言模型的评测 内在评测 在内在评测中&#xff0c;测试文本通常由与预训练中所用的文本独立同分布的文本构成&#xff0c;不依赖于具体任务。最为常用的内部评测指标是困惑度&#xff08;Perplexity&#xff09; 困惑度是衡量语言模型对测试文本预测能力的一个指标&#xf…

Golang | Leetcode Golang题解之第535题TinyURL的加密与解密

题目&#xff1a; 题解&#xff1a; import "math/rand"type Codec map[int]stringfunc Constructor() Codec {return Codec{} }func (c Codec) encode(longUrl string) string {for {key : rand.Int()if c[key] "" {c[key] longUrlreturn "http:/…

德国卡赫携丰硕成果七赴进博会

第七届中国国际进口博览会于11月5日在国家会展中心&#xff08;上海&#xff09;正式拉开帷幕。作为全球最大的清洁设备和清洁解决方案提供商&#xff0c;“全勤生”德国卡赫连续七年参展&#xff0c;并携集团旗下子品牌HAWK霍克一同亮相技术装备展区3号馆&#xff0c;更带来多…

IT架构管理

目录 总则 IT架构管理目的 明确组织与职责 IT架构管理旨在桥接技术实施与业务需求之间的鸿沟&#xff0c;通过深入理解业务战略和技术能力&#xff0c;推动技术创新以支持业务增长&#xff0c;实现技术投资的最大价值。 设定目标与范围 IT架构管理的首要目的是确立清晰的组织…

Rust项目结构

文章目录 一、module模块1.文件内的module 二、模块化项目结构1.关于module2.各个模块之间互相引用 三、推荐项目结构1.实例 参考 一、module模块 1.文件内的module 关键字&#xff1a;mod 引入模块中的方法 usemod名字&#xff1a;方法名usemod名字.*写全路径 二、模块化…

HiveSQL 中判断字段是否包含某个值的方法

HiveSQL 中判断字段是否包含某个值的方法 在 HiveSQL 中&#xff0c;有时我们需要判断一个字段是否包含某个特定的值。下面将介绍几种常用的方法来实现这个功能。 一、创建示例表并插入数据 首先&#xff0c;我们创建一个名为employee的表&#xff0c;并插入一些示例数据&am…

408——计算机网络(持续更新)

文章目录 一、计算机网络概述1.1 计算机网络的概念1.2 计算机网络体系结构1.3 总结 二、物理层2.1 物理层的基本概念2.2 物理层的基本通信技术2.3 总结 三、数据链路层3.1 数据链路层基础概论3.2 数据链路层的通信协议 一、计算机网络概述 1.1 计算机网络的概念 计算机网络的定…

正反shell反弹的区分

在shell反弹中我们会根据参照物的不同来区分正反shell反弹。 本次我们需要使用win和kali进行实验&#xff1a; 在shell反弹中我们需要在win上面安装netcat&#xff08;瑞士军刀&#xff09;用于可以执行监听指令。 下载指导链接https://blog.csdn.net/qq_40359932/article/d…

CSS的配色

目录 1 十六进制2 CSS中的十六进制2.1 十六进制颜色的基本结构2.2 十六进制颜色的范围2.3 简写形式2.4 透明度 3 CSS的命名颜色4 配色4.1 色轮4.2 互补色4.3 类似色4.4 配色工具 日常在开发小程序中&#xff0c;客户总是希望你的配色是美的&#xff0c;但是美如何定义&#xff…

Java 基于SpringBoot+Vue 的公交智能化系统,附源码、文档

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

qt QFile详解

1、概述 QFile类是Qt框架中用于读取和写入文本和二进制文件资源的I/O工具类。它继承自QFileDevice类&#xff0c;后者又继承自QIODevice类。QFile类提供了一个接口&#xff0c;允许开发者以二进制模式或文本模式对文件进行读写操作。默认情况下&#xff0c;QFile假定文件内容为…

react jsx基本语法,脚手架,父子传参,refs等详解

1&#xff0c;简介 1.1 概念 react是一个渲染html界面的一个js库&#xff0c;类似于vue&#xff0c;但是更加灵活&#xff0c;写法也比较像原生js&#xff0c;之前我们写出一个完成的是分为html&#xff0c;js&#xff0c;css&#xff0c;现在我们使用react库我们把html和js结…

Qt学习笔记第41到50讲

第41讲 UI美化遗留问题解决 如上图所示目前记事本的雏形已现&#xff0c;但是还是有待优化&#xff0c;比如右下角的拖动问题。 解决方法&#xff1a; ①首先修改了Widget类的构造函数。 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) {ui->s…

Linux(VMware + CentOS )设置固定ip

需求&#xff1a;设置ip为 192.168.88.130 先关闭虚拟机 启动虚拟机 查看当前自动获取的ip 使用 FinalShell 通过 ssh 服务远程登录系统&#xff0c;更换到 root 用户 修改ip配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 重启网卡 systemctl restart network …

CAN总线学习笔记(1、CAN总线定义)

CAN总线学习笔记&#xff08;1、CAN总线定义&#xff09; 江协科技CAN总线入门教程视频学习笔记 CAN特性 两根通信线&#xff08;CAN_H\CAN_L&#xff09;,两根线&#xff0c;无需工地 差分信号&#xff0c;抗干扰能力强 高速CAN&#xff08;ISO11898&#xff09;&#xff…

伍光和《自然地理学》电子书(含考研真题、课后习题、章节题库、模拟试题)

《自然地理学》&#xff08;第4版&#xff09;由伍光和、王乃昂、胡双熙、田连恕、张建明合著&#xff0c;于2018年11月出版。作为普通高等教育“十一五”国家级规划教材&#xff0c;本书不仅适用于高校地球科学各专业的基础课程&#xff0c;还可供环境、生态等有关科研、教学人…