今日分享【Vue3基础知识】

cff4cafa63cf401386830d4cad8ffa18.png

常用地址及工具:

[vue3官网] https://cn.vuejs.org/ vue3官网
[setup 基本使用] https://juejin.cn/post/7002490039066165279 setup基本使用
[vite中文官网] https://cn.vitejs.dev/ Vite官网

1、如何使用vue3 + vite

//要构建一个 Vite + Vue 项目,运行,使用 NPM:
npm init @vitejs/app 项目名
//使用 Yarn:
yarn create @vitejs/app 项目名
// 启动项目
cd app
// 你会觉得非常快速的创建了项目,然而它并没有给你下载依赖,你还有进入文件然后
npm install (or yarn)
npm run dev (or yarn dev)
import { createApp } from 'vue'

  import App from './App.vue'

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

  <!-- 
    引入的不是vue构造函数,而是createApp工厂函数然而,创建实例对象其实就相当于vue2中的vm,mount('#app')就相当于$mount('#app'),并且vue2的写法在vue3不能兼容,
    现在我们进入App组件,你会发现什么不一样的地方,他没有了根标签,在vue2的时候,我们都是在div根标签里面写东西,所以在vue3里面可以没有根标签 
  -->
    <!-- vue2写法 -->
    <template>
    <div class='container'>

    </div>
    </template>

    <!-- vue3写法 -->
    <template>
    <div class='container-left'></div>
    <div class='container-right'></div>
    </template>

2、常用组合式API

①【setup函数是 Composition API(组合API)的入口】,在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用
<script>
  export default {
  name: 'App',
  setup(){
    let name = '王大锤'
    let hello = 'hello!'
    //方法
    function sayHello(){
      console.log(`我叫${name},say${age}`)
    }

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

当然这不是响应式的写法,然后你们可能会问,为什么没有用this,我们要想一想之前为什么要用this,还不是作用域的问题,然而这次我们都在setup里面,所以不会用到this,而且这里兼容vue2的写法如:data,methods…,并且在vue2中可以读取到vue3里的配置但是vue3里面不能读取到vue2的配置,所以,vue3和vue2不要混用,如果有重名那么优先setup。
ps.如果大家不喜欢return这样的写法的话,可以用vue3新语法糖

父组件
  <template>
    <div class="home">
      <HelloWorld wish="不掉发" wishes="变瘦" @carried="carried">
        <h3>实现插槽1</h3>
        <template v-slot:dome>
          <h4>实现插槽2</h4>
        </template>
         </HelloWorld>
           </div>
           </template>

           <script>
           import HelloWorld from "./components/HelloWorld";
          export default {
            name: 'Home',
            components:{
              HelloWorld
            },
            setup(){
              function carried(value){
                alert(`牛呀,都实现了!!!${value}`)
              }
              return {
                carried
              }
            }
          }
        </script>
          -------
            子组件
            <template>
            <h1>HelloWorld</h1>
            <h1>{{ wish }}</h1>
            <button @click="dream">点击实现</button>
              <slot></slot>
              <slot name="dome"></slot>
              </template>

              <script>
          export default {
            name: "HelloWorld",
            props: ["wish",'wishes'],
            emits:['carried'],
            setup(props,context) {
              console.log(props)
              console.log(context.attrs)
              function dream(){
                context.emit('carried',666)
              }
              return{
                dream
              }
            },
          };
        </script>

  <style scoped></style>

ref 和 reactive

  • ref用来定义:基本类型数据
  • ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
  • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
  • reactive用来定义:对象或数组类型数据
  • reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源代码内部的数据。
  • reactive定义的数据:操作数据与读取数据:均不需要.value。 当然,我之前就说过,ref可以定义对象或数组的,它只是内部自动调用了reactive来转换。

3、vue3响应式原理

说到vue3的响应式原理,那我们就不得不提一句vue2的响应式了,(狗都知道的一句)通过Object.defineProperty的get,set来进行数据劫持,修改,从而响应式,但是它有什么缺点呢😶

  • 由于只有get()、set() 方式,所以只能捕获到属性读取和修改操作,当 新增、删除属性时,捕获不到,导致界面也不会更新。
  • 直接通过下标修改数组,界面也不会自动更新。 ok,vue2就聊这么多,什么?你还想听vue2底层?那你就Alt+←,拜拜了您嘞。

对于vue3中的响应式,我们用到的Proxy,当然,我们在vue2里面知道,Proxy是什么,是代理,当然,并不是只用到了它,还有个Window上的内置对象Reflect(反射)

  • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
  • 通过Reflect(反射): 对源对象的属性进行操作。
const p=new Proxy(data, {
  // 读取属性时调用
  get (target, propName) {
    return Reflect.get(target, propName)
  },
  //修改属性或添加属性时调用
  set (target, propName, value) {
    return Reflect.set(target, propName, value)
  },
  //删除属性时调用
  deleteProperty (target, propName) {
    return Reflect.deleteProperty(target, propName)
  }
})

4、 computed

在vue3中,把computed变成为组合式API,那么就意味着你要去引入它,代码如下:

<template>
  <div class="home">
    姓:<input type="text" v-model="names.familyName"><br>
      名:<input type="text" v-model="names.lastName"><br>
        姓名:{{fullName}}<br>
        </div>
</template>

<script>
  import {reactive,computed} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let names=reactive({
        familyName:'阿',
        lastName:'斌'
      })
      fullName=computed(()=>{
        return names.familyName+'.'+names.lastName
      })
      return {
        names,
        fullName
      }
    }
  }
