【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器(上)

news2024/11/15 15:45:04

文章目录

  • 前言
  • 一、ArkTS基本介绍
    • 1、 ArkTS组成
    • 2、组件参数和属性
      • 2.1、区分参数和属性的含义
      • 2.2、父子组件嵌套
  • 二、装饰器语法
    • 1.@State
    • 2.@Prop
    • 3.@Link
    • 4.@Watch
    • 5.@Provide和@Consume
    • 6.@Observed和@ObjectLink
      • 代码示例:
        • 示例1:(不使用@Observed和@ObjectLink)
        • 示例2:(使用@Observed和@ObjectLink)
  • 三、总结
  • 四、未完待更


前言

HarmonyOS NEXT(鸿蒙应用)开发快速入门教程ArkTS语法之装饰器篇,基于HarmonyOS NEXT Beta1版本(api 12)讲解。

本文将从前端开发者角度来理解和学习每个语法点,通过举例HarmonyOS NEXT和web端两种领域类似语法的使用,帮助前端开发人员快速入门HarmonyOS NEXT。在每个装饰器讲解上把同一个功能分别用ArkTs和vue 2种代码进行演示,使其更深刻理解每个装饰器的作用,在类比中学习记忆达到无缝衔接。


一、ArkTS基本介绍

ArkTs是鸿蒙开发主要语言,在以TS为语法基础上进行部分扩展和约束,以提升程序执行稳定性和性能。ArkTs可以看成严格模式的TS,并结合声明式UI进行页面布局。ArkTs吸收各家语言优点形成一种全新语法,在ArkTs身上我们到处都能看到web、vue、flutter、安卓等前端领域语法的身影

1、 ArkTS组成

在这里插入图片描述

说明:
1、以@开头为装饰器,装饰器都有固定英文名称,不同装饰器有着不同作用。例如@Entry表示当前组件为页面级别组件(页面路由入口),@Component声明该文件为组件 @State声明一个可引起UI响应式的变量等等
2、struct 后面跟着组件名称,固定写法,struct 类似es6 类里面关键字class, 后面的组件名称可以自定义,内部语法也类似class类语法,包括方法和属性添加
3、UI描述固定放置在build函数里面,换句话说build函数里面主要写布局代码
4、系统组件:一些系统自带的组件例如文字(Text)、按钮(Button)、输入框(TextInput)等,类似web里面dom标签,子组件通过嵌套标签写法引入,组件的属性和事件通过链式调用。

2、组件参数和属性

2.1、区分参数和属性的含义

组件标签函数入参称为组件参数,也即括号内的内容,而点后面的链式调用函数称为属性,事件和属性一样也通过链式函数调用

示例2.1:

  build() {
    Column(){
      Button('按钮')
        .type(ButtonType.Capsule)
        .onClick(()=>{
        console.log('click')
      })
    }
    .width('500px')
    .height('200px')
    .backgroundColor(Color.Black)
    }

如上述示例所示,'按钮’为组件Button入参,type为Button属性,onClick为Button点击事件,width、height、backgroundColor为组件Column属性。

所有组件都有通用属性,通用属性大部分类似web里的css属性,例如设置组件的尺寸宽高、位置、背景、透明度等。

2.2、父子组件嵌套

父组件花括号{}内写子组件,如示例2.1Column为父组件,Button为子组件,如果没有子组件可以省略{},如示例2.1的Button

示例2.1等价于如下的html写法:

    <div style="height:200px;width:500px;background:black">
      <button >按钮</button>
    </div>

二、装饰器语法

常用的装饰器语法跟vue很像,本模块将通过ArkTs示例结合web(主要vue)示例演示对比,使其更好的理解和掌握ArkTs装饰器的使用。

1.@State

@State用来装饰变量,通过@State装饰的变量改变后才能触发UI刷新,而普遍变量改变不触发UI刷新,相当于Vue3的ref

语法:@State 变量名:类型=值

//例如
@State sex:string="男"

示例:

ArkTs写法:



@Entry
@Component
struct Demo {
  @State name:string='小红'//姓名
  age:number=10//年龄

  build() {
    Column({space:10}){
      Text(`姓名:${this.name}`).fontColor(Color.Black)
      Text(`年龄${this.age}`).fontColor(Color.Black)
      Button('点击改变姓名').onClick(()=>{
         this.name='小明'
      })
      Button('点击改变年龄').onClick(()=>{
        this.age=20
      })
    }
  }
}

等价于

