Vue3常见知识**MS【4】

news/2024/9/18 14:45:28/ 标签: vue.js, 前端, javascript

一、vue2和vue3的区别

1、数据绑定原理不同

   vue2:数据绑定是利用ES5的一个API:Object.definePropert() 对数据进行劫持,结合发布订阅模式的方式来实现的。

   vue3:使用了ES6的Proxy API对数据代理。相比vue2.x,使用proxy的优势如下:

  • defineProperty只能监听某个属性,不能对全对象监听;
  • 可以省去for in,闭包等内容来提升效率(直接绑定整个对象即可);
  • 可以监听数组,不用再去单独的对数组做特异性操作vue3.x可以检测到数组内部数据的变化。

2、是否支持碎片

        vue2:不支持碎片。

        vue3:支持碎片(Fragments),或者说它可以拥有多个根节点。

3、API类型不同

        vue2:使用选项式(选项型api,选项型api在代码里分割了不同的属性:data,computed,methods等。

        vue3:使用组合式api,新的合成型api能让我们使用方法来分割,相比于旧的api使用属性来分组,这样代码会更加简便和整洁。

4、定义数据变量和方法不同

        vue2:是把数据放入data中,在vue2中定义数据变量是data(){},创建的方法要在methods:{}中。

        vue3:就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。使用以下三个步骤来建立反应性数据:

  • 从vue引入reactive;
  • 使用reactive() 方法来声明数据为响应性数据;
  • 使用setup()方法来返回我们的响应性数据,从而template可以获取这些响应性数据。

5、生命周期钩子函数不同

vue2:生命周期:

  • beforeCreate 组件创建之前
  • ​created 组件创建之后
  • ​beforeMount 组价挂载到页面之前执行
  • ​mounted 组件挂载到页面之后执行
  • ​beforeUpdate 组件更新之前
  • ​updated 组件更新之后

vue3:生命周期:

  • setup 开始创建组件前
  • onBeforeMount 组价挂载到页面之前执行
  • onMounted 组件挂载到页面之后执行
  • onBeforeUpdate 组件更新之前

        onUpdated 组件更新之后而且vue3.x 生命周期在调用前需要先进行引入。除了这些钩子函数外,其中vue3.x它还增加了onRenderTracked 和onRenderTriggered函数。

6、父子传参不同

        vue2:父传子,用props,子传父用事件 Emitting Events。在vue2中,会调用this$emit然后传入事件名和对象。

        vue3:父传子,用props,子传父用事件 Emitting Events。在vue3中的setup()中的第二个参数content对象中就有emit,那么我们只要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。

7、指令与插槽不同

        vue2:中使用slot可以直接使用slot;v-for与v-if在vue2中优先级高的是v-for指令,而且不建议一起使用。

        vue3:中必须使用v-slot的形式;vue3中v-for与v-if,只会把当前v-if当做v-for中的一个判断语句,不会相互冲突;vue3中移除keyCode作为v-on的修饰符,当然也不支持config.keyCodes;vue3中移除v-on.native修饰符;vue3中移除过滤器filter。

8、main.js文件不同

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

        vue3:中需要使用结构的形式进行操作,引入的是工厂函数;vue3中app组件中可以没有根标签。

9、Vue3带来了什么

        更快的渲染速度:Vue3使用了Proxy代理对象,可以更快地跟踪数据变化,从而提高渲染速度。

        更小的体积:Vue3的体积比Vue2更小,同时也支持按需加载,减少了页面加载时间。

        更好的TypeScript支持:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示。

        更好的组件封装:Vue3引入了Composition API,可以更好地封装组件逻辑,使得组件更加可复用和易维护。

        更好的响应式系统:Vue3的响应式系统进行了重构,可以更好地处理嵌套对象和数组的变化,同时也提供了更多的API来处理响应式数据。

        总之,Vue3带来了更好的性能、更小的体积、更好的TypeScript支持、更好的组件封装和更好的响应式系统,使得开发者可以更加高效地开发Vue应用。

 二、vue2和vue3响应式原理(Object.defineProperty和Proxy的区别)

1、 vue2的响应式原理

  • ​ vue2的响应式实现主要是利用了Object.defineProperty的方法里面的setter 与getter方法,来完成数据劫持
  • 使用观察者模式来实现响应式的变化。
  • 具体做法: 在组件初始化时会给data的每一个属性注册getter和setter,然后再new 一个自己的Watcher对象,此时watcher会立即调用组件的render函数去生成虚拟DOM。在调用render的时候,就会需要用到data的属性值,此时会触发getter函数,将当前的Watcher函数注册进sub里(订阅)。当data属性发生改变之后,就会遍历sub里所有的watcher对象,通知它们去重新渲染组件(发布)。
  • Vue2的响应式原理存在一些缺陷,例如无法监听数组的变化,需要通过特殊的方法来实现 ​

2、vue3的响应式原理:

   ​1)、 vue3用Proxy代替了Object.defineProperty。
  • Proxy 可以直接监听对象而非属性,可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的。
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  • Proxy也解决了数组监听的问题,不用再去单独的对数组做特异性操作vue3.x可以检测到数组内部数据的变化。也解决了用下标修改数组元素不是响应式的问题。
  • Proxy的性能比Object.definePropery高10倍。
  • Vue3使用了WeakMap来存储依赖关系,避免了Vue2中Watcher的内存泄漏问题。

