20230715----重返学习-vue3新API-Vue3和Vue2对比-vue3语法-Vue3编码

day-113-one-hundred-and-thirteen-20230715-vue3新API-Vue3和Vue2对比-vue3语法-Vue3编码

vue3新API

  1. Vue 3 迁移指南

虚拟DOM

  • 说明:看01视频。
  • 虚拟DOM是用于让vue核心代码脱离浏览器的限制,在微信小程序、手机端、canvas之类也有能使用vue语法的可能,而不必改动vue源码。

createRenderer

  1. 自定义渲染器 API
  • 提供⾃定义渲染器,可以在⾮DOM环境中使⽤Vue的运⾏时。

  • 虚拟dom的优点?

    • 有了虚拟dom 可以使用diff算法。
    • 跨平台:vue是针对虚拟dom创建了真实的dom,其它的框架可以基于虚拟dom做其他的事情,如:canvas。
  • 平时我们一般并不需要使用这个api,只是为了扩展渲染能力才会使用,如用vue写微信小程序之类的需求。

  • 这个api主要就是可以自定义渲染方式。

  • 说明:

    1. vue2中没createRenderer的写法。

      import { createRenderer, h, render } from "vue"
      const vnode = h('div', 'hello-vue2的render')
      render(vnode, app); // 这个render方法,createElemet()  el.textContent = 'hello'
      // // appendChild
      
    2. vue3中有createRenderer自定义浏览器的写法。

      import { createRenderer, h } from "vue"
      const { render } = createRenderer({// 创建一个元素createElement(type) {if (type === "div") {return document.createElement("p")}},setElementText(el, text) {el.textContent = text},insert(el, parent) {parent.appendChild(el)}// 给元素设置属性,方法// 给元素设置内容
      })
      const vnode = h("div", "vue3-hello-自定义render")
      render(vnode, app)
      

v-bind绑定样式CSS变量

  • 在css中使⽤v-bind绑定样式
<script>
export default {mounted() {setTimeout(() => {this.color = "blue"}, 1000)},data() {return { color: "red" }}
}
</script>
<template><div class="custorm">v-bind绑定样式CSS变量-绑定样式</div>
</template><style scoped>
.custorm {background: v-bind(color);
}
</style>

具有scoped属性的style标签中新加的选择器

  • 在scoped中自定义深度选择、插槽、全局样式的可以采用::deep():slotted():global()这些选择器函数。

  • 修改子组件中的样式:

    • 注:vue3中在子组件上直接设置的类名及样式及事件会追踪到子组件的根节点上。
    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Scoped from "./components/scoped.vue"export default {componets: {Scoped}
        }
        </script>
        <template><div class="parent"><Scoped></Scoped></div>
        </template><style scoped>
        .parent :deep(h1) {color: yellow;
        }
        </style>
        
      • vue3-7-15/src/components/scoped.vue

        <template><div><h1>子组件的h1标签----hello</h1></div>
        </template>
        
      • 样式已经生效。

    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Scoped from "./components/scoped.vue"export default {componets: {Scoped,},
        }
        </script>
        <template><div class="parent"><Scoped></Scoped></div>
        </template><style scoped>
        .parent h1 {color: yellow;
        }
        </style>
        
      • vue3-7-15/src/components/scoped.vue

        <template><div><h1>子组件的h1标签----hello</h1></div>
        </template>
        
      • 样式没有生效。

  • :slotted()在子组件中捕获修改来自于父组件插槽中的类名,并可根据预定的类让插槽的css样式有预设:

    • 示例:

      • vue3-7-15/src/App.vue

        <script>
        import Scoped from "./components/scoped.vue"export default {componets: {Scoped,},
        }
        </script>
        <template><div class="parent"><Scoped><h2 class="inner">这是来自于父组件的插槽内容</h2></Scoped></div>
        </template>
        
      • vue3-7-15/src/components/scoped.vue

        <template><slot></slot>
        </template><style scoped>
        :slotted(.inner) {background: red;
        }
        </style>
        
      • 样式生效。

    • 示例:

      • vue3-7-15/src/App.vue

        <script>
        import Scoped from "./components/scoped.vue"export default {componets: {Scoped,},
        }
        </script>
        <template><div class="parent"><Scoped><h2 class="inner">这是来自于父组件的插槽内容</h2></Scoped></div>
        </template>
        
      • vue3-7-15/src/components/scoped.vue

        <template><slot></slot>
        </template><style scoped>
        .inner{background: red;
        }
        </style>
        
      • 样式不生效。

    • 示例:

      • vue3-7-15/src/App.vue

        <script>
        import Scoped from "./components/scoped.vue"export default {componets: {Scoped,},
        }
        </script>
        <template><div class="parent"><Scoped><h2 class="inner">这是来自于父组件的插槽内容</h2></Scoped></div>
        </template>
        <style scoped>
        h2 {color: blue;
        }
        </style>
        
      • vue3-7-15/src/components/scoped.vue

        <template><slot></slot>
        </template>
        
      • 直接在父组件中设置插槽的样式,生效。

  • :global()在组件的scoped中设置全局样式。

    • 示例:

      • vue3-7-15/index.html

        <!DOCTYPE html>
        <html lang="en"><head><meta charset="UTF-8"><link rel="icon" href="/favicon.ico"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vite App</title></head><body><div id="app"></div><div id="root">root</div><script type="module" src="/src/main.js"></script></body>
        </html>
        
      • vue3-7-15/src/main.js

        import { createApp } from 'vue'import App from './App.vue'
        import router from './router'
        const app = createApp(App)
        app.use(router)
        app.mount('#app')
        
      • vue3-7-15/src/App.vue

        <script>
        export default {}
        </script>
        <style scoped>
        :global(#root) {color: red;
        }
        </style>
        
    • 在组件的scoped中设置的全局样式生效了。

