vue:组件的使用
Vue:组件的使用
1、什么是组件
1.1、传统方式开发的应用
一个网页通常包括三部分:结构(HTML)、样式(CSS)、交互(JavaScript)。在传统开发模式下,随着项目规模的增大,代码结构会变得愈发复杂。例如,多个页面可能共享部分样式和交互逻辑,但代码却分散在不同文件中,维护和修改时需要在多个地方查找相关代码,不仅效率低下,还容易引发错误。
1.2、组件化方式开发的应用
使用组件化方式开发解决了以上的两个问题:
① 每一个组件都有独立的js,独立的css,这些独立的js和css只供当前组件使用,不存在纵横交错。更加便于维护。以一个电商项目为例,商品展示组件有自己独立的JavaScript代码来处理商品数据展示逻辑,CSS样式只作用于该组件内的元素,与其他组件如购物车组件、用户登录组件等相互独立,当需要修改商品展示样式或逻辑时,只需要专注于该组件内部代码,不会影响到其他组件。
② 代码复用性增强。组件不仅让js、css复用了,HTML代码片段也复用了(因为要使用组件直接引入组件即可)。在项目中,像导航栏、按钮等组件,在多个页面或不同位置可能会重复使用。通过组件化,只需要编写一次这些组件代码,然后在需要的地方引入,大大提高了开发效率。
1.3、什么是组件?
① 组件:实现应用中局部功能的代码和资源的集合。凡是采用组件方式开发的应用都可以称为组件化应用。在Vue中,一个简单的按钮组件可能包含按钮的HTML结构、样式以及点击事件处理的JavaScript代码,这些代码和资源组合在一起,实现了按钮的功能,并且可以在不同地方复用。
② 模块:一个大的js文件按照模块化拆分规则进行拆分,生成多个js文件,每一个js文件叫做模块。凡是采用模块方式开发的应用都可以称为模块化应用。例如,在一个大型JavaScript项目中,将数据请求功能、数据处理功能等分别拆分成不同的模块,每个模块专注于特定功能,提高代码的可维护性和可复用性。
③ 任何一个组件中都可以包含这些资源:HTML、CSS、JS、图片、声音、视频等。从这个角度也可以说明组件是可以包括模块的。比如一个视频播放组件,除了HTML结构和CSS样式来定义播放界面,JavaScript代码来控制播放逻辑外,还可能包含视频资源文件以及用于播放控制的图片图标等。
1.4、组件的划分粒度很重要
粒度太粗会影响复用性。为了让复用性更强,Vue的组件也支持父子组件嵌套使用。例如,在一个复杂的页面布局中,将页面划分为头部、主体、底部等大粒度组件后,主体部分又可以进一步细分为文章列表组件、推荐组件等子组件。子组件由父组件来管理,父组件由父组件的父组件管理。在Vue中根组件就是vm。因此每一个组件也是一个Vue实例。这意味着每个组件都有自己独立的生命周期、数据和方法,它们之间通过特定的通信机制进行交互,构建出复杂而有序的应用结构。
2、组件的创建,注册,使用
2.1、组件的创建、注册、局部使用
第一步:创建组件
Vue.extend({该配置项和new Vue的配置项几乎相同,略有差别})
区别有哪些?
- 创建Vue组件的时候,配置项中不能使用el配置项。因为组件具有通用性,不特定为某个容器服务,它为所有容器服务。如果组件中指定了el,就限制了其只能在特定的DOM元素下使用,无法在其他地方复用。
- 配置项中的data不能使用直接对象的形式,必须使用function。以保证数据之间不会相互影响。例如,在多个相同组件实例存在的情况下,若data为对象,一个实例修改了数据,其他实例也会受到影响;而使用函数形式,每个实例都会有自己独立的数据副本。
3、使用template配置项来配置模板语句:HTML结构。通过template可以清晰地定义组件的HTML结构,使其与JavaScript和CSS分离,增强代码的可读性和维护性。
第二步:注册组件
局部注册:
在配置项当中使用components,语法格式:
components : {
组件的名字 : 组件对象
}
全局注册:
Vue.component(‘组件的名字’, 组件对象)。全局注册的组件可以在任何Vue实例的模板中使用,无需在每个组件内部再次注册。但在大型项目中,过多的全局注册组件可能会导致命名冲突和代码难以维护,因此局部注册在很多场景下更具优势。
第三步:使用组件
1、直接在页面中写<组件的名字></组件的名字>
2、也可以使用单标签<组件的名字 />。这种方式一般在脚手架中使用,否则会有元素不渲染的问题。在非脚手架环境中,某些浏览器可能不支持单标签自闭合语法,导致组件无法正确渲染,所以建议在非脚手架环境中使用双标签形式。
补充:组件的使用分为三步:
第一步:创建组件
Vue.extend({该配置项和new Vue的配置项几乎相同,略有差别})。
第二步:注册组件
局部注册:
在配置项当中使用components,语法格式:
components : {
组件的名字 : 组件对象
}
全局注册:
Vue.component(‘组件的名字’, 组件对象)
第三步:使用组件
<body><div id="app"><h1>{{msg}}</h1><!-- 3. 使用组件 --><userlist></userlist></div><script>// 1.创建组件(结构HTML 交互JS 样式CSS)const myComponent = Vue.extend({template: `<ul><li v-for="(user,index) of users" :key="user.id">{{index}},{{user.name}}</li></ul>`,data() {return {users: [{ id: "001", name: "jack" },{ id: "002", name: "lucy" },{ id: "003", name: "james" },],};},});// Vue实例const vm = new Vue({el: "#app",data: {msg: "第一个组件",},// 2. 注册组件(局部注册)components: {// userlist是组件的名字。myComponent只是一个变量名。userlist: myComponent,},});</script>
</body>
2.2、为什么组件中data数据要使用函数形式
面试题:为什么组件中data数据要使用函数形式
在 Vue 组件中 data
使用函数形式,原因有三:
一是保证组件复用性,若 data
为对象,复用实例会共享数据,修改一处影响其他实例;函数形式能让各实例有独立 data
副本,数据互不干扰。比如在一个商品列表页面,每个商品项都是一个组件实例,如果data为对象,当修改一个商品的价格时,其他商品的价格也会跟着改变,这显然不符合预期;而使用函数形式,每个商品组件实例都有自己独立的价格数据。
二是实现数据隔离与安全,降低数据冲突和意外修改风险,提升代码可维护性。不同组件实例的数据相互独立,避免了因一个实例的数据修改影响其他实例,使得代码在维护和扩展时更加稳定可靠。
三是契合 Vue 设计理念,使组件更独立、遵循单一职责原则。每个组件专注于自己的功能和数据,提高了代码的模块化程度。
<script>// 数据只有一份,数据会互相影响let dataobj = {counter: 1,};let a = dataobj;let b = dataobj;function datafun() {return {counter: 1,};}// 只要运行一次函数,就会创建一个全新的数据,互不影响let x = datafun();let y = datafun();
</script>
2.3、创建组件对象的简写方式
创建组件对象也有简写形式:Vue.extend() 可以省略。直接写:{}。Vue在内部会自动处理,当使用这种简写方式注册组件时,它会将对象作为参数传递给Vue.extend() 进行组件创建。这种简写方式使代码更加简洁,提高了开发效率。
<body><div id="app"><h1>{{msg}}</h1><!-- 3. 使用组件 --><userlogin></userlogin></div><script>// 1. 创建组件/* const userLoginComponent = Vue.extend({template : `<div><h3>用户登录</h3><form @submit.prevent="login">账号:<input type="text" v-model="username"> <br><br>密码:<input type="password" v-model="password"> <br><br><button>登录</button></form></div>`,data(){return {username : '',password : ''}},methods: {login(){alert(this.username + "," + this.password)}},}) */// 底层会在局部或全局注册组件时,自动调用Vue.extend()const userLoginComponent = {template: `<div><h3>用户登录</h3><form @submit.prevent="login">账号:<input type="text" v-model="username"> <br><br>密码:<input type="password" v-model="password"> <br><br><button>登录</button></form></div>`,data() {return {username: "",password: "",};},methods: {login() {alert(this.username + "," + this.password);}},};// Vue实例const vm = new Vue({el: "#app",data: {msg: "第二个用户登录组件",},// 2. 注册组件(局部注册)components: {userlogin: userLoginComponent,},});</script>
</body>
2.4、组件的全局注册
<body><!-- 组件的使用分为三步:第一步:创建组件Vue.extend({该配置项和new Vue的配置项几乎相同,略有差别})。第二步:注册组件局部注册:在配置项当中使用components,语法格式:components : {组件的名字 : 组件对象}全局注册:Vue.component('组件的名字', 组件对象)第三步:使用组件 --><div id="app"><h1>{{msg}}</h1><!-- 3. 使用组件 --><userlogin></userlogin></div><hr /><div id="app2"><userlogin></userlogin></div><script>const userLoginComponent = {template: `<div><h3>用户登录</h3><form @submit.prevent="login">账号:<input type="text" v-model="username"> <br><br>密码:<input type="password" v-model="password"> <br><br><button>登录</button></form></div>`,data() {return {username: "",password: "",};},methods: {login() {alert(this.username + "," + this.password);}},};// 全局注册Vue.component("userlogin", userLoginComponent);// 第2个vue实例const vm2 = new Vue({el: "#app2",});// Vue实例const vm = new Vue({el: "#app",data: {msg: "全局注册组件",},// 注册组件(局部注册)// components: {// userlogin : userLoginComponent// },});</script>
</body>
全局注册的组件在整个应用中都可使用,方便在不同的Vue实例中复用。但在大型项目中,要注意组件命名的唯一性,避免不同模块中同名组件冲突。例如,在一个包含多个功能模块的项目中,若两个模块都定义了名为“button”的组件并全局注册,就会导致命名冲突,使应用出现不可预期的错误。
2.5、组件的命名细节
注册组件细节:
- 在Vue当中是可以使用自闭合标签的,如果组件需要多次使用,前提必须在脚手架环境中使用。在非脚手架环境下,一些浏览器可能不识别自闭合标签,导致组件渲染异常。例如在IE浏览器的某些版本中,使用自闭合标签可能会使组件无法正常显示内容。
- 在创建组件的时候Vue.extend()可以省略,但是底层实际上还是会调用的,在注册组件的时候会调用。这一特性使得代码书写更加简洁,开发者无需每次都显式调用Vue.extend(),提高了开发效率。
- 组件的名字
(1):全部小写。这种命名方式简单直观,在HTML模板中使用时符合HTML标签的命名习惯,例如<my - component>
。
(2):首字母大写,后面都是小写。如<MyComponent>
,在一些代码风格规范中常用于区分组件和普通HTML标签。
(3):kebab - case命名法(串式命名法。例如:user - login)。这是一种常用的命名方式,在HTML模板中可读性强,易于理解组件的功能。
(4):CamelCase命名法(驼峰式命名法。例如:UserLogin)。但是这种方式只允许在脚手架环境中使用。在脚手架项目中,使用驼峰式命名法可以使组件名在JavaScript代码中更符合编程习惯,同时在模板中通过特定配置也能正确识别。
(5)不要使用HTML内置的标签名作为组件的名字。例如:header,main,footer。使用HTML内置标签名作为组件名可能会导致混淆和冲突,使浏览器无法正确解析和渲染组件。
(6)在创建组件的时候,通过配置项配置一个name,这个name不是组件的名字,是设置Vue开发者工具中显示的组件的名字。例如,在调试复杂应用时,通过设置name可以更方便地在开发者工具中识别和查找组件,提高调试效率。
<body><div id="app"><h1>{{msg}}</h1><!-- 3. 使用组件 --><hello - world></hello - world><hello - world /><!-- 使用多个的时候,会报错 --><!-- <hello - world /><hello - world /> --></div><script>// 1、创建组件// const hello = {// template: `<h1> helloworld </h1>`,// };// 2、全局注册组件// Vue.component("hello - world", hello);// 注册的时候,同时创建组件Vue.component("hello - world", {name: "hw",template: `<h1> HelloWorld </h1>`,});// Vue实例const vm = new Vue({el: "#app",data: {msg: "组件注册注意点",},});</script>
</body>
3、组件的嵌套
哪里要使用,就到哪里去注册,去使用。组件嵌套是构建复杂页面结构的重要方式。通过合理的组件嵌套,可以将一个大型页面拆分成多个层次分明、功能独立的组件。例如,在一个电商商品详情页面中,可能会有商品基本信息组件、商品图片展示组件、商品评论组件等,这些组件又可能各自包含子组件,如商品图片展示组件中可能包含图片切换子组件、图片预览子组件等。
在父组件中注册并使用子组件时,要注意组件的作用域和通信问题。父组件可以通过props向子组件传递数据,子组件可以通过 $ emit触发事件向父组件传递信息。比如在一个包含商品列表组件(父组件)和单个商品展示组件(子组件)的场景中,父组件可以将商品数据列表通过props传递给子组件,子组件在用户点击商品详情按钮时,通过$emit触发一个自定义事件,通知父组件进行相应的操作,如跳转到商品详情页。
在实际项目开发中,合理规划组件嵌套的层级非常关键。过深的嵌套层级可能会导致组件间通信变得复杂,增加维护成本。一般建议将嵌套层级控制在3 - 4层以内,若超过这个范围,可以考虑通过状态管理工具(如Vuex)来简化组件间的数据传递和共享。
当父组件更新时,会触发子组件的更新生命周期钩子函数。子组件可以在beforeUpdate
和updated
钩子函数中,根据父组件传递过来的新数据进行相应的操作,比如重新计算某些依赖数据、更新DOM元素等。
在组件嵌套的场景下,调试也需要一些技巧。当发现页面显示异常或功能错误时,可以利用Vue开发者工具,通过组件树来快速定位到可能出现问题的组件层级。可以查看每个组件的props数据、data状态以及事件触发情况,从而更高效地排查问题。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF - 8" /><title>组件嵌套</title><script src="../js/vue.js"></script>
</head>
<body><div id="root"><app></app></div><script>//4创建child组件const child = {template: `<h3>child组件</h3>`,};//3创建girl组件const girl = {template: `<h2>girl组件</h2>`,};//2 创建son组件const son = {template: `<div><h2>son组件</h2><child /></div>`,components: {child,},mounted() {// 可以在这里访问子组件实例const childInstance = this.$children[0];console.log('子组件child实例:', childInstance);}};//1、创建app组件,并注册son组件和girl组件const app = {template: `<div><h1>app组件</h1><girl /><son /></div>`,components: {girl,son,},updated() {console.log('app组件更新了');}};// 创建vm,并注册app组件const vm = new Vue({el: "#root",// 1.3 使用app组件//1.2、 注册app组件components: {app,},data() {return {// 可以在这里定义一些共享数据,通过props传递给子组件sharedData: '这是来自根组件的数据'};}});</script>
</body>
在上述代码中,app
组件作为最外层组件,嵌套了girl
和son
组件,而son
组件又嵌套了child
组件。通过在组件的生命周期钩子函数中添加日志输出,可以清晰地看到组件的加载和更新顺序。在son
组件的mounted
钩子函数中,可以通过this.$children
来访问子组件实例,实现父子组件间更直接的交互。同时,app
组件中的updated
钩子函数可以在组件数据更新时触发,用于执行一些与更新相关的逻辑。
4、VueComponent & Vue
4.1、this
new Vue({})
配置项中的this
就是:Vue实例(vm)。在这个实例中,可以访问data
中的数据、调用methods
中的方法,并且其生命周期钩子函数也围绕着整个Vue应用的创建、挂载、更新和销毁过程执行。例如,在mounted
钩子函数中,可以操作DOM元素,因为此时Vue实例已经挂载到了页面上。
Vue.extend({})
配置项中的this
就是:VueComponent实例(vc)。每个通过Vue.extend
创建的组件都是一个VueComponent
实例。它也有自己的data
、methods
和生命周期钩子函数,但与Vue实例不同的是,它主要用于构建可复用的组件模块。比如在一个组件的created
钩子函数中,可以进行一些组件特定的数据初始化操作,而不会影响到其他组件。
打开vm和vc你会发现,它们拥有大量相同的属性。例如:生命周期钩子、methods、watch等。这是因为VueComponent
的设计目的就是为了复用Vue的基本功能,同时又能保持组件的独立性和可定制性。例如,无论是Vue实例还是VueComponent
实例,都可以通过watch
来监听数据的变化,并在数据变化时执行相应的逻辑。
<body><div id="app"><h1>{{msg}}</h1><user></user></div><script>// 创建组件const user = Vue.extend({template: `<div><h1>user组件</h1></div>`,mounted() {// user是什么呢????是一个全新的构造函数 VueComponent构造函数。// this是VueComponent实例console.log('vc', this)},});// vmconst vm = new Vue({el: "#app",data: {msg: "vm与vc",},components: {user,},mounted() {// this是Vue实例console.log("vm", this);},});</script>
</body>
在上述代码中,在user
组件(VueComponent
实例)的mounted
钩子函数中输出this
,可以看到其指向的是组件自身的实例,包含了组件特有的属性和方法。而在Vue实例的mounted
钩子函数中输出this
,则指向整个Vue应用的实例,包含了应用级别的数据和配置。
4.2 vm === vc ???
只能说差不多一样,不是完全相等。
例如:
vm上有el
,vc上没有。因为el
用于指定Vue实例挂载的DOM元素,而组件本身是可复用的,不应该固定在某个特定的DOM元素上。
另外data
也是不一样的。vc的data
必须是一个函数。这是为了保证每个组件实例都有独立的数据副本,避免数据共享导致的问题。
只能这么说:vm上有的vc上不一定有,vc上有的vm上一定有。因为VueComponent
继承了Vue的部分特性,同时又有自己独特的属性和行为。例如,Vue实例有$mount
方法用于手动挂载实例到DOM,而VueComponent
实例通常不需要直接调用这个方法,它会在父组件注册和使用时,由Vue框架自动处理挂载过程。
4.3 通过vc可以访问Vue原型对象上的属性
通过vc可以访问Vue原型对象上的属性:
为什么要这么设计?代码复用。Vue原型对象上有很多方法,例如:$mount()
,对于组件VueComponent
来说就不需要再额外提供了,直接使用vc调用$mount()
,代码得到了复用。
Vue框架是如何实现以上机制的呢?
VueComponent.prototype.__proto__ = Vue.prototype
1、回顾原型对象
<script>// prototype __proto__// 构造函数(函数本身又是一种类型,代表Vip类型)function Vip() {}// Vip类型/Vip构造函数,有一个 prototype 属性。// 这个prototype属性可以称为:显式的原型属性。// 通过这个显式的原型属性可以获取:原型对象// 获取Vip的原型对象let x = Vip.prototype;// 通过Vip可以创建实例let a = new Vip();// 对于实例来说,都有一个隐式的原型属性: __proto__// 注意:显式的(建议程序员使用的)。隐式的(不建议程序员使用的。)// 这种方式也可以获取到Vip的原型对象let y = a.__proto__;// 原型对象只有一个,其实原型对象都是共享的。console.log(x === y); // true// 作用:// 在给“Vip的原型对象”扩展属性Vip.prototype.counter = 1000;// 通过a实例可以访问这个扩展的counter属性吗?可以访问。为什么?原理是啥?// 访问原理:首先去a实例上找counter属性,如果a实例上没有counter属性的话,//会沿着__proto__这个原型对象去找。// 下面代码看起来表面上是a上有一个counter属性,实际上不是a实例上的属性,是a实例对应的原型对象上的属性counter。console.log(a.counter);//console.log(a.__proto__.counter)
</script>
在JavaScript中,原型链是实现对象属性和方法继承的重要机制。通过将VueComponent.prototype.__proto__
设置为Vue.prototype
,VueComponent
实例就可以访问Vue原型对象上的属性和方法,实现了代码的复用。例如,如果在Vue原型对象上定义了一个全局的工具方法,那么所有的VueComponent
实例都可以直接调用这个方法,而无需在每个组件中重复定义。
2、底层实现
VueComponent.prototype.__proto__ = Vue.prototype
<body><div id="app"><h1>{{msg}}</h1><user></user></div><script>// 创建组件const user = Vue.extend({template: `<div><h1>user组件</h1></div>`,mounted() {// this是VueComponent实例// user是什么呢????是一个全新的构造函数 VueComponent构造函数。// 为什么要这样设计?为了代码复用。// 底层实现原理:// VueComponent.prototype.__proto__ = Vue.prototypeconsole.log("vc.counter", this.counter);},});// vmconst vm = new Vue({el: "#app",data: {msg: "vm与vc",},components: {user,},mounted() {// this是Vue实例console.log("vm", this);},});// 这个不是给Vue扩展counter属性。// 这个是给“Vue的原型对象”扩展一个counter属性。Vue.prototype.counter = 1000;console.log("vm.counter", vm.counter);// 本质上是这样的:console.log("vm.counter", vm.__proto__.counter);console.log("user.prototype.__proto__ === Vue.prototype", user.prototype.__proto__ === Vue.prototype);</script>
</body>
在上述代码中,通过将counter
属性添加到Vue原型对象上,VueComponent
实例(user
组件)和Vue实例(vm
)都可以访问到这个属性。通过console.log("user.prototype.__proto__ === Vue.prototype", user.prototype.__proto__ === Vue.prototype);
可以验证VueComponent
原型对象与Vue原型对象的关联关系,这就是实现VueComponent
实例能够访问Vue原型对象属性和方法的底层机制。
相关文章:
vue:组件的使用
Vue:组件的使用 1、什么是组件 1.1、传统方式开发的应用 一个网页通常包括三部分:结构(HTML)、样式(CSS)、交互(JavaScript)。在传统开发模式下,随着项目规模的增大&a…...
leetcode日记(105)买卖股票的最佳时机Ⅱ
原本以为是一个很难想的动态规划,没想到是最简单的贪心…… 如果实在想不出就画个折线图,只买上涨的就行了,所有上涨的段都取到。 真的没想到会这么简单…… class Solution { public:int maxProfit(vector<int>& prices) {int …...
7种数据结构
7种数据结构 顺序表sqlite.hseqlite.c 单链表linklist.clinklist.h 双链表doulinklist.cdoulinklist.h 链式栈linkstack.clinkstack.h 队列SeqQueue.cSeqQueue.h 树tree.c 哈希表hash.c 顺序表 sqlite.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ typedef struct person…...
论文阅读:Deep Hybrid Camera Deblurring for Smartphone Cameras
今天介绍一篇 ACM SIGGRAPH 2024 的文章,关于手机影像中的去模糊的文章。 Deep Hybrid Camera Deblurring for Smartphone Cameras Abstract 手机摄像头尽管取得了显著的进步,但由于传感器和镜头较为紧凑,在低光环境下的成像仍存在困难&am…...
Redis 三主三从集群部署的完整方案
一、架构设计原理 分布式数据分片 哈希槽机制:Redis Cluster 将数据划分为 16384 个槽位,每个主节点负责部分槽位(如主节点1管理槽0-5460,主节点2管理5461-10922等)。 自动负载均衡:数据按哈希值分配…...
C++项目:高并发内存池_上
目录 1. 项目介绍 2. 内存池概念 2.1 池化技术 2.2 内存池和内存碎片 2.3 细看malloc 3. 定长内存池的实现 ObjectPool.hpp 4. 高并发内存池框架 5. thread cache测试 5.1 thread cache框架 5.2 ConcurrentAlloc.hpp 6. central cache测试 6.1 central cache框架 …...
『Plotly实战指南』--折线图绘制基础篇
在数据分析的世界中,折线图是一种不可或缺的可视化工具。 它能够清晰地展示数据随时间或其他变量的变化趋势,帮助我们快速发现数据中的模式、趋势和异常。 无论是金融市场分析、气象数据监测,还是业务增长趋势预测,折线图都能以直…...
【css酷炫效果】纯CSS实现波浪形分割线
【css酷炫效果】纯CSS实现波浪形分割线 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90492023 缘 创作随缘,不定时更新。 创作背景 刚看到csdn出活动了&…...
【资料分享】全志科技T113-i全国产(1.2GHz双核A7 RISC-V)工业核心板规格书
核心板简介 创龙科技SOM-TLT113 是一款基于全志科技T113-i 双核ARM Cortex-A7 玄铁C906 RISC-V HiFi4 DSP 异构多核处理器设计的全国产工业核心板,ARM Cortex-A7 处理单元主频高达1.2GHz。核心板 CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案&…...
Coco AI 智能检索 Hugo Blog 集成指南
在此前的文章中,我们介绍了如何使用 Coco Server 连接 Notion,实现智能内容检索。本次,我们将进一步探索如何在 Coco Server 最新版本 中集成 Hugo Site,以便对 Hugo 站点 进行高效检索。 Coco Server 部署方式 要在本地或服务器…...
【MySQL数据库】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法
在DQL的基础查询中,我们已经学过了多表查询的一种:联合查询(union)。本文我们将系统的讲解多表查询。 笛卡尔积现象 首先,我们想要查询emp表和stu表两个表,按照我们之前的知识栈,我们直接使用…...
jmeter将返回的数据写入csv文件
举例说明,我需要接口返回体中的exampleid与todoid的数据信息(使用边界提取器先将其提取),并将其写入csv文件进行保存 使用后置处理器BeanShell 脚本实例如下 import java.io.*;// 设置要写入的文件路径 String filePath "…...
AI如何在财务工作中提升效率的一些看法
文章目录 1. 自动化重复性任务2. 财务预测与分析3. 欺诈检测与风险管理4. 智能报表与决策支持5. 税务管理优化6. 提升团队协作与客户体验未来的趋势与挑战结论 随着人工智能(AI)技术的迅猛发展,其正全方位地革新各行各业的运作模式࿰…...
OpenCV入门指南:从安装到基本操作
引言 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它包含了数百种计算机视觉算法,广泛应用于图像处理、视频分析、物体检测、人脸识别等领域。本文将带你从安装OpenCV开始,逐步了解其基…...
简单以太网配置
display arp //查看路由器mac地址 交换机配置命令: system-view // 从用户视图进入系统视图 dis mac-address //查看mac地址表 路由器配置命令: system-view // 从用户视图进入系统视图 int GigabitEthernet 0/0/0 //进入G口 0/0/0 进入之后配置网关: ip addre…...
蓝桥杯嵌入式组第十四届省赛题目解析+STM32G431RBT6实现源码
文章目录 1.题目解析1.1 分而治之,藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 LED模块1.3.3 LCD模块1.3.4 TIM模块1.3.4.1 频率变化处理1.3.4.1 占空比计算 1.3.5 ADC模块 2.源码2.1cubemx配置3.第十四届题目 前言:STM32G431RBT6实现嵌入…...
让双向链表不在云里雾里
又来博客留下我的足迹了,哈哈哈,这次是对于双向链表的理解 目录 创建双向链表: 申请结点: 双向链表初始化: 双向链表插入结点: 双向链表删除结点: 双向链表的打印: 双向链表…...
基于django+vue的购物商城系统
开发语言:Python框架:djangoPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 热卖商品 优惠资讯 个人中心 后台登录 管理员功能界面 用户管理 商品分类管理…...
在Vue3中使用Echarts的示例
1.常用-引用ts文件方式 1.1 导出ts文件-一个简单的柱状图 export const baseBarChart (xdata: string[], data: number[][], legendData: string[]) > {if (data.length 0) {return noData;}// 定义颜色数组const color [#00CCCC,#FF9900,#1677DC,#FF6666,#B366FF,#666…...
TCP协议的多线程应用、多线程下的网络编程
DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式,一个服务端对应一个客户端,实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类,多线程接收socket对象 public class ServerSocketNable implements Run…...
每日学习Java之一万个为什么(待补充)
Git分支操作 git branch 分支名 git branch -v git checkout -b 分支名 git checkout 分支名 git merge 分支名 git branch -d | -D 分支名Git冲突 git同名文件合并的最基本单位是行。同名文件同一行不同就会发生冲突。 解决办法:及时沟通,手动更改&…...
设计C语言的单片机接口
一、主要内容 (一)控制引脚 1、定义管脚 // 定义管脚的结构体 struct pin{ int id; // 管脚编号 int mode; // 模式,输入为1,输出为0 int pull; // 输入电阻 int driver; // 功率 } 2、输出电平 语法: void pin_output(s…...
博客迁移----宝塔面板一键迁移遇到问题
前景 阿里云轻量级服务器到期了,又免费领了个ESC, 安转了宝塔面板。现在需要迁移数据,使用宝塔面板一键迁移功能,完成了数据的迁移,改了域名的解析,现在进入博客是显示502 bad grateway 宝塔搬家参考链接…...
抽象工厂模式 (Abstract Factory Pattern)
抽象工厂模式 (Abstract Factory Pattern) 是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 一、基础 1. 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 2. …...
LeetCode 第14~16题
目录 LeetCode 第14题:最长公共前缀 LeetCode 第15题:三数之和 LeetCode 第16题:最接近的三数之和 LeetCode 第14题:最长公共前缀 题目描述 编写一个函数来查找字符数组中的最长公共前缀。如果不存在公共前缀,返回字符…...
深入了解Linux —— git三板斧
版本控制器git 为了我们方便管理不同版本的文件,就有了版本控制器; 所谓的版本控制器,就是能够了解到一个文件的历史记录(修改记录);简单来说就是记录每一次的改动和版本迭代的一个管理系统,同…...
再学:abi编码 地址类型与底层调用
目录 1.内置全局变量及函数 2.abi 3.地址类型 4.transfer 1.内置全局变量及函数 2.abi data就是abi编码 abi描述:以json格式表明有什么方法 3.地址类型 4.transfer x.transfer:合约转给x call 和 delegatecall 是 Solidity 中用于底层合约调用的函数࿰…...
Redis的消息队列是怎么实现的
Redis 本身并不是一个专门的消息队列系统,但它的 List、Pub/Sub 和 Stream 数据结构可以用来实现消息队列的功能。以下是 Redis 实现消息队列的几种常见方式: 1. 基于 List 实现消息队列 Redis 的 List 是一个双向链表,支持在头部和尾部进行高效的插入和删除操作,非常适合…...
图论入门【数据结构基础】:什么是树?如何表示树?
图论是计算机科学和数学中的一个重要分支,研究图的结构及其性质。之前我们介绍了图的基本概念和表示:图论入门【数据结构基础】:什么是图?如何表示图?,本文将介绍树的基本概念、性质及其在计算机科学中的应…...
微信小程序订阅消息发送消息,点击消息进入小程序页面
1、在小程序官网订阅消息选用或创建消息模板获取模板ID可多个 如图: 2、微信小程序前端页面发送请求订阅权限 请求模板id的权限可以是一个可以是多个,用户同意订阅,获取code传递给后端——后端拿到code生成唯一的openid用于发送订阅消息 注…...
基于小参数量大语言模型(Small Language Models) ---- 在制造业落地降本增效应用:可行性研究初探
文章大纲 一、引言二、小参数量模型概述基本技术要求小参数量大语言模型在制造业场景中的适用性分析(一)排产优化(二)错误根因分析三、制造业小参数量大语言模型开源解决方案简介Bert 系列 模型Google微软MetaMistral AI国产解决方案四、技术实现方案进行逻辑(一)模型选择…...
pandas中excel自定义单元格颜色
writerpd.ExcelWriter(filepathf05教师固定学生占比1月{today}.xlsx,engineopenpyxl) df.to_excel(writer,sheet_name明细) piv1.to_excel(writer,sheet_name1月分布) wswriter.book.create_sheet(口径) ws.cell(1,1).value综合占比: ws.cell(1,2).value固定学生占比…...
MySQL事务:确保数据一致性的关键机制
目录 1. 为什么需要事务? 2. 什么是事务? 3. 事务的四大特性 3.1 原子性(Atomicity) 3.2 一致性(Consistency) 3.3 隔离性(Isolation) 3.4 持久性(Durability&…...
图论入门【数据结构基础】:什么是图?如何表示图?
图(Graph) 是一种非线性数据结构,用于表示对象之间的关系。图由 顶点(Vertex) 和 边(Edge) 组成,其中顶点表示对象,边表示对象之间的关系。图广泛应用于计算机科学、数学…...
SpringBoot中使用AJ-Captcha实现行为验证码(滑动拼图、点选文字)
简介 AJ-Captcha行为验证码,包含滑动拼图、文字点选两种方式,UI支持弹出和嵌入两种方式。后端提供Java、Golang实现,前端提供了php、angular、html、vue、uni-app、flutter、android、ios等代码示例。点击前往AJ-Captcha代码仓库 引入Maven…...
【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴!
【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴! 【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴! 文章目录 【国际研讨会】…...
AI战略家:X厂三年复盘大纲——业务与组织双视角深度拆解
一、业务负责人视角:从0到1与从1到100的核心能力模型 (一)阶段能力要求与问题预判 1. 从0到1:破局能力 核心能力升级框架: 需求洞察三阶漏斗: 行业需求池:广泛收集行业内的各种需求ÿ…...
LuaJIT 学习(4)—— FFI 语义
文章目录 C Language SupportC Type Conversion RulesConversions from C types to Lua objects例子:访问结构体成员 Conversions from Lua objects to C typesConversions between C types例子:修改结构体成员 Conversions for vararg C function argum…...
剑指 Offer II 078. 合并排序链表
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20078.%20%E5%90%88%E5%B9%B6%E6%8E%92%E5%BA%8F%E9%93%BE%E8%A1%A8/README.md 剑指 Offer II 078. 合并排序链表 题目描述 给定一个链表数组,每个链…...
go回调函数的使用
在Go语言中,回调函数可以有参数,也可以没有参数。它们的定义和使用方式略有不同,但本质上都是将函数作为参数传递给另一个函数,并在适当的时候调用它。以下是带参数和不带参数的回调函数的示例和说明。 1. 不带参数的回调函数 不…...
CBNet:一种用于目标检测的复合骨干网架构之论文阅读
摘要 现代顶级性能的目标检测器在很大程度上依赖于骨干网络,而骨干网络的进步通过探索更高效的网络结构带来了持续的性能提升。本文提出了一种新颖且灵活的骨干框架——CBNet,该框架利用现有的开源预训练骨干网络,在预训练-微调范式下构建高…...
k8s中PAUSE容器与init容器比较 local卷与hostpath卷比较
目录 一、PAUSE容器与INIT容器比较 1. Pause 容器 作用 特点 示例 2. Init 容器 作用 特点 示例 3. Pause 容器 vs Init 容器 4. 总结 这两个哪个先启动呢? 详细启动顺序 为什么 Pause 容器最先启动? 示例 总结 二、local卷与hostpath卷…...
施耐德PLC仿真软件Modbus tcp通讯测试
安装仿真软件:EcoStruxure™ Control Expert - PLC 仿真器 下载地址:https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 配置CPU: 切换至仿真模式,系统托盘中出现仿真器图标 新建变量test,地址…...
TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket
DAY13.1 Java核心基础 TCP协议 TCP 协议是面向连接的运算层协议,比较复杂,应用程序在使用TCP协议之前必须建立连接,才能传输数据,数据传输完毕之后需要释放连接 就好比现实生活中的打电话,首先确保电话打通了才能进…...
【HarmonyOS Next】常见的字节转换
【HarmonyOS Next】常见的字节转换 字节转换、位运算在实际开发中具有广泛的应用价值,特别是在处理字节级数据时发挥着重要作用。例如,在网络通信中用于大小端序转换,在数据解析时进行位提取操作。这些特性使得位运算在USB通信、蓝牙&#x…...
Redis-锁-商品秒杀防止超卖
一、秒杀(Seckill) 1. 定义 秒杀:短时间内(如1秒内)大量用户同时抢购 限量低价商品 的营销活动。典型场景:双11热门商品抢购、小米手机首发、演唱会门票开售。 2. 技术挑战 挑战点说明后果…...
RHCE(RHCSA复习:npm、dnf、源码安装实验)
七、软件管理 7.1 rpm 安装 7.1.1 挂载 [rootlocalhost ~]# ll /mnt total 0 drwxr-xr-x. 2 root root 6 Oct 27 21:32 hgfs[rootlocalhost ~]# mount /dev/sr0 /mnt #挂载 mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# [rootlo…...
KNN算法性能优化技巧与实战案例
KNN算法性能优化技巧与实战案例 K最近邻(KNN)在分类和回归任务中表现稳健,但其计算复杂度高、内存消耗大成为IT项目中的主要瓶颈。以下从 算法优化、数据结构、工程实践 三方面深入解析性能提升策略,并附典型应用案例。 一、核心性…...
安装并使用anaconda(宏观版)
conda安装 windows 安装 1 官网下载-下载地址 2 配置环境 - 安装目录 bin,script 三个填入环境变量(windows “系统属性” -> “高级系统设置” -> “环境变量” ) 这些值可以被运行在操作系统上的程序使用。它是一个通用的概念,在不同的操作系统和应用程序…...
Qwen2.5-VL 开源视觉大模型,模型体验、下载、推理、微调、部署实战
一、Qwen2.5-VL 简介 Qwen2.5-VL,Qwen 模型家族的旗舰视觉语言模型,比 Qwen2-VL 实现了巨大的飞跃。 欢迎访问 Qwen Chat (Qwen Chat)并选择 Qwen2.5-VL-72B-Instruct 进行体验。 1. 主要增强功能 1)直观地理解事物&…...