</script>

要是你去修改计算出来的东西,你知道会发生什么吗?警告的意思是计算出来的东西是一个只读属性。

那要是我们想要修改怎么办呢,那么就要用到computed的终结写法了

<template>
  <div class="home">
    姓:<input type="text" v-model="names.familyName"><br>
      名:<input type="text" v-model="names.lastName"><br>
        姓名:<input type="text" v-model="names.fullName"><br>
        </div>
</template>

<script>
  import {reactive,computed} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let names=reactive({
        familyName:'阿',
        lastName:'斌'
      })
      names.fullName=computed({
        get(){
          return names.familyName+'.'+names.lastName
        },
        set(value){
          let  nameList=value.split('.')
          names.familyName=nameList[0]
          names.lastName=nameList[1]
        }
      })
      return {
        names
      }
    }
  }
</script>

5、watch

<template>
  <div class="home">
    <h1>当前数字为:{{num}}</h1>
    <button @click="num++">点击数字加一</button>
  </div>
</template>

<script>
  import {ref,watch} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let num=ref('0')
      watch(num,(newValue,oldValue)=>{
        console.log(`当前数字增加了,${newValue},${oldValue}`)
      })
      return {
        num
      }
    }
  }
</script>

当然这是监听ref定义出来的单个响应式数据,要是监听多个数据应该怎么办呢?其实可以用多个watch去进行监听,当然这不是最好的方法,最好的办法其实是监视数组

watch([num,msg],(newValue,oldValue)=>{
  console.log('当前改变了',newValue,oldValue)
})

既然我们监听的是数组,那么我们得到的newValue和oldValue也就是数组,那么数组中的第一个就是你监视的第一个参数。
ps.当然之前在vue2中watch不是有什么其他参数吗,vue3中也有,是写在最后的。

watch([num,msg],(newValue,oldValue)=>{
  console.log('当前改变了',newValue,oldValue)
},{immediate:true,deep:true})

之前我说过,我们现在监听的是监听ref定义出来数据,那么要是我们监听的是reactive

<template>
  <div class="home">
    <h1>当前姓名:{{names.familyName}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <button @click="names.familyName+='!'">点击加!</button>
    <button @click="names.age++">点击加一</button>
    <button @click="names.job.salary++">点击薪水加一</button>
  </div>
</template>

<script>
  import {reactive,watch} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let names=reactive({
        familyName: '鳌',
        age:23,
        job:{
          salary:10
        }
      })
      watch(names,(newValue,oldValue)=>{
        console.log(`names改变了`,newValue,oldValue)
      },{deep:false})
      return {
        names
      }
    }
  }