三、组合式api和选项式api的区别

1、组织代码的方式:

        选项式 api 是按照 选项(配置项)的思路来分隔组织代码的,例如 data、methods 和 mounted。这些选项所定义的属性都会暴露在函数内部的 this 上,指向当前的组件实例。

        组合式 api 是按照 业务逻辑的方式分隔组织代码的。组合式api中使用函数的方式代替选项式api的配置项。让代码组织更加灵活,在任何需要的地方调用对应的函数。比如:在需要定义响应式数据的地方,直接调用ref或者reactive函数既可以(不需要像选项式api那样,非得写在data配置项里)。

2、代码的复用:

        选项式api使用mixin来完成,mixin里也是配置项。容易发生命名冲突且关系不清。不够灵活(如果:只需要引入某个函数,就需要把整个混入对象都引入,颗粒度不够小)。

        组合式api使用组合式函数的方式,让代码更加灵活,复用性更好,组件里面的逻辑可以进行模块化。也不存在this的问题。

3、对TS的支持:

        组合式api  TS 的支持更好。

4、单元测试:

        组合式api 由于使用的是函数的方式,所以,更方便做单元测试。

5、使用场景:

        选项式api 适用于小型和中型项目。否则,代码逻辑复杂后,导致组件关系复杂,单个组件内部的代码太多。

        组合式api 适用于大型项目,当然小中项目也是没有问题。

四、vue3新增的响应式相关的函数

ref,reactive,readonly,computed,watch,watchEffect 

1、ref的理解 
  Vue2版本:

        在Vue2该版本中,ref的作用总结来说无非就是两种:1.获取页面DOM元素。2.父子组件之间通信,获取子组件的对象。下面举个例子来说明其用法:

子组件对应代码

<template><view><input :focus="isFocus" type="text" placeholder="请输入内容" /></view>
</template>
<script>export default {name:"base-input",data() {return {"isFocus":false};},methods:{focus(){this.isFocus = true}}}
</script>

父组件对应代码

