【送书】前端系列16集-vue3范型,vue-i18n-next,watch,watchEffect

news2025/1/11 14:04:03

送书活动:挑选1名粉丝同学哦 免费包邮送。
截止时间:2023/5/26号  19 : 00
参与底部评论区说
说:请在评论中分享你的阅读收获。

中台落地手记——业务服务化与数据资产化

34478b7e117489900fa9221ca847b722.jpeg

vue-i18n-next

vue3 中使用 i18n 需要安装的是 [vue-i18n v9] 的版本

npm install vue-i18n@9

创建 src\lang\index.ts,使用 createI18n 创建 i18n 实例:

// src\lang\index.ts
    import { createI18n } from 'vue-i18n'
    import { LANG_VALUE } from '@/common/enum'
    import ch from './ch'
    import en from './en'

    const i18n = createI18n({
      legacy: false,
      locale: getLanguage(),
      messages: {
        [LANG_VALUE.ch]: ch,
        [LANG_VALUE.En]: en
      }
    })
    export default i18n

如果使用的是 Composition API 则需要定义为 false

  • locale:当前要展示的语言。值为之前用户的语言选择,从浏览器缓存中读取。如果缓存中没有数据,则通过 navigator.language 获取浏览器使用的语言:

// src\lang\index.ts
import { localCache } from '@/utils'
export function getLanguage() {
  const chooseLanguage = localCache.getItem(LANGUAGE)
  if (chooseLanguage) return chooseLanguage

  // 如果没有选择语言
  const language = navigator.language.toLowerCase()
  const locales = [LANG_VALUE.En, LANG_VALUE.Zh]
  for (const locale of locales) {
    if (language.indexOf(locale) > -1) {
      return locale
    }
  }
  return LANG_VALUE.Zh
}
// src\common\enum.ts
export enum LANG_VALUE {
  En = 'en',
  Zh = 'zh-Hans'
}
  • messages:不同语言对应的翻译文件:

// src\lang\zh-Hans.ts
export default {
  baoguochuku: '包裹出库',
  sousuo: '搜索'
}
// src\lang\en.ts
export default {
  baoguochuku: 'Outbound',
  sousuo: 'Search'
}
// src\main.ts,省略其它代码
import i18n from './lang/index'
app.use(i18n)

从 vue-i18n 中导入 useI18n,然后进行调用生成 i18n 实例,再从里面解构得到 t 方法

  • 在 <template> 中使用

<template>
  <n-button>
    <slot name="submitBtnText">{{ $t('xxx') }}</slot>
  </n-button>
</template>

直接使用 $t 是因为有个叫做 globalInjection 的配置项默认为 true,帮我们全局注入了 $t 方法,如果设置为 false

// src\lang\index.ts
const i18n = createI18n({
  globalInjection: false
})

在 ts 文件中,在 src\lang\index.ts 配置生成的 i18n 实例

// src\service\request\index.ts
import i18n from '@/lang'
if (!axios.isCancel(error)) {
  dialog.error({
    title: i18n.global.t('biaoti'),
    // ...
  })
}
import { watch, ref } from 'vue'
 setup() {
      let mes = ref('会好的')
      //第一种情况 监听ref定义的一个响应式数据
      watch(mes, (qian, hou) => {
        console.log('变化----', qian, hou)
      }, {immediate: true})
 }

 setup() {
      let mes = ref('会好的')
      let mess = ref('我是谁')
      //第二种情况 监听ref定义的多个响应式数据
      watch([mes,mess], (qian, hou) => {
        console.log('变化----', qian, hou)
      },{immediate:true})
 }

setup() {
       let rea=reactive({
        name:'我是谁',
        obj:{
          salary:20
        }
      })
      //第三种情况 监听reactive定义的属性
       watch(rea,(qian,hou)=>{
        console.log('rea变化了',qian,hou)
      })
 }

停止监听

const stop = watchEffect(() => {
  /* ... */
})

// later
stop()
const data = ref(null)
watchEffect(async onInvalidate => {
  onInvalidate(() => {
    /* ... */
  }) // 我们在Promise解析之前注册清除函数
  data.value = await fetchData(props.id)
})
  1. watch可以访问新值和旧值,watchEffect不能访问。

  2. watchEffect有副作用,DOM挂载或者更新之前就会触发,需要我们自己去清除副作用。

  3. watch是惰性执行,也就是只有监听的值发生变化的时候才会执行,但是watchEffect不同,每次代码加载watchEffect都会执行。

  4. watch需要指明监听的对象,也需要指明监听的回调。watchEffect不用指明监视哪一个属性,监视的回调函数中用到哪个属性,就监视哪个属性。

  • 推荐使用vscode,并且安装volar插件辅助开发