Vue3写法:

<template>
    <div style="display:flex;flex-direction: column;">
       <span>姓名{{name}}</span>
       <span>年龄{{age}}</span>
       <button @click="onChangeName">点击改变姓名</button>
       <button @click="onChangeAge">点击改变年龄</button>
    </div>
</template>
<script setup>
import {ref} from 'vue'
const name=ref('小红')
let age=10

const onChangeName=()=>{
   name.value='小明'
}
const onChangeAge=()=>{
   age=20
}

</script>

运行效果:
请添加图片描述

上述示例name(姓名)变量用@State修饰而age(年龄)变量为普通变量,当点击改变姓名按钮,姓名变成小红,当点击改变年龄按钮,年龄不变

2.@Prop

@Prop用来定义子组件的入参,和父组件建立单向的同步关系,相当于vue中的prop,区别在于vue中的prop不允许改变值,而鸿蒙中可以随意改变值,但是改变后的值不会同步回其父组件,也就是数据是单向传递。

语法:@Prop 变量名:类型=默认值

@Prop size:number=20

示例:

ArkTs写法:


//父组件
@Entry
@Component
struct Parent {
  @State city:string='上海'

  build() {
    Column({space:20}) {
      //引入子组件
      Child({city:this.city})
      Button('定位').onClick(()=>{
        this.city='深圳'
      })

    }
  }
}

//子组件
@Component
struct Child{
  @Prop city:string='北京' //默认值北京
  build() {
    Column({space:10}) {
      Text(`当前所处城市:${this.city}`).fontSize(20)
    }
  }
}



等价于

Vue3写法:

child.vue(子组件):

<template>
    <div>
        <span>当前所处的城市:{{city}}</span>
    </div>
</template>
<script setup>
const props=defineProps({
    city:{
        type:String,
        default:'北京'
    }
})

</script>

parent.vue(父组件):

<template>
    <div style="display:flex;flex-direction: column;">
       <Child :city="city"></Child>
       <button @click="onLocation">定位</button>
    </div>
</template>
<script setup>
import {ref} from 'vue'
import Child from './child.vue'
const city=ref('上海')
//定位点击事件
const onLocation=()=>{
  city.value='深圳'
}

</script>
<style scoped>

</style>        

运行效果:
请添加图片描述

ps:ArkTS支持在同一个文件内自定义多个组件,也可以分出去单独写子组件通过import导入

3.@Link

@Link用来定义子组件入参,和父组件建立双向绑定关系,相当于vue中的v-model,区别在于@Link是直接在子组件内修改数据源,而v-model是语法糖,本质通过事件通知父组件来改变值。

语法:@Link 变量名:类型

@Link loop:boolean

示例:

ArkTs写法:

//父组件
@Entry
@Component
struct Parent {
  @State value: string = '' //输入内容

  build() {
    Column({ space: 20 }) {
      Text(`输入框值为:${this.value}`)
      Child({ value: this.value })
    }.padding(20)
  }
}

//子组件
@Component
struct Child {
  @Link value: string //输入内容

  build() {
    //输入框
    TextInput({ text: this.value })
      .onChange((value: string) => { //输入事件监听
        this.value = value
      })
  }
}



等价于

Vue3写法:

child.vue(子组件):

<template>
    <input :value="modelValue" @input="onChange"/>
</template>
<script setup>
const props=defineProps({
    modelValue:{
        type:String,
        default:''
    }
})

const emits=defineEmits(['update:modelValue'])

//输入事件监听
const onChange=(e)=>{
    console.log(e,'e')
   emits('update:modelValue',e.target.value)
}

</script>

parent.vue(父组件):

<template>
    <div style="display:flex;flex-direction: column;">
      <span>输入框值为:{{value}}</span>
       <Child v-model="value"></Child>
    </div>
</template>
<script setup>
import {ref} from 'vue'
import Child from './child.vue'

//输入内容
const value=ref('')

</script>
<style scoped>

</style>        

运行效果:

请添加图片描述

ps:@Link修饰的变量不能设置默认值

4.@Watch

@Watch用于对状态变量的监听,当变量值变化会触发回调。相当于vue中 watch。

语法:
其他装饰器 @Watch(回调函数名) 变量名:类型=值

@Watch(回调函数名) 其他装饰器 变量名:类型=值

推荐@Watch写在其他装饰器后面

@State @Watch("onIndexChange") index:number=0
//监听值改变回调
onIndexChange(){
} 