<template><view><base-input ref="usernameInput"></base-input><button type="default" @click="getFocus">获取焦点</button> </view>
</template>
<script>export default {methods:{getFocus(){//通过组件定义的ref调用focus方法this.$refs.usernameInput.focus(),console.log(this.$refs.usernameInput.isFocus)}}}
</script>

 访问子组件实例或子元素,通过 ref 为子组件赋予一个 ID 引用,在vue的js中可通this.$refs.XXX来获取到组件对象

Vue3版本

  响应式数据的优点

  • 数据一旦发生变化,系统能够立即响应,无需等待用户的显式请求。这种机制显著提高了数据处理的实时性和效率,尤其是在处理大量数据时更为明显。通过减少不必要的请求和等待时间,响应式数据系统能够更快地处理数据,从而优化整体性能。
  • 用户在使用响应式数据驱动的应用时,能够即时获得数据变化的反馈,无需长时间等待系统响应。这种即时性提升了用户的满意度和体验。
  • 响应式数据系统通常只需要存储最新的数据,无需保留大量历史数据,从而节约了存储空间。
  • 响应式数据系统具有高度的自动化和即时响应特性,因此降低了系统维护的复杂性和成本。
  • 响应式数据系统能够确保数据在多个组件或服务之间保持一致性,提高数据的可靠性。
  • 前端开发中,响应式数据能够自动驱动视图的更新,当数据发生变化时,无需手动操作DOM即可实现视图的同步更新,简化了开发流程并提高了开发效率。

所以,为了更好的完成客户端与服务端交互,将运行时实时更新的客户端需求与服务端响应做到及时反馈与连接是优化网页的刚需,那么将特定数据转变成响应式数据则成为必不可少的要求。

如何将数据变成响应式数据?

        在Vue3版本中,系统为我们编写提供了简便方法,那就是通过ref包裹数据,将源数据便捷的转变为响应式数据,下面通过简单例子来诠释:

<template>  <div>  <p>{{ count }}</p>  <button @click="increment">Increment</button>  </div>  
</template>  <script>  
import { ref } from 'vue'  export default {  setup() {  // 使用 ref 创建一个响应式的数据对象  const count = ref(0)  // 定义一个方法来修改这个响应式数据  function increment() {  count.value++  }  // 将响应式数据和修改数据的方法返回,使其能在模板中被访问  return {  count,  increment  }  }  
}  
</script>

        在这个实例中,首先通过 ref 定义一个名为 count 的响应式数据对象,并将其初始值设置为 0。然后,定义了一个函数名 increment的 方法,用于在点击按钮时递增 count 的值。最后,通过返回一个对象,将 count 和 increment 方法暴露给模板,使其能够在模板中被访问和使用。 

        需要注意的一个地方,在vue3的ref使用中,将数据转换的方式就是用ref将想要转换的数据通过括号包裹,在<template>中调用也和平常无异,但若想要将数据进行更改,那么在<script>中必须添加后缀 .value,才能实现对其精准更正。一般的,通过定义一个触发事件,来进行用户体验良好,交互性更强的动态改变。

注意:vue2和vue3中的ref用法截然不同,并且两者的作用不同。vue2中ref主要实现信息的传递,而vue3中主要实现数据的响应式处理。

2、reactive的理解

        是一个用于创建响应式数据的函数‌,它接收一个对象作为参数,并返回一个代理对象,该代理对象可以跟踪对象的变化,并在对象发生更改时通知相关的依赖项。使用Reactive方法,可以将普通的JavaScript对象转换为响应式对象,从而使相关的组件在对象发生更改时自动重新渲染。这是通过Vue.js的响应式系统实现的,该系统能够跟踪属性的变化,并在发生更改时触发重新渲染‌

        功能: 接受一个对象,返回一个对象的响应式代理(proxy)。返回的对象以及其中嵌套的对象都会通过 ES Proxy 包裹,因此不等于源对象,建议只使用响应式代理,避免使用原始对象。

        响应式转换是“深层”的:它会影响到所有嵌套的属性。一个响应式对象也将深层地解包任何 ref 属性,同时保持响应性。

        总的来说,Reactive方法是Vue.js 3中用于创建响应式数据的重要工具,它使得开发者能够更方便地处理复杂的数据对象,并在数据变化时自动更新UI,从而提高应用程序的响应性和用户体验。

        注意点:当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。

3、ref和reactive的区别

        ref和reactive的主要区别在于它们处理的数据类型、访问方式以及更新触发机制。‌

数据类型‌:

  • ref:适用于基本数据类型(如字符串、数字、布尔值等),它返回一个包含value属性的对象,通过修改value属性的值来触发组件更新。
  • reactive:适用于复杂对象或数组,它返回一个响应式的Proxy对象,通过修改该对象的属性值来触发组件更新。

访问方式‌:

  • ref:需要通过.value属性来访问和修改值,例如count.value。在模板中,如果ref作为顶层属性被访问,则会自动解包,不需要使用.value
  • reactive:可以直接访问和修改对象或数组的属性,例如state.count,无需使用.value属性。

更新触发机制‌:

  • ref:通过修改.value的值或直接赋值给.value来触发更新。
  • reactive:通过直接修改对象或数组的属性来触发更新。

总结来说,ref更适合处理简单的响应式数据,而reactive更适合处理复杂的对象或数组,提供更灵活的响应式更新机制。‌

五、其他 

1、toRef和toRefs

  • 相同点

        ​ toRef 和 toRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用,也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新,如果你知道 浅拷贝 的话那么这个引用就很好理解了,它复制的其实就是引用 + 响应式 。

  • 不同点:

        toRef: 复制 reactive 里的单个属性并转成 ref

        toRefs: 复制 reactive 里的所有属性并转成 ref

2、shallowReactive 与 shallowRef

  • hallowRef:只处理基本数据类型的响应式
  • shallowReactive:只处理对象最外层属性的响应式(浅响应式)
  • 浅层作用的响应式数据处理:只处理第一层对象的数据,再往下嵌套的数据,操作数据是不起作用的
  • shallowReative与shallowRef在某些特殊的应用场景下,是可以提升性能的,前者针对对象,用于浅层作用的响应式数据处理,而后者只处理基本数据类型的响应式,不进行对象的响应式处理。

3、readonly 与 shallowReadonly【扩展】

         readonly与shallowReadonly都是让响应式数据只具备读的能力,后者是浅层次的只读,也就是只对数据对象第一层起作用,深层次的嵌套,当时用shallowReadonl()处理时,深层次数据支持被修改

  • readonly: 让一个响应式数据变为只读的 (深只读),让一个响应式数据变为只读的,接收一个响应式数据,经过readonly加工处理一下,那么新赋值的数据都不允许修改
  • 接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理
  • shallowReadonly: 让一个响应式数据变为只读的 (浅只读),接收一个响应式数据,经过shallowreadonly的处理,变成一个只读的,只考虑对象的第一层数据,不可以修改,但是第一层嵌套里的深层数据却支持修改
  • 让一个响应式数据变为只读能力(浅只读)

4、toRaw与markRaw转换为普通数据和标记属性非响应式【扩展】

        toRaw,将响应式对象(由 reactive定义的响应式)转换为普通对象,然后赋值给新的变量(不影响原来的对象)

        markRaw,标记一个对象,使其不能成为一个响应式对象。

        toRaw 作用:将一个由 reactive 生成的响应式对象转为普通对象 使用场景:

  • 用于读取响应式对象对应的普通对象
  • 对这个普通对象的所有操作,不会引起页面更新。

        markRaw: 作用:标记一个对象,使其永远不会再成为响应式对象 应用场景: 1、有些值不应被设置为响应式的,例如复杂的第三方类库等 2、当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

5、自定义hooks(组合式函数)的规则和作用:

        在Vue 3中,可以使用组合式 API(Composition API)创建自定义的hooks(也被称为自定义钩子函数)。这些函数通常会包含一些逻辑,可以在多个组件之间复用。

自定义hooks的规则:

  1. 函数名以use开头,表示这是一个hooks。

  2. 内部使用Vue 3的响应式API,通常是refreactivecomputedwatch等。

  3. 应该返回响应式的数据或方法,以便在组件中使用。

  4. 不应该直接操作DOM,而是返回操作的方法供组件使用。

  5. 应该避免在hooks内部进行副作用操作,副作用操作应当放在使用hooks的组件内部或其他hooks中。

hooks调用:

  1. hooks必须在setup函数的根级调用,即:在setup函数执行时,hooks就要被调用
  2. hooks函数可以在其它hooks函数里调用。

作用:

        以函数形式抽离一些可复用的方法像钩子一样挂着,放在外部的js文件里。随时可以引入和调用,实现高内聚低耦合的目标;引用时将响应式变量或者方法显式解构暴露出来如:const {nameRef,Fn} = useXX()

下面是一个简单的自定义hook的例子,它创建了一个可以跟踪的计数器:

// useCounter.js
import { ref } from 'vue';export function useCounter(initialValue = 0) {const count = ref(initialValue);function increment() {count.value++;}function decrement() {count.value--;}return { count, increment, decrement };
}

 然后在组件中使用这个hook:

<template><div><p>Count: {{ count }}</p><button @click="increment">Increment</button><button @click="decrement">Decrement</button></div>
</template><script>
import { useCounter } from './useCounter';export default {setup() {const { count, increment, decrement } = useCounter(0);return { count, increment, decrement };}
};
</script>

6、watch与watchEffect 

        watch和watchEffect都是vue3中的监听器,但是在写法和使用上是有区别的,

1)、监听源:

        watch函数的监听源会明确指定,是watch函数的第一个参数。

        watchEffect函数的监听源是回调函数中使用的所有的响应式数据。自动收集依赖。

2)、懒侦听:

        watch默认是懒侦听,如果要立即执行,则设置第三个参数的配置项immediate 为true。

        watchEffect不是懒侦听,组件一旦执行,那么,回调函数立即会调用

3)、深度侦听:

        watch默认不是深度侦听,如果需要,则设置第三个参数的配置项deep为true。

        watchEffect默认是深度侦听的。

4)、是否能够拿到旧值:

        watch可以。

        watchEffect不可以。