</script>

但是你会发现一个问题,为什么newValue与oldValue一样呢,就很尴尬,都是新的数据,就算你使用ref来定义,还是没有办法监听到oldValue(他喵的,都给你说了ref定义的对象会自动调用reactive),所以在监视reactive定义的响应式数据时,oldValue无法正确获取,并且你会发现,它是**强制开启深度监视(deep:true),并且无法关闭。
然而现在我们监视的是reactive定义的响应式数据的全部属性,是只监听其中的一个属性,那怎么办呢,可能大家会

watch(names.age,(newValue,oldValue)=>{
  console.log(`names改变了`,newValue,oldValue)
})

来进行监视,但是,vue3会警告只能监听reactive定义的或者ref定义的,并且不能监听。

那么我们就必须这样写(不会还有人不知道return可以省略吧?不会吧?不会吧?不会那个人就是你吧?)

// 监听单个属性
watch(()=>names.age,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})
// 监听多个属性
watch([()=>names.age,()=>names.familyName],(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})

ok,要是我们监听的是深度的属性那要怎么办呢?你会发现我要是只监听第一层是监听不到的,那么我们有两种写法

//第一种
watch(()=> names.job.salary,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})
//第二种
watch(()=> names.job,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
},{deep:true})

6、watchEffect

watchEffect是vue3的新函数,它是来和watch来抢饭碗的,它和watch是一样的功能,那它有什么优势呢?

  • 自动默认开启了immediate:true
  • 用到了谁就监视谁
watchEffect(()=>{
  const one = num.value
  const tow = person.age
  console.log('watchEffect执行了')
})

其实吧,watchEffect有点像computed,都是里面的值发生了改变就调用一次,但是呢computed要写返回值,而watchEffect不用写返回值。

7、生命周期

image.png
我们先来简单分析下,在vue2中,我们是先new Vue(),然后执行beforeCreate与created接着问你有没有vm.$mount(el),有,才继续执行,但是在vue3中,它是先全部准备好后然后再进行函数。
其实在vue3中生命周期没有多大的改变,只是改变了改变了销毁前,和销毁,让它更加语义化了 beforeDestroy改名为beforeUnmount,destroyed改名为unmounted
然后在vue3中,beforeCreate与created并没有组合式API中,setup就相当于这两个生命周期函数
在vue3中也可以按照之前的生命周期函数那样写,只是要记得有些函数名称发生了改变
在setup里面应该这样写

  • beforeCreate===>Not needed*
  • created=======>Not needed*
  • beforeMount ===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted

8、hooks 函数

  • Vue3 的 hook函数 相当于 vue2 的 mixin, 不同在与 hooks 是函数
  • Vue3 的 hook函数 可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数

其实就是代码的复用,可以用到外部的数据,生命钩子函数…,具体怎么用直接看代码,

/一般都是建一个hooks文件夹,都写在里面
import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function (){
  //鼠标点击坐标
  let point = reactive({
    x:0,
    y:0
  })

  //实现鼠标点击获取坐标的方法
  function savePoint(event){
    point.x = event.pageX
    point.y = event.pageY
    console.log(event.pageX,event.pageY)
  }

  //实现鼠标点击获取坐标的方法的生命周期钩子
  onMounted(()=>{
    window.addEventListener('click',savePoint)
  })

  onBeforeUnmount(()=>{
    window.removeEventListener('click',savePoint)
  })

  return point
}
//在其他地方调用
import useMousePosition from './hooks/useMousePosition'
let point = useMousePosition()

9、toRef 与 toRefs

toRef
toRef翻译过来其实就是把什么变成ref类型的数据,可能大家会觉得没有什么用,毕竟我们之前定义时就已经定义成ref,但是你们想一想,我们在之前是怎么写的