区别和注意点:
1、@Watch无法获取旧值,相当于无vue-watch的oldValue入参
2、@Watch无法深度监听,相当vue-watch的deep属性为false
3、@Watch无法设置初始化触发,相当vue-watch的immediate属性为false
4、@Watch可监听所有装饰器装饰的状态变量。不允许监听常规变量
5、@Watch对于数组监听能力跟vue2对数组响应式监听一样能监听到push、pop、splice、shift、unshift等数组操作变化

示例:

ArkTs写法:

//父组件
@Entry
@Component
struct Demo {
  private price: number = 10 //单价
  @State @Watch('onCountChange')  count:number=1//数量
  @State total:number=10 //总价

//数量变化监听
  onCountChange(){
    this.total=this.price*this.count
  }

  build() {
    Column({ space: 20 }) {
      Text(`单价:¥${this.price}`)
      Text(`数量:x${this.count}`)
      Text(`总价:¥${this.total}`)
      Button('数量+1').onClick(()=>{
        this.count++
      })
    }.padding(20).alignItems(HorizontalAlign.Start)
  }
}

//子组件
@Component
struct Child {
  @Link value: string //输入内容

  build() {
    //输入框
    TextInput({ text: this.value })
      .onChange((value: string) => { //输入事件监听
        this.value = value
      })
  }
}



等价于

Vue3写法:

<template>
    <div style="display:flex;flex-direction: column;">
      <span>单价:¥{{price}}</span>
      <span>数量:x{{count}}</span>
      <span>总价:¥{{total}}</span>
      <button @click="onCountChange">数量+1</button>
    </div>
</template>
<script setup>
import {ref,watch} from 'vue'
//单价
const price=ref(10)
//数量
const count=ref(1)
//总价
const total=ref(10)
//数量+1
const onCountChange=()=>{
  count.value++
}
watch(count,(newValue,oldValue)=>{
 total.value=price.value*newValue
})

</script>
<style scoped>

</style>        

运行效果:

请添加图片描述

从上述例子可以看出watch回调函数中无任何入参,获取新值是通过重新访问属性值来获取,而旧值无法获取,这是第一点不足。第二点不足无法深层监听对象,第三点不足只能监听单个值变化,无法像vue3可以监听多个值。好在下一个装饰器语法版本(v2版本)将对这些不足点进行改进并支持,目前v2版本处于试用开发阶段还不成熟这里不过多介绍。

5.@Provide和@Consume

@Provide和@Consume成对使用,作用是把参数往子孙层传递,实现跨层级(多层级)传递。父组件使用@Provide修饰变量参数,子孙组件使用@Consume接收变量参数,跟vue3的Provide+Consume使用机制一样。

两种写法:

// 通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;

// 通过相同的变量别名绑定
@Provide('a') b: number = 0;
@Consume('a') c: number;

示例:

ArkTs写法:

//父组件
@Entry
@Component
struct Parent {
  @Provide('weight') weight: number = 50

  build() {
    Column({ space: 20 }) {
      Text(`父组件体重值:${this.weight}`)
      Button(`父组件体重+1`).onClick(() => {
        this.weight++
      })
      Child()
    }.padding(20).alignItems(HorizontalAlign.Start)
  }
}

//子组件
@Component
struct Child {
  build() {
    Grandson()
  }
}

//孙组件
@Component
struct Grandson {
  @Consume('weight') weight: number

  build() {
    Column({ space: 20 }) {
      Text(`孙组件体重值:${this.weight}`)
      Button(`孙组件体重+1`).onClick(() => {
        this.weight++
      })
    }.margin({ top: 50 })
  }
}

等价于

Vue3写法:

parent.vue(父组件):

<template>
   <div>
    <span>父组件体重值:{{ weight }}</span>
    <button @click="onAdd">父组件体重+1</button>
    <Child/>
   </div>
</template>

<script setup>
import { ref,provide } from "vue";
import Child from './child.vue'

const weight=ref(50)
provide('weight',weight)
const onAdd=()=>{
  weight.value++
}


</script>

child.vue(子组件):

<template>
  <Grandson/>
</template>

<script setup>
import Grandson from "./grandson .vue";
</script>

grandson.vue(孙组件)

<template>
    <div>
    <span>孙组件体重值:{{ weight }}</span>
    <button @click="onAdd">孙组件体重+1</button>
   </div>
 </template>
 
 <script setup>
 import { ref,inject } from "vue";
 const weight=inject('weight',50)
 const onAdd=()=>{
    weight.value++
 }
 </script>
 