7、provide与inject

        provide 和 inject 是一对新的API,用于在父组件中提供数据,然后在子组件中注入数据。

  • provide:是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值。如果希望提供的数据是响应式的,那么,值就需要是响应式的数据。
  •  inject:一个字符串数组,或者是一个对象。属性值可以是一个对象,包含from和default默认值。
//在父组件中,使用provide提供数据:
//name:定义提供 property的 name。
//value :property的值。setup(){provide('info',"值")}
​
//在子组件中,使用inject注入数据
//name:接收 provide提供的属性名。
//default:设置默认值,可以不写,是可选参数。
setup(){const info = inject("info")inject('info',"设置默认值")return {info}}

8、vue3中定义全局属性

  • 通过config.globalProperties
  • 通过provide注入:在应用实例上设置一个可以被注入到应用范围内所有组件中的值。当组件要使用应用提供的 provide 值时,必须用 inject 来接收。
  • 在main.js中全局引入,然后在组件中获取

 9、响应式数据的判断isRef、isReactive、isReadonly、isProxy

  • isRef:判断一个值是否为一个 ref 对象
  • isReactive:判断一个对象是否是由 reactive创建的响应式代理
  • isReadonly:判断一个对象是否是由 readonly 创建的只读代理
  • isProxy:判断一个对象是否是由 reactive 或 readonly 创建的代理

