Vue.js前端开发零基础教学(五)

目录

4.1 动态组件

4.1.1  定义动态组件

 4.1.2  利用KeepAlive组件实现组件缓存

4.1.3  组件缓存相关的生命周期函数

4.1.4  KeepAlive组件的常用属性 

 4.2 插槽

4.2.1  什么是插槽

​编辑 4.2.2  具名插槽

4.2.3  作用域插槽 

4.3 自定义指令 

4.3.1 什么是自定义指令

4.3.2  私有自定义指令的声明与使用

4.3.3 全局自定义指令的声明与使用 

4.3.4  为自定义指令绑定参数

​编辑 4.3.5  自定义指令的函数形式

4.4 引用静态资源


学习目标:

 掌握具名插槽的使用方法,能够通过name属性定义具名插槽

掌握私有自定义指令的使用方法,能够独立完成私有自定义指令的声明和使用

 掌握为自定义指令绑定参数的使用方法,能够通过等号(=)的方式,为当前   指令绑定参数

掌握自定义指令的函数形式,能够使用函数形式简化自定义指令的声明等等

4.1 动态组件

4.1.1  定义动态组件

利用动态组件可以动态切换页面中显示的组件。使用<component>标签可以定义动态组件,语法格式如下。

<component is="要渲染的组件"></component>

上述语法格式中,<component>标签必须配合is属性一起使用,is属性的属性值表示要渲染的组件,当该属性值发生变化时,页面中渲染的组件也会发生变化。

is属性的属性值可以是字符串或组件,当属性值为组件时,如果要实现组件的切换,需要调用shallowRef()函数定义响应式数据,将组件保存为响应式数据。shallowRef()函数只处理对象最外层属性的响应,它比ref()函数更适合于将组件保存为响应式数据。

代码如下:

创建Myleft.vue文件:

<template>
	Myleft组件

<div>
	count的值:{{值}}
	<button @click="count+1">+1</button>
</div>
</template>
<script setup>
	import {onMounted,onUnmounted,onActivated,onDeactivated,ref} from 'vue'
	const count = ref(0);
	onMounted(()=>{
		console.log("Myleft组件被挂载成功")
	}
	)
	onUnmounted(()=>{
		console.log("Myleft组件被销毁成功")
	}
	)
		
	onActivated(()=>{
		console.log("MyRight组件被缓存了")
	}
	)
	
onDeactivated(()=>{
		console.log("MyRight组件被缓存了")
	}
	)
	
</script>

<style>
</style>

创建Myright.vue文件:

<template>
	Myright组件
</template>

<script>
</script>

<style>
</style>

创建DynamicComponet.vue文件:

<template>
	<button @click="showComponent=Myleft">展示MyLeft组件</button>
	<button @click="showComponent=Myright">展示MyRight组件</button>
	<KeepAlive>
	<div> 
	
	<component :is="showComponent"></component></div>
	</KeepAlive>
</template>

<script setup>
	import {shallowRef} from 'vue'
	import Myleft from'./Myleft.vue' 
	import Myright from './Myright.vue'
	
	const showComponent = shallowRef(Myleft)
</script>

<style>
</style>

修改main.js文件:

import { createApp } from 'vue'
import App from './components/DynamicComponet.vue'
const app=createApp(App)
//import GlobalComponent from './components/GlobalComponent.vue'
// app.component("GlobalComponent", GlobalComponent)
app.mount('#app')

运行结果:

 4.1.2  利用KeepAlive组件实现组件缓存

概念:使用动态组件实现组件之间的按需切换时,隐藏的组件会被销毁,展示出来的组件会被重新创建。因此,当一个组件被销毁后又重新创建时,组件无法保持销毁前的状态。

如果在多个组件之间进行动态切换时想要保持这些组件的状态,以及避免重复渲染导致的性能问题,可以通过组件缓存来实现。

组件缓存可以使组件创建一次后,不会被销毁。在Vue中可以通过KeepAlive组件来实现组件缓存。 KeepAlive组件可通过<KeepAlive>标签来定义,定义时使用<KeepAlive>标签包裹需要被缓存的组件。运行结果:

 从单击“展示MyRight组件”按钮后的页面效果和控制台可以看出,控制台中没有输出“MyLeft组件被销毁了”的信息,说明此时MyLeft组件已经被缓存了。 再次单击“展示MyLeft组件”按钮,页面效果与步骤1中单击“+1”按钮后的页面效果相同,说明通过添加<KeepAlive>标签可以实现组件缓存。