<template>
    <div>{{ numberRef }}</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const numberRef = ref(0) // ===> Ref<number>
const stringRef = ref("") // ===> Ref<string>
interface IFoo {
    bar: string
}
const fooRef = ref<IFoo>() // ===> Ref<IFoo | undefined>
</script>
<template>
    <div>{{ book1.bar }}</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
interface IFoo {
    bar: string
}
// 第一种
const book1 = reactive<IFoo>({ bar: 'bar' })
// 第二种
const book2: IFoo = reactive({ bar: 'bar' })
// 第三种
const book3 = reactive({ bar: 'bar' }) as IFoo
</script>
<template>
    <div>{{ fooComputed?.bar }}</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
const numberRef = ref(0) // ===> Ref<number>
const numberComputed = computed(() => numberRef.value) // ===> ComputedRef<number>
interface IFoo {
    bar: string
}
const fooRef = ref<IFoo>() // ===> Ref<IFoo | undefined>
const fooComputed = computed(() => {
    return fooRef.value
}) // ===> ComputedRef<IFoo | undefined>
</script>
<template>
    <div>{{ fooComputedWritable?.bar }}</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
interface IFoo {
    bar: string
}
const fooRef = ref<IFoo>() // ===> Ref<IFoo | undefined>
const fooComputedWritable = computed({
    get: () => {
        return fooRef.value
    },
    set: (value) => {
        fooRef.value = value
    }
}) // ===> WritableComputedRef<IFoo | undefined>
</script>
<template>
    <div>{{ numberRef }}</div>
</template>
<script setup lang="ts">
import { ref, watch, watchEffect } from 'vue';
const numberRef = ref(0) // ===> Ref<number>
interface IFoo {
    bar: string
}
const fooRef = ref<IFoo>() // ===> Ref<IFoo | undefined>

watchEffect(() => console.log(fooRef.value?.bar))
watch(numberRef, () => {
    console.log(`numberRef变化了`)
})
const stop = watch(fooRef, () => {
    console.log(`fooRef变化了`)
}, {
    deep: true
}) // 检查深度嵌套的对象或数组
stop(); // 停止侦听
</script>
<template>
    <div></div>
</template>
<script setup lang="ts">
import { nextTick } from 'vue';

nextTick(() => {
    // ...
})

// 还可以使用 async/await
async () => {
    await nextTick()
    // ....
}
</script>
<template>
    <Foo></Foo>
    <foo-item></foo-item>
    <component :is="Foo" />
    <component :is="someCondition ? Foo : FooItem" />
</template>
<script setup lang="ts">
import Foo from "./Foo.vue"
import FooItem from "./FooItem.vue"
const someCondition = false
</script>
<template>
    <div>
        <!-- 直接使用即可,不需要toRefs转换 -->
        {{ foo }}
    </div>
</template>
<script setup lang="ts">
import { toRefs } from 'vue';
interface ICustomType {
    foo: string,
    bar: string
}
const props = defineProps({
    foo: String, // 使用构造函数声明类型
    fooMultiTypes: [String, Number], // 多个类型
    fooCustomType: Object as () => ICustomType, // 自定义类型
    fooCustomTypeWithRequire: {
        type: Object as () => ICustomType,
        required: true
    }, // 自定义类型,必选
    fooCustomTypeWithDefault: {
        type: Object as () => ICustomType,
        default: () => {
            return {
                foo: "foo",
                bar: "bar"
            }
        }
    }, // 自定义类型,带默认值
})

// 1. 可以在模板<template>中使用声明的props,不需要用toRefs转换
// 2. 如果某一个值需要在setup中使用,则需要用toRefs转换下,然后把它解构出来
const {
    foo,  // ===> Ref<string | undefined> | undefined
    fooMultiTypes, // ===> Ref<string | number | undefined> | undefined
    fooCustomType, // ===> Ref<ICustomType | undefined> | undefined
    fooCustomTypeWithRequire, // ===> Ref<ICustomType>
} = toRefs(props)
</script>
<template>
    <div>
        <!-- 直接使用即可,不需要toRefs转换 -->
        {{ foo }}
    </div>