vue3于父组件中直接上子组件上设置的事件直接会绑定到子组件的根节点上

  • vue3于父组件中直接上子组件上设置的事件直接会绑定到子组件的根节点上。

    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Emit from "./components/emit.vue"export default {componets: {Emit,},methods: {handleClick(type) {alert(`父组件中-${type}`)}}
        }
        </script>
        <template><Emit @click="handleClick"></Emit>
        </template>
        
      • vue3-7-15/src/components/emit.vue

        <template><div>子组件上的根节点-我是一个按钮</div><!-- <div @click="handleClick">我是一个按钮</div> -->
        </template>
        
      • vue3中父组件上绑定的事件会触发。

  • vue3设置上emits可以设置在当前组件中那些组件是自定义事件,需要基于$emit(“自定义事件名”)才能向让父组件在其自身组件实例上绑定的该同名方法被触发。

    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Emit from "./components/emit.vue"export default {componets: {Emit,},methods: {handleClick(type) {alert(`父组件中-${type}`)}}
        }
        </script>
        <template><Emit @click="handleClick"></Emit>
        </template>
        
      • vue3-7-15/src/components/emit.vue

        <template><div @click="handleClick">子组件上的根节点-我是一个按钮</div>
        </template><script>
        export default {emits: ["click"], // 标识哪些事件是自定义的methods: {handleClick() {console.log(`子组件中点击事件@click`)//   this.$emit("click", "hello")}}
        }
        </script>
        
      • 此时如果子组件不使用this.$emit(“click”)触发自定义的click事件,在父组件上监听不到它的执行。

    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Emit from "./components/emit.vue"export default {componets: {Emit,},methods: {handleClick1(type) {alert(`父组件中-${type}`)}}
        }
        </script>
        <template><Emit @click="handleClick1"></Emit>
        </template>
        
      • vue3-7-15/src/components/emit.vue

        <template><div @click="handleClick">子组件上的根节点-我是一个按钮</div>
        </template><script>
        export default {emits: ["click"], // 标识哪些事件是自定义的methods: {handleClick() {console.log(`子组件中点击事件@click`)this.$emit("click", "hello")}}
        }
        </script>
        
      • 此时如果子组件先执行handleClick(),之后使用this.$emit(“click”)触发自定义的click事件,在父组件上监听到才执行handleClick1()。

    • 示例:
      • vue3-7-15/src/App.vue

        <script>
        import Emit from "./components/emit.vue"export default {componets: {Emit,},methods: {handleClick1(type) {alert(`父组件中-${type}`)}}
        }
        </script>
        <template><Emit @click="handleClick1"></Emit>
        </template>
        
      • vue3-7-15/src/components/emit.vue

        <template><div @click="handleClick">子组件上的根节点-我是一个按钮</div>
        </template><script>
        export default {methods: {handleClick() {console.log(`子组件中点击事件@click`)this.$emit("click", "hello")}}
        }
        </script>
        
      • 由于没基于emits标识哪些事件是自定义的,此时如果子组件先执行handleClick(),之后使用this.$emit(“click”)触发自定义的click事件,在父组件上监听到才执行handleClick1(),此时handleClick1()的入参是子组件传递的值"hello"。而由于没基于emits标识哪些事件是自定义的,父组件依旧会监听到子组件根节点上执行了click事件,于是父组件的handleClick1(),此时handleClick1()的入参是子组件根节点的事件对象。