4.1.3  组件缓存相关的生命周期函数

概念:在Vue开发中,有时需要在组件被激活或者被缓存时执行某些操作。为此,Vue提供了组件缓存相关的生命周期函数,可以监听组件被激活和组件被缓存的事件。

当组件被激活时,会触发组件的onActivated()生命周期函数;当组件被缓存时,会触发组件的onDeactivated()生命周期函数。这两个生命周期函数的语法格式如下。

// onActivated()生命周期函数
onActivated(() => { })
// onDeactivated()生命周期函数
onDeactivated(() => { })

MyLeft.vue文件新增代码: 

<script setup>
import { ref, onMounted, onUnmounted, onActivated, onDeactivated } from 'vue'
onActivated(() => {
  console.log('MyLeft组件被激活了')
})
onDeactivated(() => {
  console.log('MyLeft组件被缓存了')
})
</script>

MyRight.vue文件新增代码:

<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
  console.log('MyRight组件被激活了')
})
onDeactivated(() => {
  console.log('MyRight组件被缓存了')
})
</script>

运行结果:

单击“展示MyRight组件”按钮后的页面效果和控制台如下图所示。

 单击“展示MyLeft组件”按钮后的页面效果和控制台如下图所示。

4.1.4  KeepAlive组件的常用属性 

概念:在默认情况下,所有被<KeepAlive>标签包裹的组件都会被缓存。如果想要实现特定组件被缓存或者特定组件不被缓存的效果,可以通过KeepAlive组件的常用属性include、exclude属性来实现。

                                     KeepAlive组件的常用属性如下表所示。

在<KeepAlive>标签中使用include属性和exclude属性时,多个组件名之间使用英文逗号分隔,以include属性为例,语法格式如下。 

<KeepAlive include="组件名1, 组件名2">
  被缓存的组件
</KeepAlive>

 4.2 插槽

4.2.1  什么是插槽

概念:Vue为组件的封装者提供了插槽(slot),插槽是指开发者在封装组件时不确定的、希望由组件的使用者指定的部分。也就是说,插槽是组件封装期间为组件的使用者预留的占位符,允许组件的使用者在组件内展示特定的内容。通过插槽,可以使组件更灵活、更具有可复用性。

插槽需要定义后才能使用,下面对定义插槽和使用插槽分别进行讲解。

1. 定义插槽

在封装组件时,可以通过<slot>标签定义插槽,从而在组件中预留占位符。假设项目中有一个MyButton组件,在MyButton组件中定义插槽的示例代码如下。

<template>
  <button>
    <slot></slot>
  </button>
</template>

在<slot>标签内可以添加一些内容作为插槽的默认内容。如果组件的使用者没有为插槽提供任何内容,则默认内容生效;如果组件的使用者为插槽提供了插槽内容,则该插槽内容会取代默认内容。 另外,如果一个组件没有预留任何插槽,则组件的使用者提供的任何插槽内容都会不起作用。

2. 使用插槽

概念:使用插槽即在父组件中使用子组件的插槽,在使用时需要将子组件写成双标签的形式,在双标签内提供插槽内容。例如,使用MyButton组件的插槽的示例代码如下。

因为插槽内容是在父组件模板中定义的,所以在插槽内容中可以访问到父组件的数据。插槽内容可以是任意合法的模板内容,不局限于文本。例如,可以使用多个元素或者组件作为插槽内容,示例代码如下。

<MyButton>
  <span style="color: yellow;">按钮</span>
  <MyLeft />
</MyButton>

创建src\components\SlotSubComponent.vue文件,用于展示子组件的相关内容。

<template>
  <div>测试插槽的组件</div>
  <slot></slot>
</template>

创建src\components\MySlot.vue文件,用于展示插槽的相关内容。

<template>
  父组件-----{{ message }}
  <hr>
  <SlotSubComponent>
    <p>{{ message }}</p>
  </SlotSubComponent>