六、setup配置(setup函数的参数)

        Vue 3中的 setup 函数接收两个参数,分别是 props 和 context。

1、props:父组件传来的属性值

        包含:组件外部传递过来。切组件内部声明接收了的属性。需要注意的是,Vue3中的 props 是只读的,即在setup 函数中不能修改 props 的值。如果需要修改传递过来的数据,可以使用响应式对象或ref。

2、context:上下文对象。

        1)、attrs:值为对象,包含组件外部传递过来,但没有在props配置中声明的属性。相当于this.$attrs

        2)、slots:收到的插槽内容,相当于this.$slots

        3)、emit:分发自定义事件的函数,相当于this.$emit

注意:

        1)、这个钩子会在created之前执行

         2)、内部不存在this

        3)、如果返回值是一个对象,那么这个对象中的键值对会被合并到created钩子的this中,而在视图上也能访问相应的数据值


http://www.ppmy.cn/news/1517104.html

相关文章

【Java设计模式】Builder模式:在Java中清晰构建自定义对象

文章目录 【Java设计模式】Builder模式&#xff1a;在Java中清晰构建自定义对象一、概述二、Builder设计模式的意图三、Builder模式的详细解释及实际示例四、Java中Builder模式的编程示例五、Builder模式类图六、Java中何时使用Builder模式七、Builder模式Java教程八、Builder模…