</template>
<script setup lang="ts">
import { toRefs } from 'vue';
interface ICustomType {
    foo: string,
    bar: string
}
const props = defineProps<{
    foo?: string,
    fooWithRequire: string,
    fooMultiTypes: string | number,
    fooCustomType?: ICustomType,
    fooCustomTypeWithRequire: ICustomType
}>()

// 泛型方式声明默认值,需要使用withDefaults 编译器宏
const propsWithDefault = withDefaults(
    defineProps<{
        fooCustomTypeWithDefault: ICustomType
    }>(),
    {
        fooCustomTypeWithDefault: () => {
            return {
                foo: "foo",
                bar: "bar"
            }
        }
    })

// 1. 可以在模板<template>中使用声明的props,不需要用toRefs转换
// 2. 如果某一个值需要在setup中使用,则需要用toRefs转换下,然后把它解构出来
const {
    foo,  // ===> Ref<string | undefined> | undefined
    fooWithRequire,  // ===> Ref<string>
    fooMultiTypes, // ===> Ref<string | number>
    fooCustomType, // ===> Ref<ICustomType | undefined> | undefined
    fooCustomTypeWithRequire, // ===> Ref<ICustomType>
} = toRefs(props)

const {
    fooCustomTypeWithDefault,  // ===> Ref<ICustomType>
} = toRefs(propsWithDefault)
</script>
// FooBar.vue
<template>
    <div>
        <!-- 一个单文件组件可以通过它的文件名被其自己所引用 -->
        <FooBar></FooBar>
        <foo-bar></foo-bar>

        <foo-bar-other></foo-bar-other>
    </div>
</template>
<script setup lang="ts">
// 使用 import 别名导入避免冲突
import { default as FooBarOther } from './others/FooBar.vue'
</script>
<template>
    <div></div>
</template>
<script setup lang="ts">
import {
    onBeforeMount,
    onMounted,
    onBeforeUpdate,
    onUpdated,
    onBeforeUnmount,
    onUnmounted,
    onErrorCaptured,
    onRenderTracked,
    onRenderTriggered,
    onActivated,
    onDeactivated
} from "vue"

// 直接使用就好了
onMounted(() => {
    // ...
})
</script>
<template>
    <div></div>
</template>
<script setup lang="ts">
import { provide } from 'vue';
export interface IUser {
    name: string,
    age: number
}
provide("name", "foo")
provide<IUser>("user", {
    name: "foo",
    age: 23
})
</script>
<template>
    <div></div>
</template>
<script setup lang="ts">
import { inject } from 'vue';
import { IUser } from './Foo.vue';

const name = inject<string>("name") // ===> string | undefined
const user = inject<IUser>("user") // ===> IUser | undefined
</script>
import { createApp } from 'vue';
import App from './App.vue'

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

利用了 import 和 export 的导入导出语法,实现了按需打包模块的功能,项目打包后的文件体积明显小了很多

<template>
  <div id="app">
      <p>{{ number }}</p>
      <button @click="add">增加</button>
  </div>
</template>

<script>
// 1. 从 vue 中引入 ref 函数
import {ref} from 'vue'
export default {
  name: 'App',
  setup() {
      // 2. 用 ref 函数包装一个响应式变量 number
      let number = ref(0)

      // 3. 设定一个方法
      function add() {
          // number是被ref函数包装过了的,其值保存在.value中
          number.value ++
      }

      // 4. 将 number 和 add 返回出去,供template中使用
      return {number, add}
  }
  
}
</script>

setup 函数还有两个参数,分别是 props 、context,前者存储着定义当前组件允许外界传递过来的参数名称以及对应的值;后者是一个上下文对象,能从中访问到 attr 、emit 、slots

<template>
  <div id="app"></div>
</template>

<script>
// 1. 从 vue 中引入 多个生命周期函数
import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, unMounted} from 'vue'
export default {
  name: 'App',
  setup() {
      onBeforeMount(() => {
          // 在挂载前执行某些代码
      })

      onMounted(() => {
          // 在挂载后执行某些代码
      })

      onBeforeUpdate(() => {
          // 在更新前前执行某些代码
      })

      onUpdated(() => {
          // 在更新后执行某些代码
      })

      onBeforeUnmount(() => {
          // 在组件销毁前执行某些代码
      })

      unMounted(() => {
          // 在组件销毁后执行某些代码
      })

      return {}
  }
  
}
</script>