</template>
<script setup>
import SlotSubComponent from './SlotSubComponent.vue'
const message = '这是组件的使用者自定义的内容'
</script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/MySlot.vue'

运行结果:

 演示插槽的默认内容

 演示插槽的默认内容,实现当组件的使用者没有自定义内容时默认内容生效的效果。 注释MySlot组件中插槽内容。

<!-- <p>{{ message }}</p> -->

在SlotSubComponent组件中为<slot>标签提供默认内容。

<slot>
  <p>这是默认内容</p>
</slot>

运行结果:

将MySlot组件中的插槽内容取消注释,保存上述代码后,页面效果如下图所示。

 4.2.2  具名插槽

概念:在Vue中当需要定义多个插槽时,可以通过具名插槽来区分不同的插槽。具名插槽是给每一个插槽定义一个名称,这样就可以在对应名称的插槽中提供对应的数据了

插槽通过<slot>标签来定义,<slot>标签有一个name属性,用于给各个插槽分配唯一的名称,以确定每一处要渲染的内容。添加name属性的<slot>标签可用来定义具名插槽。 定义具名插槽的语法格式如下。

<slot name="插槽名称"></slot>

在父组件中,如果要把内容填充到指定名称的插槽中,可以通过一个包含v-slot指令的<template>标签来实现,语法格式如下。

<组件名>
  <template v-slot:插槽名称></template>
</组件名>

与v-on和v-bind类似,v-slot也有简写形式,即把v-slot:替换为#。例如,v-slot:title可以简写为#title。

演示具名插槽的使用

创建src\components\ArticleInfo.vue文件,用于展示文章内容模板。

<template>
  <div class="article-container">
    <div class="header-box"><slot name="header"></slot></div>
    <div class="content-box"><slot name="content"></slot></div>
    <div class="footer-box"><slot name="footer"></slot></div>
  </div>
</template>
<style>
.article-container > div { border: 1px solid black; }
</style>

创建src\components\MyArticle.vue文件,用于提供文章数据,在MyArticle组件中导入并使用ArticleInfo组件,并在<ArticleInfo>标签中为不同插槽添加不同的信息。

<template>
  <ArticleInfo>
    <template v-slot:header><p>这是文章的头部区域</p></template>
    <template v-slot:content><p>这是文章的内容区域</p></template>
    <template #footer><p>这是文章的尾部区域</p></template>
  </ArticleInfo>
</template>
<script setup>import ArticleInfo from './ArticleInfo.vue' </script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/MyArticle.vue'

运行结果:

4.2.3  作用域插槽 

概念:一般情况下,在父组件中不能使用子组件中定义的数据。如果想要在父组件中使用子组件中定义的数据,则需要通过作用域插槽来实现。作用域插槽是带有数据的插槽,子组件提供一部分数据给插槽,父组件接收子组件的数据进行页面渲染。

作用域插槽的使用分为定义数据和接收数据两个部分。

1. 定义数据

在封装组件的过程中,可以为预留的插槽定义数据,供父组件接收并使用子组件中的数据。在作用域插槽中,可以将数据以类似传递props属性的形式添加到<slot>标签上。 例如,在封装MyHeader组件时,在插槽中定义数据供父组件使用,示例代码如下。

<slot message="Hello Vue.js"></slot>

2. 接收数据

使用默认插槽和具名插槽接收数据的方式不同,接下来分别进行讲解。

下面讲解默认插槽:

在Vue中,每个插槽都有name属性,表示插槽的名称。在定义插槽时虽然省略了<slot>标签的name属性,但是name属性默认为default,这样的插槽属于默认插槽。

在父组件中可以通过v-slot指令接收插槽中定义的数据,即接收作用域插槽对外提供的数据。通过v-slot指令接收到的数据可以在插槽内通过Mustache语法进行访问。 例如,在父组件中使用MyHeader组件中的插槽时,通过v-slot指令的值接收传递的数据的示例代码如下。

作用域插槽对外提供的数据对象可以使用解构赋值以简化数据的接收过程,示例代码如下。

 下面讲解具名插槽: 在Vue中,通过<slot>标签添加name属性来定义具名插槽,在具名插槽中也可以向父组件中传递数据。 例如,在封装MyHeader组件时,向具名插槽中传入数据的语法格式如下。