运行效果:

请添加图片描述

ps:@Consume修饰的变量不能设置默认值

6.@Observed和@ObjectLink

对于对象类型的数据劫持鸿蒙和vue不一样,不管是@State、@Prop、@Link或者@Provide+@Consume对于对象类型的数据只能监听到最外层变化,当对象嵌套多层对象内部对象的属性值改变将无法响应UI变化,@Observed和@ObjectLink就是为了解决这个问题而设计的。

使用方法:
1、@Observed用来修饰类(也即TS对象类型),被@Observed装饰的类,可以被观察到属性的变化,每一层的类都需要用@Observed修饰才能生效。
2、@ObjectLink装饰器在子组件中使用,用于装饰@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定,也可以看成子组件的入参变量。
3、@Observed和@ObjectLink要配合自定义子组件使用才能生效,而且每嵌套一层就要抽离出一个子组件引入,简单理解就是每一层数据当入参传入子组件。

语法示例:

@Observed
class xxx{
  constructor(){
  }
}

子组件:

 @ObjectLink 变量名:类型

代码示例:

场景设计—— 假设有个学生对象数据,对象里包含姓名、性别、和成绩属性,成绩属性又是个对象,包含语文、数学、英文分数属性。通过改变学生性别和分数观察UI变化。

示例1:(不使用@Observed和@ObjectLink)
//学生对象
class Student {
  name: string //姓名
  sex: string //性别
  score: ScoreData //分数对象

  constructor(name: string, sex: string, score: ScoreData) {
    this.name = name
    this.sex = sex
    this.score = score
  }
}

//分数对象
class ScoreData {
  math: number //数学
  chinese: number //语文
  english: number //英语

  constructor(math: number, chinese: number, english: number) {
    this.math = math
    this.chinese = chinese
    this.english = english
  }
}


@Entry
@Component
struct Demo {
  //学生对象实例
   @State student:Student=new Student("王明","男",new ScoreData(80,90,75))

  build() {
    Column({space:10}) {
      Text(`姓名:${this.student.name}`)
      Text(`性别:${this.student.sex}`)
      Text(`数学成绩:${this.student.score.math}`)
      Text(`语文成绩:${this.student.score.chinese}`)
      Text(`英语成绩:${this.student.score.english}`)

      Button('改变性别').onClick(()=>{
        this.student.sex='女'
      })

      Button('改变数学成绩').onClick(()=>{
        this.student.score.math=10
      })

    }.width('100%').padding(20).alignItems(HorizontalAlign.Start)
  }
}

运行效果:
请添加图片描述
从运行效果可以看出性别变了,而数学分数未变,因为数学分数(math属性)属于对象中第二层数据,@State无法观察到多层变化,而性别(sex属性)属于第一层可以观察到变化。

示例2:(使用@Observed和@ObjectLink)
//学生对象
@Observed
class Student {
  name: string //姓名
  sex: string //性别
  score: ScoreData //分数对象

  constructor(name: string, sex: string, score: ScoreData) {
    this.name = name
    this.sex = sex
    this.score = score
  }
}

//分数对象
@Observed
class ScoreData {
  math: number //数学
  chinese: number //语文
  english: number //英语

  constructor(math: number, chinese: number, english: number) {
    this.math = math
    this.chinese = chinese
    this.english = english
  }
}


@Entry
@Component
struct Demo {
  //学生对象实例
  @State student: Student = new Student("王明", "男", new ScoreData(80, 90, 75))

  build() {
    Column({ space: 10 }) {
      Text(`姓名:${this.student.name}`)
      Text(`性别:${this.student.sex}`)
      ScoreView({
        data: this.student.score
      })

      Button('改变性别').onClick(() => {
        this.student.sex = '女'
      })

      Button('改变数学成绩').onClick(() => {
        this.student.score.math = 10
      })

      Button('改变语文成绩').onClick(() => {
        this.student.score.chinese--
      })

    }.width('100%').padding(20).alignItems(HorizontalAlign.Start)
  }
}

//子组件
@Component
struct ScoreView {
  @ObjectLink data: ScoreData //分数对象

  build() {
    Column() {
      Text(`数学成绩:${this.data.math}`)
      Text(`语文成绩:${this.data.chinese}`)
      Text(`英语成绩:${this.data.english}`)
    }
  }
}

运行效果:

请添加图片描述