Suspense组件可以支持渲染异步组件

  • Suspense组件主要的作⽤优雅地处理异步组件的加载状态。

  • 可以支持渲染异步组件 并且添加loading,我们需要先有一个异步组件。异步组件可以是懒加载的组件,也可以在setup被异步执行的组件。我们也可以自己写一个异步组件。

  • 异步组件示例:

    <template><div>这是一个异步加载到的的组件---哈哈</div>
    </template><script setup>
    await new Promise((resolve, reject) => {setTimeout(() => {resolve()}, 1000)
    })
    </script>
    

    等价于

    <template><div>这是一个异步加载到的的组件---哈哈</div>
    </template><script>
    export default {async setup() {await new Promise((resolve, reject) => {setTimeout(() => {resolve()}, 1000)})}
    }
    </script>
    
  • Suspense组件的示例:

    • vue3-7-15/src/App.vue

      <script>
      import AsyncDemo from "./components/async-demo.vue"
      import { Suspense } from "vue"export default {componets: {AsyncDemo,Suspense}
      }
      </script>
      <template><Suspense><template #default><AsyncDemo></AsyncDemo></template><template #fallback>正在加载异步组件的loading文字 </template></Suspense>
      </template>
      
    • vue3-7-15/src/components/async-demo.vue

      <template><div>这是一个异步加载到的的组件---哈哈</div>
      </template><script setup>
      await new Promise((resolve, reject) => {setTimeout(() => {resolve()}, 1000)
      })
      </script>
      

Vue3和Vue2对比

  1. 整个性能比以前高了

    • 代理实现得更优越了。
      • 为什么性能高了?
        • Object.defineProperty()性能低。要递归增加getter和setter,不存在的属性不能事件进行getter与setter劫持,数组由于性能问题不能用它,需要使用 s e t ( ) 与 set()与 set()delete()给它上补丁。
          • 无法支持set或者map的属性劫持
          • 优化层级不能嵌套过深,属性使用的时候一定要缓存。
          • 有些属性不需要响应式 Object.freeze()
        • Proxy(完美解决以上的问题)
    • diff算法的缺点是:要一层层比对。
      • vue3在模版编译的时候做了很多优化。
        • Block(收集当前组件的动态节点) Tree (靶向更新)更新的过程中会进行动态属性的描述(标记哪些属性会变化,不变的不用更新)。
          • vue3 建议是尽量模板语法,jsx 无法得到这些靶向更新的优化支持。
  2. 整个体积小了。

    • 用的compositionAPI打包小。
    • 删除vue2大量api
      • $set$delete.native$listenerseventBus$on$emit$off$once都移除了;
      • 不再支持keyCode修饰符
      • 过滤器 干掉。
      • inline-template 直接删除。
      • Vue.componentVue.directive等全局静态方法,全部移除。
      • .sync移除,如@xxx.sync="xxx"不再支持。
      • provideinject 实例上的api也进行了转移。需要使用import {provide,inject} from 'vue'这类写法。
  3. vue3 采用ts来编写提示好, vue2.7 也是用ts来编写的

  4. 以前vue2把代码都放在一起管理,想扩展或者单独使用不方便, vue3在一个仓库下管理了多个项目,每个模块可以单独使用