reactive 方法是用来创建一个响应式的数据对象,该API也很好地解决了Vue2通过 defineProperty 实现数据响应式的缺陷

<template>
  <div id="app">
   <!-- 4. 访问响应式数据对象中的 count  -->
   {{ state.count }}
  </div>
</template>

<script>
// 1. 从 vue 中导入 reactive 
import {reactive} from 'vue'
export default {
  name: 'App',
  setup() {
      // 2. 创建响应式的数据对象
      const state = reactive({count: 3})

      // 3. 将响应式数据对象state return 出去,供template使用
      return {state}
  }
}
</script>

.value 是在 setup 函数中访问 ref 包装后的对象时才需要加的,在 template 模板中访问时是不需要的,因为在编译时,会自动识别其是否为 ref 包装过的

<script>
// 1. 导入 toRef
import {toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = toRef(obj, 'count')

        // 3. 将toRef包装过的数据对象返回供template使用
        return {state}
    }
}
</script>
<script>
// 1. 导入 ref
import {ref} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = ref(obj.count)

        // 3. 将ref包装过的数据对象返回供template使用
        return {state}
    }
}
</script>
<template>
    <p>{{ state1 }}</p>
    <button @click="add1">增加</button>

 <p>{{ state2 }}</p>
    <button @click="add2">增加</button>
</template>

<script>
import {ref, toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 3}
        const state1 = ref(obj.count)
        const state2 = toRef(obj, 'count')

        function add1() {
            state1.value ++
            console.log('原始值:', obj);
            console.log('响应式数据对象:', state1);
        }

        function add2() {
            state2.value ++
            console.log('原始值:', obj);
            console.log('响应式数据对象:', state2);
        }

        return {state1, state2, add1, add2}
    }
}
</script>

ref 是对原数据的一个拷贝,不会影响到原始值,同时响应式数据对象值改变后会同步更新视图

视图未发生改变,原始值改变了,响应式数据对象的值也改变了,这说明 toRef 是对原数据的一个引用,会影响到原始值,但是响应式数据对象值改变后不会更新视图

  1. ref 是对传入数据的拷贝;toRef 是对传入数据的引用

  2. ref 的值改变会更新视图;toRef 的值改变不会更新视图

toRefs ,其作用就是将传入的对象里所有的属性的值都转化为响应式数据对象,该函数支持一个参数,即 obj 对象

将 obj 作为参数传递给 reactive 生成响应式数据对象时,若 obj 的层级不止一层,那么会将每一层都用 Proxy 包装一次

shallowReactive

一个浅层的 reactive

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改变1</button>
 <button @click="change2">改变2</button>
</template>
<script>
import {shallowReactive} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowReactive(obj)

        function change1() {
            state.a = 7
        }

        function change2() {
            state.first.b = 8
            state.first.second.c = 9
            console.log(state);
        }

        return {state}
    }
}
</script>

改变了第二层的 b 和第三层的 c,虽然值发生了改变,但是视图却没有进行更新;改变了第一层的 a 时,整个视图进行了更新;shallowReactive 监听了第一层属性的值,一旦发生改变,则更新视图

shallowRef

一个浅层的 ref,与 shallowReactive 一样是拿来做性能优化的

shallowReactive 是监听对象第一层的数据变化用于驱动视图更新,那么 shallowRef 则是监听 .value 的值的变化来更新视图的

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改变1</button>
 <button @click="change2">改变2</button>
</template>

<script>
import {shallowRef} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowRef(obj)
        console.log(state);

        function change1() {
            // 直接将state.value重新赋值
            state.value = {
                a: 7,
                first: {
                    b: 8,
                    second: {
                        c: 9
                    }
                }
            }
        }

        function change2() {
            state.value.first.b = 8
            state.value.first.second.c = 9
            console.log(state);
        }

        return {state, change1, change2}
    }
}
</script>

triggerRef ,调用它就可以立马更新视图,其接收一个参数 state ,即需要更新的 ref 对象

<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change">改变</button>
</template>