从运行效果可以看出,因为使用了@Observed和@ObjectLink,所以修改第二层数据(数学和英文成绩)都会响应UI变化。

小结:

通过上面示例演示来看,鸿蒙对嵌套对象场景的开发显得力不从心,如果数据对象是n层就需要自定义n-1个子组件来传递每一层的数据,特别麻烦。好在官方已经注意到这些不足,在下个版本(v2版)提供的新的装饰器@ObservedV2+@Trace解决对象嵌套问题,v2版本目前处于开发试用阶段还没正式发布,这里不过多介绍,有兴趣可以自行查阅官网文档。

ps:对于多层嵌套场景不单单指对象中嵌套对象,还包括对象中嵌套数组或者数组中嵌套对象,因为在js世界里数组也是对象类型。


三、总结

上述6种装饰器语法是开发中比较高频率使用的装饰器,可以看出除了第六个剩下的都可以在vue中找到对应的语法,使用上几乎一样,所以从事前端开发特别是vue技术栈的开发人员可以快速无缝衔接。

四、未完待更

除了上述6种常用装饰器,ArkTs还有一些其他比较重要装饰器,将在下篇博文继续介绍。。。。。。

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

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

相关文章

Windows11家庭版修改用户密码策略为永不过期。

今天有个朋友找到我说&#xff0c;他的电脑密码老是过期然后需要修改&#xff0c;让我帮忙改一下密码策略&#xff0c;改为永不过期。 下面就来操作一下吧。 这里有个小小的坑&#xff0c;就是win11的家庭版是没有 gpedit.msc的&#xff0c;也就不能直接cmd打开本地策略便器&…

【WebGis开发 - Cesium】获取视野中心点,并设置顶视图视角

引言 项目开发过程中遇到一个需求&#xff0c;通过一个按钮切换视角为顶视图。 分析了一下这个模糊的需求&#xff0c;首先没有给出切换顶视图后俯视的区域范围&#xff0c;其次没有给出俯视点的高度。 这里可以粗略的认为当前的侧俯视的角度下观看的范围即为俯视的区域范围&am…

视频美颜SDK核心功能解析:打造高效直播美颜工具方案详解

随着直播行业的迅猛发展&#xff0c;用户对于直播画质和个人形象的要求越来越高。视频美颜SDK作为一项关键技术&#xff0c;已经成为各大直播平台和短视频应用的重要组成部分。通过实时美颜技术&#xff0c;用户能够在直播过程中呈现出更加理想的形象&#xff0c;从而提升直播体…

实验一:Windows下的IIS服务器配置和管理

第一次实验隐藏关很多&#xff0c;稍不留神服务器就寄了。 实验一完成后会有联网问题&#xff0c;问题解决详见番外篇。 实验内容 任务一&#xff1a; 1、建立一个基于主机名www.study.com的站点&#xff0c;站点的主目录为C:\inetpub\wwwroot&#xff0c;给站点建立一个虚拟…

Codeforces Round 973 (Div. 2) F1. Game in Tree (Easy Version)(思维题 博弈)

题目 思路来源 乱搞ac 题解 两个人的策略是一样的&#xff0c;把1到u的路径标记&#xff0c; 如果能走旁边的链&#xff08;也就是当前点&#xff0c;刨去标记链以外的子树中最长的链&#xff09;&#xff0c; 使得对面走剩余的连通块无法比你大&#xff0c;就走旁边的链&…

业务资源管理模式语言16

示例&#xff1a; 图25 描述了PayForTheResourceTransaction 的一个实例。其中&#xff0c;“Sale”扮演“Resource Transaction”&#xff0c;“Accounts Receivable”扮演“Payment”。 图25——PayForTheResourceTransaction 模式实例 相关模式&#xff1a; PayForTheRes…

特殊类的设计与类型转换

特殊类的设计 1.请设计一个不能被拷贝的类 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c;只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 C98 C98是怎么设计的呢&#xff1f; class Cop…

从零开始讲DDR(3)——DDRC与DDRPYH

一、DDR的使用 在之前的文章中我们介绍了DDR的基本概念&#xff0c;但是DDR内存的操作不仅仅是简单的数据读取和写入&#xff0c;它包括许多时序要求和信号调度。为了让DDR内存有效运作&#xff0c;系统需要在逻辑层和物理层之间进行大量的协作。我们拿出一张DDR的操作简化状态…

MySQL程序