Vue3对⽐Vue2的变化

  • Vue3对⽐Vue2的变化?
    1. 性能优化(更快):
      • 使⽤了Proxy替代Object.defineProperty实现响应式。(为什么?defineProperty需要对属性进⾏递归重写添加getter及setter 性能差,同时新增属性和删除属性时⽆法监控变化,需要 s e t 、 set、 setdelete⽅法。此⽅法对数组劫持性能差,同时不⽀持map和set的数据结构。)
      • 模板编译优化。给动态节点增添PatchFlag标记;对静态节点进⾏静态提升;对事件进⾏缓存处理等。
      • Diff算法优化,全量diff算法中采⽤最⻓递增⼦序列减少节点的移动。在⾮全量diff算法中只⽐较动态节点,通过PatchFlag标记更新动态的部分。
    2. 体积优化(更⼩):
      • Vue3移除了不常⽤的API:
        • 移除inline-template (Vue2中就不推荐使⽤)
        • o n 、 on、 onoff、$once (如果有需要可以采⽤mitt库来实现)
        • 删除过滤器 (可以通过计算属性或者⽅法来实现)
        • 移除.sync .native)修饰符 (.sync通过 v-model:xxx实现,.native为Vue3中的默认⾏为) 以及不在⽀持keycode作为v-on修饰符(@keyup.13不在⽀持)
        • 移除全局API。Vue.component、Vue.use、Vue.directive (将这些api挂载到实例上)
      • 通过构建⼯具Tree-shaking机制实现按需引⼊,减少⽤户打包后体积。
    3. ⽀持⾃定义渲染器:
      • ⽤户可以⾃定义渲染API达到跨平台的⽬的。扩展能⼒更强,⽆需改造Vue源码就可以支持类似于微信小程序这类平台。
    4. TypeScript⽀持:
      • Vue3源码采⽤Typescript来进⾏重写 , 对Ts的⽀持更加友好。
    5. 源码结构变化:
      • Vue3源码采⽤ monorepo ⽅式进⾏管理,将模块拆分到package⽬录中,解耦后可单独使⽤。

vue3源码的核心组成

  • vue3的源码组成结构 : vue
    • @vue/compiler-dom - @compiler-core (将我们的模版变成render函数)。
    • @vue/runtime-dom - @vue/runtime-core - @vue/reactivity 方便管理可以单独使用。

Vue3 响应式数据原理

const isObject = (val) => val !== null && typeof val === "object"
const proxyMap = new WeakMap()
function createReactiveObject(target) {if (!isObject(target)) {console.warn(`value cannot be madereactive: ${String(target)}`)return target}// 经过劫持处理过的,就不在重复处理了const existingProxy = proxyMap.get(target)if (existingProxy) return existingProxy// 进⾏数据劫持const proxy = new Proxy(target, {get: function get(target, key, receiver) {const res = Reflect.get(target, key)if (isObject(res)) {return reactive(res)}return res},set: function set(target, key, value, receiver) {let oldValue = target[key]if (oldValue === value) returnconst result = Reflect.set(target, key, value, receiver)console.log("渲染")return result}})proxyMap.set(target, proxy)return proxy
}
function reactive(target) {return createReactiveObject(target)
}
const state = reactive({ name: "jw", arr: [1, 2, 3] })
state.name = "哈哈"
state.arr[0] = 100

Proxy与Object.definePrototype()

  • 以前劫持的是属性-重写set和get,新增的不行。
  • proxy劫持的是对象-代理,并没有增添客户的属性。代理的范围变大了。

Proxy

const 以函数作为属性的代理配置对象 = {get: function(obj, prop) {return prop in obj ? obj[prop] : 37;}
};
const 源对象 = {}
const 代理对象 = new Proxy(源对象, 以函数作为属性的代理配置对象);
代理对象.a = 1;
代理对象.b = undefined;console.log(代理对象.a, 代理对象.b);      // 1, undefined
console.log('c' in 代理对象, 代理对象.c); // false, 37
  1. Proxy
  2. Proxy()的特点:
    • Proxy()返回的是一个代理对象,对该返回的代理对象执行操作才会触发以函数作为属性的代理配置对象中的配置属性。
    • 对源对象直接进行的操作,并不会与代理对象有什么直接联系,以函数作为属性的代理配置对象也监听不到源对象上的直接修改。
    • 源对象一般是常被作为代理对象的存储后端。
      • 代理对象一般根据目标验证关于源对象不可扩展性或不可配置属性的不变量。
      • 也就是说,一般一旦一个对象被作为代理对象后,就不直接改动它了,只用于存储数据,以便代理对象对应的以函数作为属性的代理配置对象中的函数里去修改它。

