vue3 语法糖<script setup>
在 Vue 3 中,<script setup>是一种新的语法糖,它极大地简化了组件的编写方式。
<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。
基本概念
- 简洁的语法:
<script setup>允许在<script>标签中直接使用组合式 API(Composition API),无需显式地返回一个对象(不需要使用return语句显示的暴露数据、方法)。 - 自动注册:在
<script setup>中定义的变量、函数和导入的组件会自动在模板中可用,无需手动注册。 - 响应式声明:可以直接使用
ref、reactive等函数来创建响应式数据,无需在setup函数中进行额外的处理。
基本语法
要启用该语法,需要在 <script> 代码块上添加 setup 属性:
<script setup>console.log('hello script setup')
</script>
里面的代码会被编译成组件 setup() 函数的内容。
- 普通的
<script>只在组件被首次引入的时候执行一次 <script setup>中的代码会在每次组件实例被创建的时候执行。
定义在顶层的变量和函数会被暴露给模板
当使用 <script setup> 时,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用:
<template><div>{{ count }}</div><button @click="increment">点击count+1</button>
</template><script setup>
import { ref } from 'vue';const count = ref(10);
const increment = () => {count.value++;
};
</script>
在这个例子中,定义了一个响应式变量count和一个函数increment,它们可以直接在模板中使用。
不需要使用return显示的暴露。
import 导入的内容也会被暴露给模板
可以直接导入其他组件,并在模板中使用它们。导入的的组件会自动注册,不需要在components选项中进行显式注册。
<template><div><Child ref="cihldRef" /></div>
</template><script setup lang="ts">
import Child from './Child.vue';
</script>
在这个例子中,导入了一个名为Child的组件,并在模板中直接使用它。
<script setup> 范围里的值也能被直接作为自定义组件的标签名使用。
这里 Child 应当被理解为像是在引用一个变量。
可以在模板表达式中直接使用导入的 helper 函数,而不需要通过 methods 选项来暴露它:
<template><div>{{ capitalize('hello') }}</div>
</template>
<script setup>
import { capitalize } from './helpers'
</script>
使用动态组件
动态组件是指在运行时根据条件动态地切换不同的组件进行渲染。
在 Vue 中,可以使用<component>标签结合:is属性来实现动态组件。
由于组件是通过变量引用而不是基于字符串组件名注册的,在 <script setup> 中要使用动态组件的时候,应该使用动态的 :is 来绑定:
<template><component :is="Foo" /><component :is="someCondition ? Foo : Bar" />
</template>
<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>
可以使用响应式变量来控制动态组件的切换:
<template><component :is="currentComponent" /><button @click="toggleComponent">切换组件</button>
</template>
<script setup>
import { ref } from 'vue'
import Foo from './Foo.vue'
import Bar from './Bar.vue'const currentComponent = ref(ComponentA);
const toggleComponent = () => {currentComponent.value =currentComponent.value === Bar ? Foo : Bar;
};
</script>
可以为导入的组件添加别名:
import { Recur as RecursiveComponent } from './components'
使用递归组件
递归组件是指一个组件在其自身的模板中调用自身的组件。
在 Vue 3 中使用递归组件,在组件的模板(template)中直接调用自身,即可实现递归渲染。
例如:名为 RecursiveComponent.vue 的组件可以在其模板中用 <RecursiveComponent /> 引用它自己。
<template><div><!-- 这里是组件的当前层级内容 --><div v-for="item in data" :key="item.id">{{ item.name }}<RecursiveComponent v-if="item.children" :data="item.children" /></div></div>
</template>
在这个模板中,当 当前层级的数据存在子节点(item.children)时,就递归地调用自身(<RecursiveComponent />)来渲染子节点。
注意:name 属性的重要性
- 唯一标识:递归组件必须要有
name属性。- 因为
name属性为组件提供了一个唯一的标识。在递归调用中,Vue 需要通过这个唯一标识来正确地识别和处理组件。
- 因为
- 错误提示和调试:
- 如果没有
name属性,Vue 在运行时可能会抛出错误,难以确定是哪个组件出现了问题。
- 如果没有
在设计递归组件时,一定要确保有明确的终止条件,以避免无限递归导致栈溢出等问题。
使用命名空间组件
在大型 Vue 3 项目中,命名空间组件可以帮助更好地组织和管理组件。
可以使用<Foo.Bar>这样的带 . 的组件标签来引用嵌套在对象属性中的组件。
这里的Foo是一个包含Bar组件的对象或者模块。
例如,有一个名为MyNamespace的对象,其中包含一个名为NestedComponent的组件,可以在模板中这样引用:<MyNamespace.NestedComponent />。
// MyNamespace.js
import NestedComponent from './NestedComponent.vue';export default {NestedComponent,
};
在组件中使用:
<template><div><MyNamespace.NestedComponent /></div>
</template><script setup>
import MyNamespace from './MyNamespace';
</script>
对于具有相似功能但来自不同模块的组件,可以通过命名空间进行区分,避免名称冲突。
使用自定义指令
自定义指令是一种在 Vue 中扩展 HTML 元素行为的方式。可以通过自定义指令来实现对 DOM 元素的操作,例如添加事件监听器、修改样式等。
全局注册的自定义指令将正常工作。
本地的自定义指令在 <script setup> 中不需要显式注册,但必须遵循 vNameOfDirective 这样的命名规范:
<template><h1 v-my-directive>This is a Heading</h1>
</template>
<script setup>
const vMyDirective = {beforeMount: (el) => {// 在元素上做些操作el.style.backgroundColor = 'lightblue';}
}
</script>
在这个例子中:
- 在
<script setup>中,定义了一个名为vMyDirective的常量,它实际上是一个对象,代表自定义指令的定义。 - 对象
vMyDirective包含一个beforeMount钩子函数,该函数会在指令所绑定的元素挂载到 DOM 之前被调用。 - 在
beforeMount函数中,可以接收一个参数el,它代表被绑定指令的 DOM 元素。在这里可以对这个元素进行各种操作,比如添加事件监听器、修改样式、设置属性等。
defineProps() 和 defineEmits()
在 Vue 3 的 <script setup> 中,defineProps() 和 defineEmits() 是用于定义组件的 props 和 emits 的函数。
defineProps()用于定义组件接收的外部传入的属性(props)。它可以明确组件的输入参数。defineEmits()用于定义组件可以触发的自定义事件(emits)。它允许组件向父组件传递数据或通知父组件发生了某些事件。
示例:
<template><div>{{ message }}</div><button @click="emitEvent">触发事件</button>
</template><script setup>
// 调用 `defineProps()`,并传入一个对象来定义 `props` 的类型和默认值
const props = defineProps({message: {type: String,default: 'Hello, Vue 3!',},
});// 调用 `defineEmits()`,并传入一个数组来定义可以触发的事件名称
const emit = defineEmits(['customEvent']);const emitEvent = () => {emit('customEvent', 'Some data');
};
</script>
在这个例子中:
- 定义了一个名为
message的prop,类型为字符串,默认值为'Hello, Vue 3!'。在模板中可以直接使用message变量来显示传入的prop值。 - 定义了一个名为
customEvent的自定义事件。当按钮被点击时,调用emitEvent方法,触发customEvent事件并传递一些数据。
注意
-
defineProps和defineEmits都是只能在<script setup>中使用的编译器宏。它们不需要导入,且会随着<script setup>的处理过程一同被编译掉。- 在 Vue 3 的
<script setup>中,defineProps和defineEmits被称为编译器宏。它们是一种在编译阶段由编译器处理的特殊语法结构,用于特定的目的,在这个场景下,分别用于定义组件的props和emits。
- 在 Vue 3 的
-
defineProps接收与props选项相同的值。- 可以使用对象的形式来定义
props的类型、默认值等属性,就像在传统的组件选项中一样。 - 例如:
defineProps({ propName: String, propWithDefault: { type: Number, default: 0 } })。
- 可以使用对象的形式来定义
-
defineEmits接收与emits选项相同的值。defineEmits接收与传统的emits选项相同的值,通常是一个数组,列出组件可以触发的自定义事件名称。- 例如:
defineEmits(['eventName1', 'eventName2'])。
-
defineProps和defineEmits在选项传入后,会提供恰当的类型推导。- 例如,如果定义了一个
propName的prop为字符串类型,在使用这个prop时,编辑器可以自动识别其类型为字符串,并提供相应的类型提示。
- 例如,如果定义了一个
-
传入到
defineProps和defineEmits的选项会从setup中提升到模块的作用域。因此,传入的选项不能引用在setup作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。
<script setup>
const localVar = 'some value';
defineProps({ propName: localVar }); // 这会导致编译错误,因为 localVar 是 setup 作用域的局部变量import { importedValue } from './someModule';
defineProps({ propName: importedValue }); // 这是合法的,因为 importedValue 在模块作用域内
</script>
针对类型的 props/emit 声明
props 和 emit 也可以通过给 defineProps 和 defineEmits 传递纯类型参数的方式来声明:
const props = defineProps<{foo: stringbar?: number
}>()const emit = defineEmits<{(e: 'change', id: number): void(e: 'update', value: string): void
}>()// 3.3+:另一种更简洁的语法
const emit = defineEmits<{change: [id: number] // 具名元组语法update: [value: string]
}>()
-
defineProps或defineEmits要么使用运行时声明,要么使用类型声明。同时使用两种声明方式会导致编译报错。 -
使用类型声明的时候,静态分析会自动生成等效的运行时声明,从而在避免双重声明的前提下确保正确的运行时行为。
-
在开发模式下,编译器会试着从类型来推导对应的运行时验证。例如这里从
foo: string类型中推断出foo: String。如果类型是对导入类型的引用,这里的推导结果会是foo: null(与any类型相等),因为编译器没有外部文件的信息。 -
在生产模式下,编译器会生成数组格式的声明来减少打包体积 (这里的
props会被编译成['foo', 'bar'])。
-
-
在 3.2 及以下版本中,
defineProps()的泛型类型参数只能使用类型字面量或者本地接口的引用。 -
这个限制已经在 3.3 版本中解决。最新版本的 Vue 支持在类型参数的位置引用导入的和有限的复杂类型。
使用类型声明时的默认 props 值
在使用针对类型的 defineProps 声明时,它没有可以给 props 提供默认值的方式。
当需要为 props 提供一些初始值或者在没有外部传入值时使用特定的默认值时,使用withDefaults 编译器宏。
withDefaults 编译器宏允许在使用类型声明的同时为 props 设置默认值。
<script setup>
import { withDefaults } from 'vue';const props = withDefaults(defineProps({message: String,count: Number,
}), {message: 'Hello, Vue 3!',count: 0,
});
</script>
也可以换一种写法:
export interface Props {msg?: stringlabels?: string[]
}const props = withDefaults(defineProps<Props>(), {msg: 'hello',labels: () => ['one', 'two']
})
上面代码会被编译为等价的运行时 props 的 default 选项。此外,withDefaults 辅助函数提供了对默认值的类型检查,并确保返回的 props 的类型删除了已声明默认值的属性的可选标志。
defineModel()
这个宏可以用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。
defineModel 允许在组件中轻松创建双向绑定的变量。这意味着当父组件传递一个值给子组件,并且子组件可以修改这个值时,父组件也会自动更新这个值。
在子组件的 <script setup> 中,可以使用 defineModel 来定义一个双向绑定的变量。
<template><input v-model="modelValue" />
</template><script setup>
import { defineModel } from 'vue';const modelValue = defineModel();
</script>
modelValue 是一个双向绑定的变量,可以在输入框中使用 v-model 指令进行绑定。
在父组件中,可以将一个值传递给子组件,并使用 v-model 指令来实现双向绑定。
<template><div><Child ref="cihldRef" v-model="parentValue" /></div>
</template><script setup lang="ts" name="Person">
import { ref } from "vue";
import Child from './Child.vue';
const parentValue = ref('Initial value')
</script>
parentValue 是一个响应式变量,通过 v-model 指令传递给子组件 ChildComponent。当子组件中的输入框的值发生变化时,parentValue 也会自动更新。

使用 defineModel 可以使双向绑定的实现更加简洁和直观,无需手动处理 input 事件和 update:propName 事件。
如果为 defineModel prop 设置了一个 default 值且父组件没有为该 prop 提供任何值,会导致父组件与子组件之间不同步。
在子组件中:
<script setup lang="ts">
import { defineModel } from 'vue';
const modelValue = defineModel({default: 'value'}); // 设置一个默认值
</script>
在父组件中:
<script setup lang="ts" name="Person">
import { ref } from "vue";
import Child from './Child.vue';
const parentValue = ref() // parentValue 是undefined
</script>
初始化后,parentValue 与 modelValue 不同步:


当子组件中的输入框的值发生变化时,parentValue 也会自动更新。

解构defineModel()返回值
defineModel()函数在 Vue 3 的 <script setup>中用于处理v-model双向绑定。它返回一个包含两个元素的数组:
- 第一个元素是双向绑定的值,通常用于在组件内部进行操作和展示。
- 第二个元素是一个对象,包含了使用
v-model指令时可能设置的修饰符。
通过解构赋值的方式,可以方便地将这两个返回值分别提取到独立的变量中。
例如:const [modelValue, modelModifiers] = defineModel()。
这样,modelValue就代表了双向绑定的值,而modelModifiers则是包含修饰符的对象。
在代码中,可以通过检查modelModifiers对象的属性来确定是否存在特定的修饰符。
例如,if (modelModifiers.trim) { //... }这段代码就是在检测是否存在trim修饰符。如果存在,就可以执行相应的逻辑。
const [modelValue, modelModifiers] = defineModel()// 对应 v-model.trim
if (modelModifiers.trim) {// ...
}
当存在修饰符时,需要在读取或将其同步回父组件时对其值进行转换。可以通过使用 get 和 set 转换器选项来实现:
const [modelValue, modelModifiers] = defineModel({get() {// 在这里可以对读取的值进行转换或处理return modelValue + ' (processed on get)';},set(value) {// 对设置的值进行处理,如果有修饰符可以在这里应用// 如果使用了 .trim 修饰符,则返回裁剪过后的值if (modelModifiers.trim) {return value.trim()}if (modelModifiers.uppercase) {return value.toUpperCase();}// 否则,原样返回return value}
})
在这个例子中:
get方法在读取modelValue时被调用。get方法可以用于在读取双向绑定的值时进行特定的处理或转换。set方法用于在设置双向绑定的值时进行特定的处理或转换。set方法接收一个参数value,代表要设置的值。根据不同的修饰符情况对这个值进行处理。- 如果存在
trim修饰符,就对值进行去空格处理。 - 如果存在
uppercase修饰符,就将值转换为大写字母。 - 如果没有任何修饰符,直接返回传入的值。
在 TypeScript 环境下,defineModel可以接收一个类型参数来明确指定双向绑定的值的类型。
// 表示双向绑定的值为字符串类型。
// modelValue 被推断为 Ref<string | undefined>,响应式应用,可能包含字符串值或者为undefined。
const modelValue = defineModel<string>()// 如果不想modelValue 为undefined,设置required: true
// modelValue 被推断为 Ref<string>
const modelValue = defineModel<string>({ required: true })// 可以同时指定第二个类型参数来明确修饰符的类型
// modelValue 被推断为 Ref<string | undefined>
// 修饰符被指定为只能是"trim"或者"uppercase"这两种字符串字面量类型之一。
// modifiers 被推断为 Record<'trim' | 'uppercase', true | undefined>
// 表示modifiers是一个对象,键为指定的修饰符类型,值为true或undefined,表示该修饰符是否被应用。
const [modelValue, modifiers] = defineModel<string, "trim" | "uppercase">()
defineExpose()
在 Vue 3 的 <script setup> 中,defineExpose 是一个用于明确指定组件实例对外暴露哪些属性和方法的函数。
使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。
defineExpose 允许开发者精确地控制哪些属性和方法可以被父组件通过模板引用访问到。
在子组件的 <script setup> 中,可以调用 defineExpose 并传入一个对象,该对象包含要暴露的属性和方法。
<template><div><div>count: {{ count }}</div><button @click="addCount">点击 count+1</button></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';let count = ref(0);const addCount = () => {count.value++;
};// 把属性count、方法addCount暴露给父组件
defineExpose({count,addCount
});
</script>
在这个例子中,子组件定义了一个内部的响应式数据 count和一个方法 addCount,然后通过 defineExpose 将它们暴露出去。
在父组件中,可以通过模板引用获取子组件的实例,并访问通过 defineExpose 暴露出来的属性和方法。
<template><ChildComponent ref="childRef" /><button @click="accessChildComponent">Access child component</button>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const childRef = ref(null);const accessChildComponent = () => {if (childRef.value) {console.log(childRef.value.count);childRef.value.addCount();}
};
</script>
在这个例子中,父组件通过模板引用 childRef 获取子组件的实例,并在按钮的点击事件中访问子组件暴露出来的 count 和调用 addCount。
defineOptions()
defineOptions 是一个用于定义组件选项的函数。
这个宏可以用来直接在 <script setup> 中声明组件选项,而不必使用单独的 <script> 块:
<script setup>
defineOptions({inheritAttrs: false,customOptions: {/* ... */}
})
</script>
这是一个宏定义,选项将会被提升到模块作用域中,无法访问 <script setup> 中不是字面常数的局部变量。
可以用来直接在 <script setup> 中声明组件选项,比如 name、inheritAttrs 等。
使用 defineOptions 来明确指定组件的名称:
<script setup>
import { defineOptions } from 'vue';defineOptions({name: 'MyComponent',
});
</script>
在这个例子中,明确指定了组件的名称为 MyComponent。
inheritAttrs 选项决定了组件是否继承未被识别的属性并将其应用到根元素上。默认情况下,组件会继承这些属性。
使用 defineOptions 设置 inheritAttrs: false 时,组件不会继承未被识别的属性:
<script setup>
import { defineOptions } from 'vue';defineOptions({inheritAttrs: false,
});
</script>
在这个例子中,设置 inheritAttrs 为 false,表示组件不继承未被识别的属性。
使用defineOptions 设置emits属性(替代defineEmits),定义组件可以触发的自定义事件:
<script setup>
import { defineOptions } from 'vue';defineOptions({emits: ['customEvent1', 'customEvent2'],
});
</script>
使用defineOptions 设置props属性(替代defineEmits),定义组件接收的外部传入的属性:
<script setup>
import { defineOptions } from 'vue';defineOptions({props: {propName1: String,propName2: {type: Number,default: 0,},},
});
</script>
可以用来对组件的 setup 函数进行一些额外的配置:
<script setup>
import { defineOptions } from 'vue';defineOptions({setup() {// 一些特殊的 setup 配置逻辑return {// 返回一些特定的值或对象};},
});
</script>
虽然可以使用 defineOptions 来配置这些属性,但在很多情况下,使用专门的函数如 defineProps、defineEmits 等可能会更加简洁和直观。
defineSlots()
defineSlots是一个用于定义组件插槽的函数。defineSlots允许开发者在<script setup>语法中明确地定义组件的插槽。defineSlots()只接受类型参数,没有运行时参数。- 类型参数应该是一个类型字面量,其中属性键是插槽名称,值类型是插槽函数。
- 函数的第一个参数是插槽期望接收的
props,其类型将用于模板中的插槽props。返回类型目前被忽略,可以是any。
- 返回
slots对象,该对象等同于在setup上下文中暴露或由useSlots()返回的slots对象。
<script setup lang="ts">
const slots = defineSlots<{default(props: { msg: string }): any
}>()
</script>
可以使用 defineSlots 来定义一个名为 default 的插槽:
<script setup>
import { defineSlots } from 'vue';const slots = defineSlots({default: () => null,
});
</script>
在这个例子中,定义了一个默认插槽,其函数返回值为 null,表示插槽的默认内容为空。
在模板中,可以使用 <slot> 标签来渲染插槽内容:
<template><div><slot /></div>
</template>
useSlots() 和 useAttrs()
在 <script setup> 使用 slots 和 attrs 的情况应该是相对来说较为罕见的,因为可以在模板中直接通过 $slots 和 $attrs 来访问它们。在需要使用它们的罕见场景中,可以分别用 useSlots 和 useAttrs 两个辅助函数:
useSlots函数用于访问组件的插槽内容。它返回一个对象,其中包含了组件所定义的各个插槽的内容。- 通过
useSlots,可以在组件的逻辑部分动态地处理插槽内容,根据不同的条件渲染不同的插槽内容,或者对插槽内容进行进一步的加工和处理。
- 通过
<script setup>
import { useSlots } from 'vue';const slots = useSlots();
console.log(slots.default());
</script>
在这个例子中,useSlots 返回的对象被赋值给 slots。然后,可以通过 slots.default() 来访问默认插槽的内容。如果组件有多个插槽,可以通过相应的属性名来访问,比如 slots.slotName。
useAttrs函数用于访问组件上未被识别的属性(即没有被组件的props定义的属性)。它返回一个包含这些属性的对象。
<script setup>
import { useAttrs } from 'vue';const attrs = useAttrs();
console.log(attrs.class);
</script>
在这个例子中,useAttrs 返回的对象被赋值给 attrs。可以通过 attrs 对象访问组件上的属性,比如 attrs.class 访问 class 属性。
与普通的 <script> 一起使用
<script setup> 可以和普通的 <script> 一起使用。普通的 <script> 在有这些需要的情况下或许会被使用到:
- 声明无法在
<script setup>中声明的选项,例如inheritAttrs或插件的自定义选项 (在 3.3+ 中可以通过defineOptions替代)。 - 声明模块的具名导出 (named exports)。
- 运行只需要在模块作用域执行一次的副作用,或是创建单例对象。
<script>
// 普通 <script>,在模块作用域下执行 (仅一次)
runSideEffectOnce()// 声明额外的选项
export default {inheritAttrs: false,customOptions: {}
}
</script><script setup>
// 在 setup() 作用域中执行 (对每个实例皆如此)
</script>
相关文章:
vue3 语法糖<script setup>
在 Vue 3 中,<script setup>是一种新的语法糖,它极大地简化了组件的编写方式。 <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。 基本概念 简洁的语法…...
微服务设计原则——高性能:异步与并发
文章目录 1.异步1.1 调用异步1.2 流程异步1.3 数据流异步1.4 小结 2.并发2.1 请求并发2.2 冗余请求2.3 小结 参考文献 1.异步 对于处理耗时长的任务,如果采用同步等待的方式,会严重降低系统的吞吐量,可以采用异步化进行解决。 异步…...
机器学习——决策树,朴素贝叶斯
一.决策树 决策树中的基尼系数(Gini Index)是用于衡量数据集中不纯度(或混杂度)的指标。基尼系数的取值范围在0到0.5之间,其中0表示数据完全纯(同一类别),0.5表示数据完全混杂。 基…...
C语言基础(十)
编译预处理命令: 预编译命令在C语言中用于在编译前进行一些特定的处理和控制,帮助程序员更灵活地管理源代码和控制编译过程。 C语言常用的预编译命令: #include:用于包含头文件,将另一个文件的内容插入到当前文件中…...
人像比对-人证比对-人脸身份证比对-人脸身份证实名认证-人脸三要素对比-实人认证
人脸身份证实名认证是一种基于生物识别技术的身份验证方式,主要依托证件OCR识别技术、活体检测、人脸比对等技术手段,对用户身份信息真实性进行核验,确保用户为真人且为本人。以下是关于人脸身份证实名认证的详细解析: 一、认证流…...
Android 上下滑隐藏显示状态栏
一、DisplayPolicy类中监听滑动事件,然后发送广播事件 Android12类路径: frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.javamSystemGestures new SystemGesturesPointerEventListener(mUiContext, mHandler,new SystemGest…...
USBCAN-II/II+使用方法以及qt操作介绍
一.USBCAN-II/II介绍 USBCAN-II/II 是一款常用的 USB-CAN 转换器,广泛应用于汽车电子、工业自动化等领域。以下是使用该设备的一般步骤和方法: 1. 硬件连接 连接设备:将 USBCAN-II/II 的 USB 接口连接到计算机的 USB 端口。 连接 CAN 网络…...
笔记-系统规划与管理师-案例题-2022年-IT服务部署实施
【说明】 某大型企业去年信息化投入大,完成了重点核心业务系统的建设。由于应急相应预案制定得不充分并且未开展演练,出现了系统性故障时,部分关键的应用系统不可用且在12小时内未能完成恢复业务,给企业带来了较大损失。 为加强该…...
Kubernetes 清理资源常用的 Kubernetes 清理命
清理特定状态的 Pod: 清理 Evicted 状态的 Pod: kubectl get pods --all-namespaces -o wide | grep Evicted | awk {print $1,$2} | xargs -L1 kubectl delete pod -n清理 Error 状态的 Pod: kubectl get pods --all-namespaces -o wide | g…...
【数据结构初阶】二叉树--基本概念
hello! 目录 一、树 1.1 树的概念和结构 1.2 树的相关术语 1.3 树的表示 1.4 树形结构实际应用场景 二、二叉树 2.1 概念和结构 2.2 特殊的二叉树 2.2.1 满二叉树 2.2.2 完全二叉树 2.3 二叉树的存储结构 2.3.1 顺序结构 2.3.2 链式结构 …...
Pytorch添加自定义算子之(12)-开闭原则设计tensorrt和onnxruntime推理语义分割模型
一、开闭原则 开闭原则是SOLID原则中的一个,指的是尽量使用开放扩展,关闭修改的设计原则。 在C++中如何使用开闭原则导出动态库,可以按照以下步骤进行: 定义抽象基类:定义动态库中的抽象基类,该基类应该封装可扩展的接口。 实现派生类:实现基类的派生类,这些派生类将封…...
第二百零九节 Java格式 - Java数字格式类
Java格式 - Java数字格式类 以下两个类可用于格式化和解析数字: java.text.NumberFormatjava.text.DecimalFormat NumberFormat 类可以格式化一个数字特定地区的预定义格式。 DecimalFormat 类可以格式化数字以特定区域设置的自定义格式。 NumberFormat类的 getXXXInstance…...
LSI-9361阵列卡笔记
背景 要将raid0更改为JBOD直通模式 注意的点是要先将raid模式调整为JBOD之后重启机器,即可 备注:转换过程中硬盘中的数据未丢失。 步骤贴图 refer https://zhiliao.h3c.com/questions/dispcont/123250 https://blog.csdn.net/GreapFruit_J/article/…...
ArcGIS热点分析 (Getis-Ord Gi*)——基于地级市尺度的七普人口普查数据的热点与冷点分析
先了解什么是热点分析 ? 热点分析 (Getis-Ord Gi*) 是一种用于空间数据分析的技术,主要用于识别地理空间数据中值的聚集模式,可以帮助我们理解哪些区域存在高值或低值的聚集,这些聚集通常被称为“热点”或“冷点”,Gi* 统计量为…...
ASIACRYPT 2021
分类文章编号获奖论文1-3后量子密码4-9多方计算10-15物理攻击,泄露和对策16-21理论22-27公钥密码和鉴权密钥交换28-33高级加密和签名34-39对称密钥构建40-46量子安全47-53获奖论文54对称密码分析55-66增强型公钥加密和时间锁难题67-72同态加密和加密搜索73-77NIZK和SNARK78-80…...
C#学习之路day1
目录 一、概念:.net和c# 二、.net发展方向 三、.Net两种交互模式 四、创建项目 五、vs的组成部分 六、我的第一个C#程序 七、多个项目时启动项目的设置 八、注释 九、快捷键 一、概念:.net和c# 1、.net/dotnet :一般指.Net Framework框架&#…...
【安当产品应用案例100集】010-基于国密UKEY的信封加密应用案例
安当有个客户开发了一套C/S架构的软件,Server在云端,Client由不同的用户使用。最初软件设计开发的时候,没有考虑数据安全形势日渐严峻的问题,Server端和Client端直接就建立一个socket连接来进行通信,Server端发出去的数…...
扫码点餐系统小程序功能分析
扫码点餐系统小程序通常具备以下核心功能: 用户界面:提供直观易用的界面,方便用户浏览菜单、选择菜品、查看订单状态等 。菜单展示:展示餐厅的菜单,包括菜品图片、价格、描述等信息 。扫码点餐:用户通过…...
网络安全——基础知识记忆梳理
1. SQL注入攻击 SQL注入攻击是一种常见的网络安全威胁,它利用Web应用程序中对用户输入的数据的不正确处理,攻击者可以在SQL查询中注入恶意代码,从而执行非授权的数据库操作。这种攻击方式可以导致数据泄漏、数据篡改、绕过认证等多种安全问题…...
GitHub开源的轻量级文件服务器,可docker一键部署
文件服务器 介绍安装使用命令使用API调用 介绍 项目github官网地址 Dufs是一款由Rust编写的轻量级文件服务器,不仅支持静态文件服务,还能轻松上传、下载、搜索文件,甚至支持WebDAV,让我们通过Web方式远程管理文件变得轻而易举。…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