<template>
  <div class="home">
    <h1>当前姓名:{{names.name}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <button @click="names.name+='!'">点击加!</button>
    <button @click="names.age++">点击加一</button>
    <button @click="names.job.salary++">点击薪水加一</button>
  </div>
</template>

<script>
  import {reactive} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let names=reactive({
        name:'老谭',
        age:23,
        job:{
          salary:10
        }
      })
      return {
        names
      }
    }
  }
</script>

是不是一直都是用到代码name.xx,可能你会说,那我就return的时候不这样写,改成这样

return {
  name:names.name,
  age:names.age,
  salary:names.job.salary
}

但是你要是在页面进行操作时就不是响应式了,为什么呢?那是因为你现在暴露出去的是简简单单的字符串,字符串会有响应式吗?肯定没有呀,但是你要是用到了toRef,那就是把name.xx变为响应式,然后操作它时会自动的去修改name里面的数据

return {
  name:toRef(names,'name'),
  age:toRef(names,'age'),
  salary:toRef(names.job,'salary')
}

但是有的人可能会说那我为什么不用ref去改变?可能大家会发现在页面里也是响应式的,但是我告诉你们,根本用到的不是names里面的数据,而是你单独定义出来的数据,所以要是这样写,无论怎么修改都不会修改到names里的数据

return {
  name:ref(names.name),
  age:ref(names.age),
  salary:ref(names.job.salary),
}

toRefs
聪明一点,toRefs与toRef有什么不同,加了个s,toRef是单个转化为响应式,那toRefs就是多个转化为响应式咯,这样的话就减少代码,不然要是有成千上万个,那你不是要当憨憨闷写吗?(…是结构哈,看不懂就麻溜的alt+←),当然它只会结构一层,深层里的代码还是要老实的写

<h1>当前姓名:{{name}}</h1>
  <h1>当前薪水:{{job.salary}}K</h1>
  return {
    ...toRefs(names)
  }

10、toRaw 与 markRaw

toRaw其实就是将一个由reactive生成的响应式对象转为普通对象。如果是ref定义的话,是没有效果的(包括ref定义的对象)如果在后续操作中对数据进行了添加的话,添加的数据为响应式数据,当然要是将数据进行markRaw操作后就不会变为响应式,可能大家会说,不就是和readonly一样吗?那肯定不一样咯,readonly是根本没办法改,但markRaw是不转化为响应式,但是数据还会发生改变。