Reflect

  1. Reflect
  • Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与 proxy handler (en-US) 的方法相同。Reflect 不是一个函数对象,因此它是不可构造的。
  • 与大多数全局对象不同 Reflect 并非一个构造函数,所以不能通过 new 运算符对其进行调用,或者将 Reflect 对象作为一个函数来调用。Reflect 的所有属性和方法都是静态的(就像 Math 对象)。
  • 虽然Reflect常与Proxy来一起使用,但先有的Reflect才有的Proxy。两者不是包含的关系,而是同为js的基础API。不过,Proxy的入参值一般与Reflect入参值保持一致。

Proxy懒代理

// 以前我们劫持的是属性(重写set和get)(新增的不行) $set $delete
// proxy 劫持的是对象 (代理,并没有增添额外的属性)(劫持的范围变大了)
function isObject(value) {return value !== null && typeof value === "object"
}
const state = { name: "zf", age: { n: { n: 100 } } }
// 最终返回的是代理对象,后续我们使用代理对象访问属性
function reactive(state) {const proxy = new Proxy(state, {get(target, key, receiver) {// target指代的是被代理源对象// key 是取值的属性// receiver 代理对象// 依赖收集// return target[key]let res = Reflect.get(target, key, receiver)if (isObject(res)) {// 懒代理return reactive(res)}return res},set(target, key, value, receiver) {console.log("用户设置值了")return Reflect.set(target, key, value, receiver)}})return proxy
}
// proxy支持数组和对象的新增以及删除,而且没有给属性重新定义。 性能好,是懒代理的
const proxy = reactive(state)// 当我取到proxy.age 的时候发现他是一个对象,那我就把这个对象在进行代理
// Reflect 以后会将所有的Object的api全部放到reflect中
// Object.defineProperty  Reflect.defineProperty
// Object.setPrototypeof Reflect.setPrototypeof

靶向更新

  1. 深入学习Vue.js(十三)编译优化-靶向更新
  • 就是在模板语法如果一个是静态内容,如不绑定响应式数据的DPM,则比较时直接跳过它。
  • Vue3的模板经过编译后,可以把从模板中提取到这个信息附着到对应的vnode上,可以看到编译后的vnode中p标签多了一个patchFlag属性。

vue3语法

  1. new Vue不再使用了,而是使用createApp()来创建应用。
    • Vue3整个的入口都是基于组件 createApp(组件)

入口文件的更改

全局组件

  • Vue2中的全局扩展 Vue.component, Vue.directive Vue.use Vue.prototype -> app.config.globalProperties , app.use app.mixin;

注释全局组件

访问全局组件

选项式
组合式
  • Vue3 composition ApireactivecomputedwatchwatchEffectreftoReftoRefs

vue3生命周期

  1. 可以写多次。
  2. 名称修改了。
    • 生命周期: setup 替代了 (beforeCreate created) onXxxx (beforeDestroy destroyed) 做了修改

与vue2生命周期的对比

全局捕获错误示例

  • app.config.errorHandler 如果面试中问到如何监控vue中的错误;

组件的组成

  • 组件的组成
    • 模板
    • 实例:生命周期、属性、状态、事件、通信方式、插槽
    • 样式

组件中配置组件名

  1. 开发中如果有对应的语法糖,一般就使用对应的语法糖写法。
    • setup语法声明的组件 要配置name属性 defineOption();

Vue3编码

  • Vue2中的全局扩展
  • app.config.errorHandler
  • Vue3整个的计算器老师基于组件

setup(){}与setup模式

  • Vue组件我们期望采用vue3 compositionAPI的方式来进行编写 setup(){} , setup语法糖(新的语法);

with

  1. 模板中this可以省略也可以不省略。内部可以认为是用了with(){}来达到类似的效果。
let proxy = { name: "zf" }
with (proxy) {console.log(proxy.name) //zf
}

计算属性computed

计算属性与watch

  • 什么时候用watch,什么时候用computed?

watch

watchEffect

ref

ref的实现原理

// Object.defineProperty({getter})
const total = {// ref的实现原理_value: null,get value() {console.log("依赖收集")return this._value},set value(val) {this._val = val}
}
console.log(total.value)
total.value = "abc"
console.log(total.value)

toRef

toRefs

props与attrs与emits与slots与expose

数据传递

属性通信

事件通信

插槽通信

setup语法糖的内容

  • Setup语法的使用
    • const props = defineProps()
    • const emit = defineEmits()
    • defineExpose()
    • const attrs = useAttrs()
    • const slots = useSlots()

ref与reactive与

自定义use

获取props

获取attrs

获取emit

获取slots

设置expose

setup语法糖的使用

进阶参考

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

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

相关文章

Windows11 C盘瘦身

1.符号链接 将大文件夹移动到其他盘&#xff0c;创建成符号链接 2.修改Android Studio路径设置 1.SDK路径 2.Gradle路径 3.模拟器路径 设置环境变量 ANDROID_SDK_HOME

FLutter 开发中 fijkplayer设置屏幕常亮

FLutter 视频播放&#xff1a; 目前在做FLutter种的视频播放功能&#xff0c;遇到了视频播放的时候&#xff0c;屏幕突然黑屏了。网上找了很多&#xff0c;无论是设置在原生的Activity界面&#xff0c;添加如下代码&#xff0c; getWindow().addFlags(WindowManager.LayoutPara…

基于单片机的盲人导航智能拐杖老人防丢防摔倒发短息定位

功能介绍 以STM32单片机作为主控系统&#xff1b; OLED液晶当前实时距离&#xff0c;安全距离&#xff0c;当前经纬度信息&#xff1b;超声波检测小于设置的安全距离&#xff0c;蜂鸣器报警提示&#xff1a;低于安全距离&#xff01;超声波检测当前障碍物距离&#xff0c;GPS进…

虚幻引擎复习笔记

虚幻引擎 宏观了解 工具链&#xff1a;纹理&#xff0c;材质&#xff0c;模型&#xff0c;动画&#xff0c;粒子&#xff0c;地形&#xff0c;声音&#xff0c;光照&#xff0c;毛发&#xff0c;破碎逻辑编写&#xff1a;蓝图可视化脚本&#xff0c;虚幻CGamePlay框架 初次接…

python发送邮件yagmail库

yagmail库发送邮件简洁&#xff0c;代码量少 import yagmaildef send_yagmail(sender, send_password, addressee, hostsmtp.qq.com, port465):yag yagmail.SMTP(sender, send_password, host, port)img_url https://img2.baidu.com/it/u483398814,2966849709&fm253&…

基于单片机的智能空调系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前水温&#xff0c;定时提醒&#xff0c;水量变化DS18B20检测当前水体温度&#xff1b;水位传感器检测当前水位&#xff1b;继电器驱动加热片进行水温加热&#xff1b;定时提醒喝水&#xff0c;蜂鸣器报警&#x…

学习注解的使用模拟RequestMapping解析path

文章目录 前言一、代码部分总结 前言 注解在后端开发过程中提供了许多的便利&#xff0c;提高了代码简洁性和可读性&#xff0c;在应用程序中占据越来越重要的作用&#xff0c;很有学习的必要&#xff0c;接下来会通过代码来完成对类、方法、属性注解的解析。 一、代码部分 p…

LeetCode面试题02.07.链表相交

面试题02.07.链表相交 两种解题思路 面试题02.07.链表相交一、双指针二、哈希集合 一、双指针 这道题简单来说&#xff0c;就是求两个链表交点节点的指针 这里注意&#xff1a;交点不是数值相等&#xff0c;而是指针相等 为了方便举例&#xff0c;假设节点元素数值相等&…

用Python采用Modbus-Tcp的方式读取485电子水尺数据

README.TXT 2023/6/15 V1.0 实现了单个点位数据通信、数据解析、数据存储 2023/6/17 V2.0 实现了多个点位数据通信、数据解析、数据存储 2023/6/19 V2.1 完善log存储&#xff0c;仅保留近3天的log记录&#xff0c;避免不必要的存储&#xff1b;限制log大小&#xff0c;2MB。架…

数字原生时代,奥哲如何让企业都成为“原住民”?

22年前&#xff0c;美国教育学家马克‧普伦斯基&#xff08;Marc Prensky&#xff09;出版了《数字原生与数字移民》&#xff08;Digital Natives, Digital Immigrants&#xff09;一书&#xff0c;首次提出了“数字原住民”和“数字移民”两大概念&#xff0c;用来定义跨时代的…

法规发展与算法备案:预测未来的重要议题

随着科技的快速发展&#xff0c;算法逐渐成为各行各业的核心驱动力&#xff0c;尤其在互联网领域&#xff0c;算法更是被赋予了生命力&#xff0c;为人们提供了便利的同时&#xff0c;也引发了一系列问题。因此&#xff0c;未来法规发展对于算法备案的关注将变得尤为重要。本文…

05-Vue基础之Class 与 Style 绑定

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

OpenCV如何实现图像截取

import cv2img cv2.imread("image/2.png", 1) roi cv2.selectROI(img,showCrosshairTrue,fromCenterFalse) xmin,ymin,w,h roi imgROI img[ymin:yminh,xmin:xminw].copy()cv2.imshow("demo",imgROI) cv2.waitKey(0) 代码的核心就是用到了OpenCV中的函数…

leetcode_54 螺旋矩阵

1. 题目 螺旋矩阵 2. 题意 给定一个二维数组&#xff0c;顺时针螺旋输出其中的元素。 3. 题解 3.1 自己想的 一层一层的&#xff0c;关键点在于如何进入下一循环。和确定停止的位置&#xff0c;找停止的位置写了个函数。 用控制比特位的方式来进行控制一次顺时针循环, 还…

序列化的意义以及常见的的序列化方式

一&#xff0c;为什么序列化&#xff1f; 对象保存到文件或数据库网络编程时对象跨平台跨语言传输&#xff0c;也即从windows上序列化的对象可到linux上反序列化&#xff0c;用c&#xff03;序列化的对象可以被java反序列化。RPC远程接口调用 二&#xff0c;常见得序列化方式…

【数据结构】_1.集合与复杂度

目录 1. 集合框架 2. 时间复杂度 2.1 时间复杂度和空间复杂度 2.2 时间复杂度的概念 2.3 大O的渐进表示法 2.3.1 精确的时间复杂度表达式 2.3.2 大O渐进表示法的三条规则 2.3.3 时间复杂度的最好、平均与最坏情况 2.4 时间复杂度计算示例 3.空间复杂度 1. 集合框架 …

字节跳动后端面试,笔试部分

var code "7022f444-ded0-477c-9afe-26812ca8e7cb" 背景 笔者在刷B站的时候&#xff0c;看到了一个关于面试的实录&#xff0c;前半段是八股文&#xff0c;后半段是笔试部分&#xff0c;感觉笔试部分的题目还是挺有意思的&#xff0c;特此记录一下。 笔试部分 问…

【多线程例题】顺序打印abc线程

顺序打印-进阶版 方法一&#xff1a;三个线程竞争同一个锁&#xff0c;通过count判断是否打印 方法二&#xff1a;三个线程同时start&#xff0c;分别上锁&#xff0c;从a开始&#xff0c;打印后唤醒b 三个线程分别打印A&#xff0c;B&#xff0c;C 方法一&#xff1a;通过co…

JavaFX中MVC例子理解

JavaFX可以让你使用GUI组件创建桌面应用程序。一个GUI应用程序执行三个任务&#xff1a;接受用户的输入&#xff0c;处理输入&#xff0c;并显示输出。而一个GUI应用程序包含两个 类型的代码&#xff1a; 领域代码。处理特定领域的数据和遵循业务规范。交互代码。处理用户输入…

【Linux】多线程(上)

本文详细介绍了多线程的常见概念 生产者消费者模型将在多线程&#xff08;下&#xff09;继续讲解 欢迎大家指正 提起讨论进步啊 目录 多线程的理解 线程的优点 线程的缺点&#xff1a; 线程的用途 线程VS进程 用户级线程库 POSIX线程库 线程创建&#xff1a; 线程…