目录 MySQL程序 常用的MySQL的程序 mysqld程序 mysql客户端 客户端命令的常用的选项 配置文件 配置文件语法 MySQL客户端命令 ​编辑 .sql 文件中执行SQL语句 mysqlcheck &#xff08;表维护程序&#xff09; Mysqldump&#xff08;数据库备份程序&#xff09; mysql…

单片机项目合集列表——Excel合集列表目录查阅(持续更新)

阿齐Archie《单片机项目合集》专栏项目 为方便查找本专栏的项目&#xff0c;特整理Excel合集列表供查阅&#xff08;可搜索或按系列查找&#xff09; 持续更新链接如下&#xff1a; 阿齐单片机项目合集 (kdocs.cn)https://www.kdocs.cn/l/cmrxCxJN05YN 打开链接如下Exce表所…

【开源免费】基于SpringBoot+Vue.JS网上购物商城(JAVA毕业设计)

本文项目编号 T 041 &#xff0c;文末自助获取源码 \color{red}{T041&#xff0c;文末自助获取源码} T041&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

代码随想录Day50|图论Part01,leetcode题目:98. 所有可达路径

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 图论理论基础Part01图的基本概念图的种类 连通性连通图强连通图连通分量强连通分量 图的构造邻接矩阵邻接表 图的遍历方式 深度优先搜索理论基础DFS 与 BFS 区别dfs 搜索过程代码框架深搜三部曲为…

Superset 使用指南之优化数据可视化性能与扩展

1. Superset 概述 什么是 Apache Superset&#xff1f; Apache Superset 是一个开源、现代化的数据可视化和数据探索平台。它通过提供直观的用户界面&#xff0c;使用户能够轻松创建复杂的图表和仪表板&#xff0c;探索海量数据&#xff0c;同时避免传统商业智能&#xff08;…

Apache James配置连接达梦数据库

项目场景&#xff1a; Apache James配置连接达梦数据库&#xff0c;其他配置中不存在的数据库也可参考此方案。 配置步骤 1、把需要的jar包导入到James 把DmJdbcDriver18.jar复制到下面lib目录下 james-2.3.2\lib 2、 修改连接配置 james-2.3.2\apps\james\SAR-INF\confi…

k8s部署jenkins集群时,使用ThinBackup进行定期备份

一、背景 使用k8s部署jenkins集群的时候&#xff0c;一般会把$JENKSIN_HOME&#xff08;默认是/var/jenkins_home&#xff09;进行持久化。 volumeMounts:- name: jenkins-homemountPath: /var/jenkins_home这样&#xff0c;机器重启&#xff0c;保证不会丢失文件。 本文要讲…

杀死端口占用的进程

1、查看端口的进程&#xff0c;以9023为例 &#xff08;1&#xff09;方法1 netstat -tunpl|grep 9023 &#xff08;2&#xff09;方法2 ss -tulpan |grep 9023 &#xff08;3&#xff09;方法3 netstat -ntlp |grep 9023 &#xff08;4&#xff09;方法4 lsof -i:9023 …

Linux:虚拟文件系统/proc和self进程

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 /proc目录 在Linux操作系统中&#xff0c;目录/proc是一个虚拟文件系统&#xff0c;称为procfc&#xff0c;用于访问内核和系统的实时状态信息。这个文件系统不同于常规…

下载 B 站封面的正确方式

B 友们经常用一些很好看的图片作为视频封面&#xff0c;但是大部分都不会指出图片来源&#xff0c;为此我们可以下载封面原图&#xff0c;用于保存或者搜索源出处。 这里介绍几个我知道的方法&#xff0c;欢迎补充&#x1f914; ‍ 使用相关客户端 上一篇博客介绍了很多的能…

基于微型5G网关的酒店服务机器人应用

智能机器人在酒店中已经越来越常见&#xff0c;并且也是提升客户体验、提高服务效率的重要工具。然而&#xff0c;尽管这些机器人在自动化服务方面可以发挥着重要作用&#xff0c;但它们仍然面临着一些通信、组网和在线管理方面的痛点。 针对这些难题&#xff0c;可以通过部署微…

【数据结构入门】排序算法之三路划分与非比较排序

文章目录 前言 一、三路划分优化 1.1. 基本思想 1.2. 实现步骤 1.3. 优点 1.4 代码实现 二、非比较排序 2.1 计数排序 2.1.1基本思想 2.1.2具体步骤 2.1.3算法特性 2.1.4算法实现 2.2 基数排序 2.2.1基本思想 2.2.2具体步骤 2.2.3 基数排序的方法 2.2.4算法特…