【Linux篇】Linux的压缩与解压

1. 压缩格式 市面上有非常多的压缩格式&#xff1a; zip格式&#xff1a;Linux&#xff0c;win&#xff0c;MacOS&#xff0c;常用7zip&#xff1a;win常用rar&#xff1a;win常用tar&#xff1a;Linux&#xff0c;MacOS常用gzip&#xff1a;Linux&#xff0c;MacOS常用 如何…

C++_ch07_visual studio调试代码

C_ch07_visual studio调试代码 1.1 Break Point 断点就是程序执行到这里就会暂停&#xff0c;一个程序可以设置很多短点。在visual studio中只需要点击侧栏就可以设置断点。 点击左边的栏目&#xff0c;出现红点就是设置的断点。 另外要确保打断点的位置必须是可执行的代码&…

WordPress美化节日灯笼插件,适合春节的时候使用

源码介绍&#xff1a; WordPress美化节日灯笼插件&#xff0c;适合每年过年的时候安在网站上使用&#xff0c;这款插件可以备用着&#xff0c;一款WordPress节日灯笼美化插件&#xff0c;可以给网页自动加一个灯笼效果使用说明&#xff1a;到网站WP后台 - 插件 - 安装插件 - 上…

【学术会议征稿】第六届智能控制、测量与信号处理国际学术会议 (ICMSP 2024)

第六届智能控制、测量与信号处理国际学术会议 (ICMSP 2024) 2024 6th International Conference on Intelligent Control, Measurement and Signal Processing 文化是人类社会相对于经济和政治的精神活动和产物。传统的人类观念认为&#xff0c;文化是一种社会现象&#xff0…

CDGA|数据治理:统一数据标准成为核心关切

在数字化转型浪潮席卷全球的今天&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;其价值不言而喻。然而&#xff0c;随着数据量呈爆炸式增长&#xff0c;数据来源多样化、格式不一、质量参差不齐等问题日益凸显&#xff0c;给企业的数据管理和利用带来了前所未有的挑战…

C语言基础(二十)

链表是一种常见的数据结构&#xff0c;通常用来存储一系列元素&#xff0c;每个元素由一个节点来表示。在链表中&#xff0c;每个节点包含两部分&#xff1a;数据元素本身和指向下一个节点的指针。这种结构使得链表中的元素在内存中不是连续存储的&#xff0c;而是通过指针连接…

电商支付异常处理分享

时间&#xff1a;2024年08月28日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频地址&#xff1a;https://xima.tv/1_1qSvgv?_sonic0 希望大家帮个忙&#xff01;如果大家有工作机会&#xff0c;希望帮小蒋内推一下&#x…

Spring Boot如何压缩Json并写入redis?

1.为什么需要压缩json&#xff1f; 由于业务需要&#xff0c;存入redis中的缓存数据过大&#xff0c;占用了10G的内存&#xff0c;内存作为重要资源&#xff0c;需要优化一下大对象缓存&#xff0c;采用gzip压缩存储&#xff0c;可以将 redis 的 kv 对大小缩小大约 7-8 倍&…

如何考取PostgreSQL认证证书?

PostgreSQL数据库炙手可热&#xff0c;国内知名的腾讯云TDSQL、阿里云PolarDB都有PostgreSQL版本的产品&#xff0c;还有人大金仓、华为opengauss、翰高数据库等都跟PostgreSQL有关系&#xff0c;所以考一个PostgreSQL认证非常有必要。要获得PostgreSQL认证&#xff0c;可以从以…