<slot name="header" message="hello"></slot>

具名插槽和作用域插槽可以作用在同一个<slot>标签上且并不冲突。<slot>标签的name属性不会作为数据传递给插槽,所以最终传递给组件的数据只有message属性。

在使用具名插槽时,插槽属性可以作为v-slot的值被访问到,基本语法格式为“v-slot:插槽名称="形参"”,简写形式为“#插槽名称="形参"”,使用简写形式使用插槽的示例代码如下。

<MyHeader>
  <template #header="{ message }">
    {{ message }}
  </template>
</MyHeader>

如果在一个组件中同时定义了默认插槽和具名插槽,并且它们均需要为父组件提供数据,这时就需要为默认插槽使用显式的<template>标签来接收数据,示例代码如下。

<MyHeader>
  <template #default="{ message }">
    {{ message }}
  </template>
</MyHeader>

演示作用域插槽的使用

创建src\components\SubScopeSlot.vue文件,用于展示作用域插槽。

<template>
  <slot message="Hello 默认插槽"></slot>
  <hr>
  <slot message="Hello Vue.js" name="header"></slot>
  <hr>
  <slot :user="user" name="content"></slot>
</template>
<script setup>
import { reactive } from 'vue'
const user = reactive({ name: 'xiaoyuan', age: '15' })	    
</script>

创建src\components\ScopeSlot.vue文件,用于为作用域插槽提供数据。

<template>
  <SubScopeSlot>
    <template v-slot:default="scope"><p>{{ scope }}</p></template>
    <template v-slot:header="scope">
      <p>{{ scope }}</p><p>{{ scope.message }}</p>
    </template>
    <template #content="{ user }">
      <p>{{ user.name }}</p><p>{{ user.age }}</p></template>
  </SubScopeSlot>
</template>
<script setup>import SubScopeSlot from './SubScopeSlot.vue'</script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/ScopeSlot.vue'

运行结果:

4.3 自定义指令 

4.3.1 什么是自定义指令

当内置指令不能满足开发需求时,可以通过自定义指令来拓展额外的功能。自定义指令的主要作用是方便开发者通过直接操作DOM元素来实现业务逻辑。

Vue中的自定义指令分为两类,分别是私有自定义指令和全局自定义指令 私有自定义指令是指在组件内部定义的指令。私有自定义指令可以在定义该指令的组件内部使用。例如,在组件A中自定义了指令,只能在组件A中使用,组件B、组件C中不能使用。 全局自定义指令是指在全局定义的指令。全局自定义指令可以在全局使用,例如,在src\main.js文件中定义了全局自定义指令,这个指令可以用于任何一个组件。

一个自定义指令由一个包含自定义指令生命周期函数的参数来定义。常用的自定义指令生命周期函数如下表所示。

常用的自定义指令生命周期函数的参数如下表所示。

binding中包含以下6个常用属性。

value:传递给指令的值。

arg:传递给指令的参数。

oldValue:之前的值,仅在beforeUpdate()函数和updated()函数中可用,无论值是否更改都可用。 modifiers:一个包含修饰符的对象 (如果有)。例如,在v-my-directive.foo.bar 中,修饰符对象是{ foo: true, bar: true }。

instance:使用该指令的组件实例。 dir:指令的定义对象。 

4.3.2  私有自定义指令的声明与使用

如果没有使用setup语法糖,可以在directives属性中声明私有自定义指令。例如,声明一个私有自定义指令color,示例代码如下。

export default {
  directives: {
    color: {}
  }
}

在上述代码中,color为自定义指令的名称,指令名称可以自定义。名称为color的指令指向一个配置对象,对象中可以包含自定义指令的生命周期函数,可通过这些函数来操作DOM元素。

在使用自定义指令时,需要以“v-”开头,示例代码如下。

<h1 v-color>标题</h1>

如果使用setup语法糖,任何以“v”开头的驼峰式命名的变量都可以被用作一个自定义指令,示例代码如下。

<template>
  <span v-color></span>
</template>
<script setup>
const vColor = { }
</script>

驼峰式命名:驼峰式命名规则是一种在编程中广泛使用的命名约定。它有两种主要形式:

小驼峰式命名法:这种命名方式中,第一个单词的首字母小写,从第二个单词开始,每个单词的首字母都大写。例如,“firstName”和“lastName”。

大驼峰式命名法:在这种命名法中,每个单词的首字母都大写,而第一个单词的首字母小写。例如,“FirstName”、“LastName”和“CamelCase”。大驼峰式也被称为Pascal命名法,这种命名法常用于类名和常量名。

演示私有自定义指令的使用方法

创建src\components\DirectiveComponent.vue文件。

<template>
  <p v-fontSize>DirectiveComponent组件</p>
</template>
<script setup>
const vFontSize = {}
</script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/DirectiveComponent.vue'

修改DirectiveComponent组件,添加mounted()函数,实现元素挂载完成后文本字号的改变。

const vFontSize = {
  mounted: el => {
    el.style.fontSize = '24px'
  }
}

 运行结果:

4.3.3 全局自定义指令的声明与使用 

全局自定义指令需要通过Vue应用实例的directive()方法进行声明,语法格式如下。

directive('自定义指令名称', 对象)

在上述语法格式中,directive()方法的第1个参数类型为字符串,表示全局自定义指令的名称;第2个参数类型为对象或者函数,可以是对象或者函数形式,用于接收指令的参数值。

下面演示全局自定义指令的使用方式。 修改src\main.js文件,声明全局自定义指令fontSize。

import { createApp } from 'vue'
import './style.css'
import App from './components/DirectiveComponent.vue'
const app = createApp(App)
app.directive('fontSize', {
  mounted: el => {
    el.style.fontSize = '24px'
  }
})
app.mount('#app')

4.3.4  为自定义指令绑定参数

在使用自定义指令时,开发人员可以通过自定义指令的参数改变元素的状态,传递的参数由自定义指令的生命周期函数的第2个参数接收。 在标签中使用自定义指令时,通过等号(=)的方式可以为当前指令绑定参数,示例代码如下。

<h1 v-color="color"></h1>

如果指令需要多个值,可以传递一个对象,示例代码如下。

<div v-demo="{ color: 'red', text: 'hello' }"></div>

演示自定义指令参数的使用方法

创建src\components\CustomDirective.vue文件。

<template>
  <p v-fontSize="fontSize">DirectiveComponent组件</p>
  <button @click=“fontSize = ‘24px’”>更改字号大小</button>
</template>
<script setup>
import { ref } from 'vue'
const fontSize = ref('12px')
const vFontSize = {
  mounted: (el, binding) => { el.style.fontSize = binding.value },
}
</script>

修改src\main.js文件,切换页面中显示的组件。

运行结果:

演示自定义指令参数的使用方法

在自定义指令fontSize中添加updated()函数,实现自定义指令绑定的参数改变时,页面进行同步更改。

const vFontSize = {
  // 原有代码……
  updated: (el, binding) => {
    el.style.fontSize = binding.value
  }
}

运行结果:

4.3.4  为自定义指令绑定参数

在使用自定义指令时,开发人员可以通过自定义指令的参数改变元素的状态,传递的参数由自定义指令的生命周期函数的第2个参数接收。
在标签中使用自定义指令时,通过等号(=)的方式可以为当前指令绑定参数,示例代码如下。
<h1 v-color="color"></h1>

如果指令需要多个值,可以传递一个对象,示例代码如下。

<div v-demo="{ color: 'red', text: 'hello' }"></div>

演示自定义指令参数的使用方法

创建src\components\CustomDirective.vue文件。

<template>
  <p v-fontSize="fontSize">DirectiveComponent组件</p>
  <button @click=“fontSize = ‘24px’”>更改字号大小</button>
</template>
<script setup>
import { ref } from 'vue'
const fontSize = ref('12px')
const vFontSize = {
  mounted: (el, binding) => { el.style.fontSize = binding.value },
}
</script>

修改src\main.js文件,切换页面中显示的组件。

import App from './components/CustomDirective.vue'

运行效果:

演示自定义指令参数的使用方法

在自定义指令fontSize中添加updated()函数,实现自定义指令绑定的参数改变时,页面进行同步更改。

const vFontSize = {
  // 原有代码……
  updated: (el, binding) => {
    el.style.fontSize = binding.value
  }
}

 运行结果:

单击“更改字号大小”按钮后的页面效果如下图所示。

 4.3.5  自定义指令的函数形式

对于自定义指令来说,通常仅需要在mounted()函数和updated()函数中操作DOM元素,除此之外,不需要其他的生命周期函数。

例如,4.3.4小节CustomDirective 组件中的mounted()函数和updated()函数中的代码完全相同。此时,可以将自定义指令简写为函数形式。 将私有自定义指令简写为函数形式的示例代码如下。

const vFontSize = (el, binding) => {
  el.style.fontSize = binding.value
}

将全局自定义指令简写成函数形式的示例代码如下。

app.directive('fontSize', (el, binding) => {
  el.style.fontSize = binding.value
})

4.4 引用静态资源

1. 引用public目录中的静态资源

public目录用于存放不可编译的静态资源文件,该目录下的文件会被复制到打包目录,该目录下的文件需要使用绝对路径访问。 例如,在组件中引用public目录中的demo.png文件,示例代码如下。

<img src="/demo.png" >

演示引用public目录中静态资源的方法

创建src\components\Image.vue文件。

<template>
  <img src="/vite.svg" >
</template>

修改src\main.js文件,切换页面中显示的组件,示例代码如下。

import App from './components/Image.vue'

运行效果:

2. 引用src\assets目录中的静态资源 

src\assets目录用于存放可编译的静态资源文件,例如图片、样式文件等。该目录下的文件需要使用相对路径访问。

在引用src\assets目录中的图片时,首先将图片保存到本地,然后使用import语法将图片导入需要的组件,最后通过img元素的src属性添加图片的路径。

演示引用src\assets中静态资源的方法

创建src\components\Icon.vue文件。

<template>
  <img :src="icon">
</template>
<script setup>
import icon from '../assets/vue.svg'
</script>

修改src\main.js文件,切换页面中显示的组件,示例代码如下。

import App from './components/Icon.vue'

运行效果:

 

今天就分享到此,感谢预览~ 

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

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

相关文章

LLM大语言模型(十):LangChain自定义Agent使用自定义的LLM

背景 独立部署ChatGLM3-6B并提供HTTP API能力。 自定义LLM封装对ChatGLM3-6B的访问。 创建一个简单的Agent来使用自定义的LLM。 自行封装LLM&#xff08;MyChatGLM&#xff09; 上一篇文章LLM大语言模型&#xff08;九&#xff09;&#xff1a;LangChain封装自定义的LLM-C…

基于SSM+Jsp+Mysql的个性化影片推荐系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

[数据结构]栈和队列结构的简单制作

一、栈 1.1栈的概念以及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原…

Vant DropdownMenu 下拉菜单带搜索功能

Vant DropdownMenu 下拉菜单带搜索功能 效果图&#xff1a; 上代码&#xff1a; <van-dropdown-menu active-color"#E33737"><van-dropdown-item ref"dropdownItem"><template #title><span>{{ dropdownItem.text }}</span…

蓝桥杯2022年第十三届省赛真题-最少刷题数

solution&#xff08;通过50%&#xff09; 忽略了存在分数相同的情况&#xff0c;若从p位置开始有若干个相同分数的无需再多刷&#xff0c;但是在p位置前若干个&#xff08;含p位置&#xff09;分数相同则都需要多刷一道题。 #include<iostream> #include<algorithm…

运动想象 (MI) 分类学习系列 (7) :CMO-CNN

运动想象分类学习系列:CMO-CNN 0. 引言1. 主要贡献2. 提出的算法3. 数据增强策略4. 结果4.1 学科内分类4.2 跨学科分类4.3 数据增强策略4.4 网络可视化4.4.1 短连接可视化4.4.2 滤波器可视化4.4.3 中间特征的可视化 5. 总结欢迎来稿 论文地址&#xff1a;https://www.sciencedi…

金铲铲单机版含教程,仅支持S1\S6\S11赛季

金铲铲单机版&#xff0c;官方的单机版&#xff0c;支持S3/S6/S11赛季&#xff0c; 我自己玩了两把&#xff0c;可以加金币/加血/设置GM权限等&#xff0c; 我猜测是开发者测试版本&#xff0c; 金铲铲单机版含教程&#xff0c;仅支持S1\S6\S11赛季 网盘自动获取 链接&#xff…