<script>
import {shallowRef, triggerRef} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowRef(obj)
        console.log(state);

        function change() {
            state.value.first.b = 8
            state.value.first.second.c = 9
            // 修改值后立即驱动视图更新
            triggerRef(state)
            console.log(state);
        }

        return {state, change}
    }
}
</script>

toRaw 方法是用于获取 ref 或 reactive 对象的原始数据的

<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改变</button>
</template>

<script>
import {reactive} from 'vue'
export default {
    setup() {
        const obj = {
            name: 'xxx',
            age: 22
        }

        const state = reactive(obj) 

        function change() {
            state.age = 90
            console.log(obj); // 打印原始数据obj
            console.log(state);  // 打印 reactive对象
        }

        return {state, change}
    }
}
</script>

toRaw 方法从 reactive 对象中获取到的是原始数据

可以很方便的通过修改原始数据的值而不更新视图来做一些性能优化了

<script>
import {reactive, toRaw} from 'vue'
export default {
    setup() {
        const obj = {
            name: 'xxx',
            age: 22
        }

        const state = reactive(obj) 
        const raw = toRaw(state)

        console.log(obj === raw)   // true
    }
}
</script>

markRaw 方法可以将原始数据标记为非响应式的,即使用 ref 或 reactive 将其包装,仍无法实现数据响应式,其接收一个参数,即原始数据,并返回被标记后的数据

<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改变</button>
</template>

<script>
import {reactive, markRaw} from 'vue'
export default {
    setup() {
        const obj = {
            name: 'xxx',
            age: 22
        }
        // 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
        const raw = markRaw(obj)   
        // 试图用reactive包装raw, 使其变成响应式数据
        const state = reactive(raw) 

        function change() {
            state.age = 90
            console.log(state);
        }

        return {state, change}
    }
}
</script>

被 markRaw 方法处理过后的数据是否还能被 reactive 包装成响应式数据

watch 和 watchEffect 都是用来监视某项数据变化从而执行指定的操作的

<script>
import {ref, watch} from 'vue'
export default {
    setup() { 
        const state = ref(0)

        watch(state, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`)
            console.log(`新值为${newValue}`)
            /* 1秒后打印结果:
                            原值为0
                            新值为1
            */
        })

        // 1秒后将state值+1
        setTimeout(() => {
            state.value ++
        }, 1000)
    }
}
</script>
<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({count: 0})

        watch(() => state.count, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`)
            console.log(`新值为${newValue}`)
            /* 1秒后打印结果:
                            原值为0
                            新值为1
            */
        })

        // 1秒后将state.count的值+1
        setTimeout(() => {
            state.count ++
        }, 1000)
    }
}
</script>
<script>
import {reactive, watch} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'xx' })

        watch(
            [() => state.count, () => state.name], 
            ([newCount, newName], [oldvCount, oldvName]) => {
                console.log(oldvCount) // 旧的 count 值
                console.log(newCount) // 新的 count 值
                console.log(oldName) // 旧的 name 值
                console.log(newvName) // 新的 name 值
            }
        )

        setTimeout(() => {
          state.count ++
          state.name = 'dd'
        }, 1000)
    }
}
</script>

watch方法会返回一个stop方法,若想要停止监听,便可直接执行该stop函数

watchEffect

  1. 不需要手动传入依赖

  2. 每次初始化时会执行一次回调函数来自动获取依赖

  3. 无法获取到原值,只能得到变化后的值

<script>
import {reactive, watchEffect} from 'vue'
export default {
    setup() { 
        const state = reactive({ count: 0, name: 'xx' })

        watchEffect(() => {
            console.log(state.count)
            console.log(state.name)
            /*  初始化时打印:
                            0
                            xx

                1秒后打印:
                            1
                            da
            */
        })

        setTimeout(() => {
          state.count ++
          state.name = 'da'
        }, 1000)
    }
}
</script>

const store = useStore()

Vue3的 getCurrentInstance().ctx

<template>
  <div>
    <div ref="el">div元素</div>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
export default {
  setup() {
      // 创建一个DOM引用,名称必须与元素的ref属性名相同
      const el = ref(null)

      // 在挂载后才能通过 el 获取到目标元素
      onMounted(() => {
        el.value.innerHTML = '内容被修改'
      })

      // 把创建的引用 return 出去
      return {el}
  }
}
</script>