PTA - C语言国庆题集1

目录 7-1 阶梯电价7-2 求矩阵的最大值&#xff08;设惟一&#xff09;7-3 换硬币&#xff08;鸡兔同笼&#xff09;7-4 逆序输出一个整数的各位数字7-5 交换最小值7-6 分段函数27-7 数组中能被5整除的数的和7-8 统计字母出现的次数&#xff08;hash思想&#xff09;7-9 字母三角…

openEluer安装软件提示系统缺少的一些库的解决

mysql客户端相关的坑 问题&#xff1a;mysql: error while loading shared libraries: libncurses.so.5 解决&#xff1a; ln -s /usr/lib64/libncurses.so.6 /usr/lib64/libncurses.so.5 问题&#xff1a;mysql: error while loading shared libraries: libtinfo.so.5 解决…

npm阿里云制品仓库

配置 配置仓库地址&#xff0c;可以再在仓库指南看到 npm config set registryxxxxx#登录&#xff0c;帐户密码可以在仓库指南看到 npm login注意&#xff1a;npm>9的版本npm login目前有问题 verbose web login not supported, trying couch&#xff0c;暂时没试验到解决…

数据结构-递归算法-第四天

参考文献&#xff1a; 华为云 博客园 labuladong 的算法笔记 递归是一种编程技巧&#xff0c;一种解决问题的思维方式&#xff1b;分治算法和动态规划很大程度上是递归思想基础上的&#xff08;虽然动态规划的最终版本大都不是递归了&#xff0c;但解题思想还是离不开递归&…

Linux环境使用docker搭建Navidrome本地个人音乐库并实现远程访问

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动Navidrome容器 前言 本文和大家分享一款目前在G站有11KStar的开源跨平台音乐服务器Navidrome&#xff0c;如何在Linux环境本地使用Docker部署&#xff0c;并结合cpolar内网穿透工具配置公网地址&#xff0c;实…

入门STM32--按键输入

上一篇博客我们介绍了如何使用GPIO配置跑马灯&#xff0c;根据GPIO的基本结构图&#xff0c;我们能够发现&#xff0c;他肯定不单单有输出的功能&#xff0c;肯定可以检测IO上的电平变化&#xff0c;实际上就是输入的功能。 1.按键 在大多数情况下&#xff0c;按键是一种简单的…

今日算法:蓝桥杯基础题之“切面条”

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注&#xff01;个人知乎 从今天开始&#xff0c;一起了解算法&#xff0c;每日一题&#xff0c;从 JavScript 的技术角度进行解答&#xff0c;如果你对算法也感兴趣&#xff0c;请多多关注哦。 问题描述 一…

15 - FFmpeg 音频混音(过滤器)

过滤器链接流程 -------- auto_aresample_0:default--[48000Hz flt:stereo]--input0| amix |default--[48000Hz flt:stereo]--auto_aresample_2:default auto_aresample_1:default--[48000Hz flt:stereo]--input1| (amix) | …

Linux 数据结构 顺序表 链表

数据结构&#xff1a; 1.衡量一个程序是否优秀&#xff1a; 1.时间复杂度&#xff1a; 数据量增长与程序运行时间的比例关系以函数描述称为时间渐进复杂度函数,简称时间复杂度 O(c) > O(logn) > O(n) > O(nlogn) > O(n^2) > O(n^3) > O…

一个prolog最简单推理示例

假设现在知道一些年轻人&#xff0c;谁喜欢谁&#xff0c;定义为love(x, y)&#xff1b; 定义了一些这样的关系&#xff1b; 如果x喜欢y&#xff0c;y也喜欢x&#xff0c;则定义他们是一对情侣&#xff1b; 规则表示为&#xff1a; lovers(X,Y) :- love(X,Y), love(Y,X). 输入…