实现WAF对CC攻击的零误封防护:关键技术解析与实践

一、引言 Web应用防火墙&#xff08;WAF&#xff09;作为网站安全的重要防线&#xff0c;其在防御CC&#xff08;Challenge Collapsar&#xff0c;即挑战黑洞&#xff0c;一种分布式拒绝服务攻击&#xff09;攻击中的效能至关重要。然而&#xff0c;精准识别并有效拦截CC攻击的…

CUDA执行模型

CUDA执行模型概述 一般来说&#xff0c;执行模型会提供一个操作视图&#xff0c;说明如何在特定的计算架构上执行指令。CUDA执行模型揭示了GPU并行架构的抽象视图&#xff0c;使我们能够据此分析线程的并发。 GPU架构概述 GPU架构是围绕一个流式多处理器&#xff08;SM&…

掌握内容时效性:Kompas.ai如何帮你赢在起跑线上

在这个快速变化的数字时代&#xff0c;内容的时效性成为了品牌和媒体机构在竞争中脱颖而出的关键。时效性强的内容能够迅速吸引受众的注意力&#xff0c;提高品牌的可见度和影响力。本文将深入探讨时效性内容的重要性&#xff0c;展示Kompas.ai如何利用实时数据和趋势分析为用户…

8.string库函数的用法以及string的模拟实现

1. 为什么学习string类&#xff1f; C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0…

RTX RTOS操作实例分析之---邮箱(mailbox)

0 Preface/Foreword 1 邮箱&#xff08;mailbox&#xff09; 1.1 mailbox ID定义 static osMailQId app_mailbox NULL; 1.2 定义mailbox结构体变量 #define osMailQDef(name, queue_sz, type) \ static void *os_mail_p_##name[2]; \ const char mail_##name[] #name; \ con…

mysql双机热备

MySQL双机热备&#xff1a;保障数据库高可用性的关键技术 在当今信息化社会中&#xff0c;数据库作为企业信息系统的核心组成部分&#xff0c;其高可用性和数据安全性至关重要。MySQL作为广泛应用的开源关系型数据库管理系统&#xff0c;其双机热备技术成为保障数据库稳定运行…

4.9QT

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…

苹果商店审核指南:确保Flutter应用顺利通过审核的关键步骤

引言 Flutter是一款由Google推出的跨平台移动应用开发框架&#xff0c;其强大的性能和流畅的用户体验使其备受开发者青睐。然而&#xff0c;开发一款应用只是第一步&#xff0c;将其成功上架到苹果商店才是实现商业目标的关键一步。本文将详细介绍如何使用Flutter将应用程序上…

数字时代电子账单邮件群发:简便、高效、环保

电子账单已经在许多行业得到广泛应用&#xff0c;通过邮件群发发送电子账单简便、高效、环保&#xff0c;以下是一些通常使用电子账单的行业&#xff1a; 1.银行和金融服务&#xff1a;银行、信用合作社、金融科技公司等机构通常通过电子账单向客户提供账户摘要、交易明细、利息…

Python-VBA函数之旅-bool函数

目录 1、bool函数 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、相关文章&#xff1a; 个人主页&#xff1a;非风V非雨-CSDN博客 bool函数(Boolean Function)用于将给定的值转换为布尔值(True或False)。常见的应用场景有&#xff1a; 1、条件判断&#xff1a;bool()…

每日一题 — 无重复字符的最长子串

解法一&#xff1a;暴力枚举 先固定一个left&#xff0c;让right向右遍历遇到重复的字符&#xff0c;让left加一然后right返回&#xff0c;重新遍历 解法二&#xff1a; 滑动窗口(在解法一的基础上进行优化) 还是先固定一个left在起始位置&#xff0c;让right从起始位置开始向…

使用docker制作Android镜像(实操可用)

一、安装包准备 1、准备jdk 下载地址&#xff1a;Java Downloads | Oracle 注意版本&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我下载的jdk17&#xff0c;不然后面构建镜像报错&#xff0c;就是版本不对 2、准备安装的工具包 ttps://dev…

Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…