加群联系作者vx:xiaoda0423

仓库地址:https://github.com/webVueBlog/WebGuideInterview

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

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

相关文章

Nat Biotechnol –精准 CRISPR-Cas噬菌体疗法将为重症感染患者带来福音

治疗血液系统恶性肿瘤的化学药物常会引起骨髓功能抑制&#xff08;bone marrow suppression&#xff09;和胃肠道黏膜炎&#xff0c;并伴有肠道通透性增加。肠道细菌&#xff08;包括大肠杆菌&#xff09;从胃肠道易位是血流感染的常见原因。肠道细菌引起血流感染导致的死亡率为…

【这个问题纠结了我好多年】3dMax到底使用Intel还是AMD的CPU更好?

随着英特尔和 AMD 的新 CPU上市&#xff0c;是时候进行新一轮的硬件测试了。通过以极具竞争力的价格提供大量内核&#xff0c;AMD 已成为 CPU 领域的有力竞争者。作为回应&#xff0c;英特尔已开始增加其 CPU 中的内核数量。虽然它们提供的内核数量仍然不如 AMD&#xff0c;但它…

基于ESP32-CAM 和 OpenCV 设计的手势控制虚拟鼠标

概述 在本文中,我们将使用ESP32-CAM和OpenCV开发手势控制虚拟鼠标。ESP32 Camera Module和Python程序可用于无线控制鼠标跟踪和点击操作。 入门者必须具备 Python、图像处理、嵌入式系统以及物联网的丰富知识。首先,我们将了解如何控制鼠标跟踪和单击,以及运行 python 程序…

《Kali渗透基础》03. 被动信息收集

kali渗透 1&#xff1a;被动信息收集1.1&#xff1a;收集内容1.2&#xff1a;信息用途 2&#xff1a;域名信息收集2.1&#xff1a;nslookup2.1.1&#xff1a;命令参数2.1.2&#xff1a;示例 - 命令行2.1.3&#xff1a;示例 - 交互式 2.2&#xff1a;dig2.2.1&#xff1a;命令参…

chatgpt赋能python:PythonSplit连续空格

Python Split 连续空格 在Python编程中&#xff0c;split()方法是用来将字符串按照指定的分隔符划分成一个列表。默认情况下&#xff0c;分隔符是空格。但是&#xff0c;在实际应用中&#xff0c;我们可能会遇到连续空格的情况&#xff0c;这时候split()方法会出现一些问题。本…

让你不再好奇怎样无损放大图片

随着科技的不断进步&#xff0c;放大图片已经成为我们生活中不可避免的需求。但是&#xff0c;放大图片往往会导致图片失真、模糊或者变形等问题&#xff0c;让人感到十分困扰。那么&#xff0c;你知道怎样无损放大图片吗&#xff1f;接下来我将分享三个无损放大图片的方法给你…

顺丰科技携手飞桨自研“智能外呼机器人”,为客户打造优质服务体验

“您好&#xff0c;请问是李立先生吗”&#xff0c;或许不少人在拨通客服电话后发现是机器人客服&#xff0c;都希望能快点转人工。但顺丰的“客服机器人”却是“与众不同”的存在。 顺丰已成为国内领先的快递物流综合服务商、全球第四大快递公司&#xff0c;依托领先的科技研发…

DailyMart02:DDD领域分解与微服务划分

大家好&#xff0c;今天咱们继续更新DDD&微服务系列&#xff01; DailyMart是一个简单的购物商城&#xff0c;主要销售书籍&#xff0c;包括实体书和电子书。本文将使用领域驱动设计&#xff08;DDD&#xff09;对DailyMart的业务进行分析与优化&#xff0c;以提高系统的内…

今天的技术干货由 ChatGPT 买单了~~

ChatGPT 技术最近有多火就不用再介绍了吧&#xff0c;连超级大佬都说了 ChatGPT 这是几百年不遇的、类似发明电的工业革命一样的机遇。 这种机遇当然不能错过&#xff0c;使用得当那就像玄幻小说里的男主角开了挂一样&#xff0c;用来做快速查询、资料搜集、辅助学习相当不错&a…

ip网络广播对讲的特点

随着科技的不断发展&#xff0c;通讯方式也在不断地变革。传统的对讲机已经无法满足现代化沟通的需求&#xff0c;特别是在大型企业、学校和安保等领域对讲机的局限性已经显现出来。而一种新型通讯方式&#xff1a;IP网络广播对讲正在逐渐受到人们的关注和使用。本篇文章将围绕…