<template>
  <div class="home">
    <h1>当前姓名:{{names.name}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <h1 v-if="names.girlFriend">女朋友:{{names.girlFriend}}</h1>
    <button @click="names.name+='!'">点击加!</button>
    <button @click="addAges">点击加一</button>
    <button @click="addSalary">点击薪水加一</button>
    <button @click="add">添加女朋友</button>
    <button @click="addAge">添加女朋友年龄</button>
  </div>
</template>

<script>
  import {reactive,toRaw,markRaw} from 'vue'
  export default {
    name: 'Home',
    setup(){
      let names=reactive({
        name:'老伍',
        age:23,
        job:{
          salary:10
        }
      })
      function addAges(){
        names.age++
        console.log(names)
      }
      function addSalary(){
        let fullName=toRaw(names)
        fullName.job.salary++
        console.log(fullName)
      }
      function add(){
        let girlFriend={sex:'女',age:40}
        names.girlFriend=markRaw(girlFriend)
      }
      function addAge(){
        names.girlFriend.age++
        console.log(names.girlFriend.age)
      }
      return {
        names,
        add,
        addAge,
        addAges,
        addSalary
      }
    }
  }
</script>

11、customRef

customRef创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
单纯觉得这个东西的作用只有防抖的作用

<template>
  <input type="text" v-model="keyWord">
    <h3>{{keyWord}}</h3>
  </template>

<script>
  import {customRef} from 'vue'
  export default {
    name: 'App',
    setup() {
      //自定义一个ref——名为:myRef
      function myRef(value,times){
        let time
        return customRef((track,trigger)=>{
          return {
            get(){
              console.log(`有人从myRef中读取数据了,我把${value}给他了`)
              track() //通知Vue追踪value的变化(必须要有,并且必须要在return之前)
              return value
            },
            set(newValue){
              console.log(`有人把myRef中数据改为了:${newValue}`)
              clearTimeout(time)
              time = setTimeout(()=>{
                value = newValue
                trigger() //通知Vue去重新解析模板(必须要有)
              },times)
            },
          }
        })
      }
      let keyWord = myRef('HelloWorld',1000) //使用自定义的ref

      return {keyWord}
    }
  }
</script>

防抖:在第一次触发事件时,不立即执行函数,而是给出一个时间段,如果短时间内大量触发同一事件,只会执行一次函数。
节流:函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活,如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再生效,直至过了这段时间才重新生效。(可以理解为游戏技能冷却期)

12、provide 与 inject

都知道组件传值吧,在vue2中,如果要在后代组件中使用父组件的数据,那么要一层一层的父子组件传值或者用到vuex,但是现在,无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

//父
import { provide } from 'vue'
setup(){
  let fullname = reactive({name:'阿月',salary:'15k'})
  provide('fullname',fullname) //给自己的后代组件传递数据
  return {...toRefs(fullname)}
}
//后代
import {inject} from 'vue'
setup(){
  let fullname = inject('fullname')
  return {fullname}
}

13、响应式判断

  • isRef: 检查值是否为一个 ref 对象。
  • isReactive:检查对象是否是由 reactive 创建的响应式代理。
  • isReadonly: 检查对象是否是由 readonly 创建的只读代理。
  • isProxy:检查对象是否是由 reactivereadonly 创建的 proxy
import {ref, reactive,readonly,isRef,isReactive,isReadonly,isProxy } from 'vue'
export default {
  name:'App',
  setup(){
    let fullName = reactive({name:'小唐',price:'20k'})
    let num = ref(0)
    let fullNames = readonly(fullName)
    console.log(isRef(num))
    console.log(isReactive(fullName))
    console.log(isReadonly(fullNames))
    console.log(isProxy(fullName))
    console.log(isProxy(fullNames))
    console.log(isProxy(num))
    return {}
  }
}

14、Fragment

对我而言这个更像是一种概念,它的意思就相当于创建页面时,给了一个虚拟根标签VNode,因为我们知道在vue2里面,我们是有根标签这个概念的,但是到来vue3,它是自动给你创建个虚拟根标签VNode(Fragment),所以可以不要根标签。好处就是 减少标签层级, 减小内存占用

15、Teleport

teleport 提供了一种有趣的方法,允许我们控制在 DOM 中哪个父节点下渲染了 HTML,而不必求助于全局状态或将其拆分为两个组件。
其实就是可以不考虑你写在什么位置,你可以定义teleport在任意标签里进行定位等(常见操作为模态框),除了body外,还可以写css选择器(id,class)

//id定位
    <teleport to="#app">
      <div class="four">
        <div class="five"></div>
      </div>
    </teleport>
      //class定位
      <teleport to=".one">
        <div class="four">
        <div class="five"></div>
        </div>
        </teleport>
        //示例
        <template>
        <div class="one">
        <h1>第一层</h1>
        <div class="two">
        <h1>第二层</h1>
        <div class="three">
        <h1>第三层</h1>
        <teleport to="body">
        <div class="four">
        <div class="five"></div>
        </div>
        </teleport>
        </div>
        </div>
        </div>
        </template>

        <script>
      export default {
        name:'App',
        setup(){
          return {}
        }
      }
    </script>

  <style lang="less">
    .one{
      width: 100%;
      background-color: blue;
      .two{
        margin: 20px;
        background-color: aqua;
        .three{
          margin: 20px;
          background-color: aliceblue;
        }
      }
    }
    .four{
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: rgba(0, 0, 0, 0.5);
      .five{
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        width: 300px;
        height: 300px;
        left: 50%;
        background-color:#f60;
      }
    }
  </style>

16、全局API的转移

2.x 全局 API(Vue)3.x 实例 API (app)
Vue.config.xxxxapp.config.xxxx
Vue.config.productionTip移除
Vue.componentapp.component
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use
Vue.prototypeapp.config.globalProperties

其他改变:
移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes
移除v-on.native修饰符
移除过滤器(filter)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

react18【系列实用教程】useMemo —— 缓存数据 (2024最新版)

为什么添加了 memo &#xff0c;子组件2依然重新渲染了呢&#xff1f; 因为父组件向子组件2传递了引用类型的数据 const userInfo {name: "朝阳",};<Child2 userInfo{userInfo} />memo() 函数的本质是通过校验Props中数据的内存地址是否改变来决定组件是否重新…

实战10:基于机器学习参数优化的疾病预测实战-完整代码数据-计算机毕设

直接看演示视频: 基于机器学习参数优化的疾病预测实战-完整代码数据-计算机毕设 直接看实验结果: 数据: 没加参数优化之前的模型效果: 优化之后的效果: 数据分析:

5月17日世界电信日:共筑数字桥梁,深圳市企讯通科技引领通讯创新潮流

在全球信息化浪潮中&#xff0c;每年的5月17日被赋予了非凡的意义——“世界电信日”。这不仅仅是全球电信业发展成果展示与未来趋势探讨的盛会&#xff0c;更是对未来通信领域无限可能的展望。自1969年设立以来&#xff0c;世界电信日不断激励着各国在信息通信技术&#xff08…

618好物推荐大赏:2024年必囤好物一网打尽,购物攻略助你抢购无忧!

在618购物狂欢节来临之际&#xff0c;我为大家精心挑选了一系列好物&#xff0c;它们不仅品质卓越&#xff0c;更能在日常生活中为我们带来无限便利与乐趣。这里的每一款产品都经过我严格筛选&#xff0c;只为给你最优质的购物体验。让我们一起在这个618&#xff0c;发现生活中…

【编程题-错题集】kotori和气球(组合数学)

牛客对应题目链接&#xff1a;kotori和气球 (nowcoder.com) 一、分析题目 简单的排列组合问题&#xff0c;结果等于 n 与 m-1 个 n - 1 的乘积。 二、代码 //值得学习的代码 #include <iostream>using namespace std;const int MOD 109;int main() {int n, m;cin >…

Redis基于Redisson的限流和限流算法

限流 限流是在高并发或者某个瞬间高并发时&#xff0c;为了保证系统的稳定性&#xff0c;对超出服务处理能力之外的请求进行拦截&#xff0c;对访问服务的流量进行限制。 常见的限流算法有四种&#xff1a;固定窗口限流算法、滑动窗口限流算法、漏桶限流算法和令牌桶限流算法…

为何要使用静态或动态住宅IP代理来运营亚马逊?

跨境电商作为当前主流的行业&#xff0c;在运营亚马逊等跨境电商平台时&#xff0c;使用静态或动态住宅IP代理成为了一个重要的策略。这种策略不仅有助于提升运营效率&#xff0c;还能在一定程度上保护卖家的隐私和账号安全。 静态住宅IP代理在亚马逊运营中的优势。 静态住宅I…

亚马逊Prime Day旺季备货遭遇美国海关查验高峰,应对策略全攻略!

随着全球化贸易的日益繁荣&#xff0c;跨境电商企业在旺季备货时面临着巨大的挑战&#xff0c;尤其是当遇到美国海关查验潮时&#xff0c;如何应对成为众多商家关注的焦点。本文将从分析美国海关查验的原因入手&#xff0c;为商家提供一系列应对策略和建议。 一、美国海关查验潮…

FENDI CLUB啤酒,为何女生喜欢?

精酿啤酒已经成了女生喜欢的饮品&#xff0c;在日剧《无法成为野兽的我们》里&#xff0c;主人公小晶永远保持标准笑容&#xff0c;完美完成所有的工作。只有一个人的时候&#xff0c;她才会放下习惯性的微笑&#xff0c;显露自己的疲惫。小晶缓解疲惫&#xff0c;就是下班后去…

利用if-else,while-do,case-end的存储过程

生成一个student表&#xff0c;要求有id&#xff0c;createDate&#xff0c;userName&#xff0c;phone&#xff0c;age&#xff0c;sex&#xff0c;introduce。只需要返回DDL CREATE TABLE student (id INT PRIMARY KEY AUTO_INCREMENT, -- 假设ID为主键且自动增长createDat…

USB2.0协议解读

一、说明 本文以Universal Serial Bus Specification Revision 2.0 April 27, 2000内容为准。 USB2.0支持三种速率&#xff0c;High speed&#xff08;480Mb/s500ppm&#xff09;、Full speed&#xff08;12Mb/s2500ppm&#xff09;以及Low speed&#xff08;1.5Mb/s1.5%&…

通过gen_compile_commands.py产生compile_commands.json文件的方法

大家在使用vscode查看linux源代码时&#xff0c;会有很多飘红处&#xff0c;而且函数的跳转非常不方便。所以linux给了一个脚本gen_compile_commands.py&#xff0c;此脚本类似ctags这样&#xff0c;产生相应的关联之类的数据库&#xff0c;方便函数及文件的跳转等等。非常好。…

GPT-4o 引领人机交互新风向的向量数据库Milvus Cloud 成本

成本 AIGC 时代对于冷热储存的呼唤 成本一直是向量数据库获得更广泛使用的最大阻碍之一,这个成本来自两点: 储存,绝大多数向量数据库为了保证低延迟,需要把数据全量缓存到内存或者本地磁盘。在这个动辄百亿量级的AI 时代,意味着几十上百 TB 的资源消耗。 计算,数据需…

每日一练 2024.5.16 (补2024.5.13)

题目&#xff1a; 给你一个字符串数组 words 和一个字符串 s &#xff0c;请你判断 s 是不是 words 的 首字母缩略词 。 如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s &#xff0c;则认为 s 是 words 的首字母缩略词。例如&#xff0c;"ab" 可以…

笔记-Windows NFS → 中文乱码导致文件找不到

前提准备 项目中有这么一块业务 1、 脚本同步 这一环&#xff0c;是运维同事通过脚本实现的&#xff0c;所以我没去关注 2、 读取文件并上传 这一环&#xff0c;是我实现的&#xff0c;稳定运行了很长一段时间了&#xff0c;一直没出问题 中文乱码** 直到有一天&#xff0…

算法工程师面试问题 | YOLOv8面试考点原理全解析(一)

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv8面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习目标检测面试问题&#xff0c;并提供参考的回答…

Flink 高可用之StandAlone-HA模式(一)

Flink 高可用之StandAlone-HA模式 压缩包: tar -xvzf flink-1.9.1-bin-scala_2.11.tgz -C /opt && cd /opt/flink-1.9.1 集群规划: 1.集群规划 - 服务器: node1(Master Slave): JobManager TaskManager- 服务器: node2(Master Slave): JobManager TaskManager- …

国内常用的项目管理软件有哪些?六大企业级项目管理软件大盘点

一、 奥博思 PowerProject 项目管理软件 官方网址&#xff1a;http://www.powerproject.com.cn 北京奥博思软件技术有限公司自成立以来&#xff0c;一直专注于企业级项目管理软件的开发及解决方案&#xff0c;致力于为各类企业&#xff08;制造业、IT交付、金融、汽车及汽车零…

Pikachu 靶场敏感信息泄露通关解析

前言 Pikachu靶场是一种常见的网络安全训练平台&#xff0c;用于模拟真实世界中的网络攻击和防御场景。它提供了一系列的实验室环境&#xff0c;供安全专业人士、学生和爱好者练习和测试他们的技能。 Pikachu靶场的目的是帮助用户了解和掌握网络攻击的原理和技术&#xff0c;…

php解密工具

在线编辑器 复制如下代码到空白地区: <?php namespace FatSmallTools; class NavicatPassword {protected $version 0;protected $aesKey libcckeylibcckey;protected $aesIv libcciv libcciv ;protected $blowString 3DC5CA39;protected $blowKey null;protected $b…