chatgpt赋能python:Python工程师必知:掌握Pythonspdiags用于高效稀疏矩阵计算

Python工程师必知&#xff1a;掌握Python spdiags用于高效稀疏矩阵计算 在机器学习和数据分析中&#xff0c;我们常常需要处理大量的数据集来进行模型训练和预测&#xff0c;但是在实际应用中&#xff0c;很多数据集都是稀疏的。这时候&#xff0c;稀疏矩阵的计算就变得非常重…

2023年网络安全自治区职业院校技能大赛暨全国职业院校技能大赛新疆选拔赛任务书

2023年自治区职业院校技能大赛暨全国职业院校技能大赛新疆选拔赛任务书 一、竞赛时间 总计&#xff1a;360分钟 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件…

linux安装并启动nacos

前提准备 下载最新稳定版本&#xff0c;此处以nacos-server-2.1.0.tar.gz版本为例安装下载地址&#xff1a;https://github.com/alibaba/nacos/releases 二、具体步骤2.1 下载完成后解压&#xff1a;tar -zxvf nacos-server-2.1.0.tar.gz 2.2 将解压文件移动到/usr/local目录下…

生活中有趣好玩的产品设计

生活纷繁忙碌&#xff0c;设计无处不在。我们的衣食住行、吃喝玩乐都在跟设计打交道&#xff0c;创作奇才们用竭尽所能的心智引导和体验设计&#xff0c;吸引着我们的注意力。 这其中充满着做产品的思路&#xff0c;散发着智慧的光芒&#xff0c;留心观察就会发现很多有趣好玩的…

机器视觉陶瓷板外观检测设备有哪些优点?

随着制造业的不断发展&#xff0c;各种各样的产品被生产出来&#xff0c;其中陶瓷板是一种被广泛应用的材料。然而&#xff0c;由于制造过程中的各种因素&#xff0c;陶瓷板的表面可能存在各种缺陷&#xff0c;比如裂纹、气泡、凹凸不平等问题&#xff0c;这些问题会影响到产品…

惊呆!用streamlit快速搭建炫酷站点!

大家注意&#xff1a;因为微信最近又改了推送机制&#xff0c;经常有小伙伴说错过了之前被删的文章&#xff0c;比如前阵子冒着风险写的爬虫&#xff0c;再比如一些限时福利&#xff0c;错过了就是错过了。 所以建议大家加个星标&#xff0c;就能第一时间收到推送。&#x1f44…

C++ MFC 学习笔记+小型通讯录系统实现

MFC 最详细入门教程 [MFC常用函数总结]&#xff08;https://www.cnblogs.com/jiu0821/p/4606639.html&#xff09; [C & MFC]https://www.cnblogs.com/gaohongchen01/p/4176963.html [MFC入门&#xff08;一&#xff09;]https://www.cnblogs.com/yangyuqing/p/10283641…

FPGA远程更新/远程调试的一种简单方法

之前介绍过一种远程&#xff08;无线&#xff09;更新的方式&#xff0c;详见《起飞&#xff01;通过无线WIFI下载调试FPGA》&#xff0c;这种方式缺点有两个&#xff1a;一是速度较慢&#xff1b;二是我们的设备中需要增加一个无线设备&#xff0c;增加成本的同时增加了暴露的…

DOUBLETROUBLE: 1实战演练

文章目录 DOUBLETROUBLE: 1实战演练一、前期准备1、相关信息 二、信息收集1、nmap探测目标靶机端口2、扫描目标网址目录3、访问网站&#xff0c;发现secret下有个图片4、将图片下载5、查看图片所含内容6、破解密码并查看7、登陆邮箱8、创建反弹shell9、上传反弹shell10、监听11…

【Android工具】更新小米电视安装小白云盘观看阿里网盘视频资源方法

微信关注公众号 “DLGG创客DIY” 设为“星标”&#xff0c;重磅干货&#xff0c;第一时间送达。 之前分享过两篇关于安卓电视看网盘资源的方法&#xff1a; 【Android工具】安卓TV云存储观影工具测试正常&#xff0c;安卓电视看电影方案小结 【Android工具】更新安卓TV云存储观…