【Vue-组件】学习笔记

news2025/7/14 4:41:03

目录

  • <<回到导览
  • 组件
    • 1.项目
      • 1.1.Vue Cli
      • 1.2.项目目录
      • 1.3.运行流程
      • 1.4.组件的组成
      • 1.5.注意事项
    • 2.组件
      • 2.1.组件注册
      • 2.2.scoped样式冲突
      • 2.3.data是一个函数
      • 2.4.props详解
      • 2.5.data和prop的区别
    • 3.组件通信
      • 3.1.父子通信
        • 3.1.1.父传子(props)
        • 3.1.2.子传父($emit)
      • 3.2.非父子通信
        • 3.2.1.事件总线
        • 3.2.2.provide-inject
      • 3.3.v-model详解
      • 3.4.sync修饰符(已废弃)
      • 3.5.(重点)ref和$refs
      • 3.6.ref和$refs选择器
      • 3.7.$nextTick
    • 4.自定义指令
      • 4.1.指令的值
      • 4.2.封装v-loading指令
    • 5.插槽
      • 5.1默认插槽
      • 5.2.后备内容
      • 5.3.具名插槽
      • 5.4.作用域插槽
    • 6.my-tag组件封装

<<回到导览

组件

1.项目

1.1.Vue Cli

官方提供的一个全局命令工具,可以快速生成vue项目的标准化基础架子(集成webpack),开箱即用

使用步骤:

  1. 全局安装(安装一次即可)

    yarn global add @vue/cli
     // 或者
    npm i @vue/cli -g
    
  2. 查看vue/cli版本:

    vue --version
    
  3. 创建项目架子:

    vue create project-name
    
  4. 启动项目:

     yarn serve
     // 或者
     npm run serve
    

启动项目的命令并不固定,其取决于package.json文件
在这里插入图片描述

1.2.项目目录

在这里插入图片描述

  • 第三包文件夹(依赖)被删除,只要package.json还存在,就可以安装回来

    npm i --force 或者 npm i --legacy-peer-deps

1.3.运行流程

在这里插入图片描述

1.4.组件的组成

  • 语法高亮插件

在这里插入图片描述

  • 三部分构成

    • template:结构 (有且只能一个根元素),在template中,最外层标签只能为div盒子
    • script: js逻辑
    • style: 样式 (可支持less,需要装包)
  • 让组件支持less

    1. style标签,lang=“less” 开启less功能
    2. 装包:
      yarn add less less-loader -D 
      // 或者
      npm i less less-loader -D
      

1.5.注意事项

  1. 在组件的template中,最外面必须有一个div盒子

  2. 组件名称最好采用大驼峰命名法,且至少两个驼峰

  3. 有时候有些错误改正后依旧报错(列如上面第二个报错),重新启动项目即可

  4. 启动项目时在项目的根目录下启动(我们项目根目录叫luyou)

2.组件

2.1.组件注册

  • 局部注册

    1. 在components文件夹创建组件 xxx.vue

    2. 在根组件App.vue导入

      // 导入组件
      // import xxx from 'xxx.vue的文件路径'
      import HmHeader from './components/HmHeader'
      
      export default{
          // 局部注册
          components:{
              // '组件名':组件对象,
              // HmHeader:HmHeader  同名可简写
              HmHeader
          }
      }
      
  • 全局注册

    1. 在components文件夹创建组件 xxx.vue

    2. 在main.js进行全局注册

      // 导入组件
      // import xxx from 'xxx.vue的文件路径'
      import HmHeader from './components/HmHeader'
      
      // 调用Vue.component进行全局注册
      // Vue.component('组件名',组件对象)
      Vue.component('HmHeader',HmHeader)
      

    一般都用局部注册,如果发现是通用组件,再注册为全局

2.2.scoped样式冲突

  • 默认组件中的样式会全局生效

  • 可以给组件加上scoped属性,可以让样式只作用于当前组件

    <style scoped></style>
    

scoped的原理:

  1. 组件被都添加 data-v-hash (添加自定义属性)
  2. css选择器添加 [data-v-hash] (添加自定义属性的属性选择器)

2.3.data是一个函数

在最开始的vue基本语法学习中,data被写为data: {},键值(值为对象,对象又嵌套键值数据)

但在组件开发中,data选项必须是一个函数

data(){
    return {
        // 数据
    }
}
  • 这是因为组件具有复用性,在同一个组件的复用过程中,data里的数据应该不一样,且数据不相互影响

  • 将data设置为一个函数,将数据写进return返回值中,每次创建组件都会调用data函数,返回一个独立数据对象,这些独立的对象分别用于保存同一组件的不同次使用的数据。
    在这里插入图片描述

2.4.props详解

  • 定义:在组件使用时,注册的一些自定义属性

  • 作用:向子组件传递数据

  • 示例

    export default {
      props: ['w'],
    }
    

    在为子组件传递数据时,我们应该为组件的 prop 指定验证要求

    props: {
      校验的属性名: {
        type: 类型,  // Number String Boolean ...
        required: true, // 是否必填
        default: 默认值, // 默认值
        validator (value) {
          // 自定义校验逻辑
          return 是否通过校验
        }
      }
    },
    
    • default和required一般不同时写
    • default后面如果是复杂类型,则需要以函数的形式return一个默认值

    示例

    props: {
        w: {
          type: Number,
          //required: true,
          default: 0,
          validator(val) {
            if (val >= 100 || val <= 0) {
              console.error('传入的范围必须是0-100之间')
              return false
            } else {
              return true
            }
          },
        },
      },
    

2.5.data和prop的区别

  • data 的数据是自己的 → 随便改
  • prop 的数据是外部的 → 不能直接改,要遵循 单向数据流

单向数据流:父级props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的

3.组件通信

上面讲到,data是一个函数,同一组件的不同的使用之间数据独立,同样,不同组件之间数据也不共享
在这里插入图片描述

3.1.父子通信

在这里插入图片描述

3.1.1.父传子(props)
  • 父组件通过 props 将数据传递给子组件

    1. 在父组件中的子组件标签添加动态属性(App.vue)

      <MySon :title="say"></MySon>
      
    2. 子组件通过props进行接收

      export default {
        data() {
          return {};
        },
        props: ["title"],
      };
      
3.1.2.子传父($emit)
  • 子组件利用 $emit 通知父组件修改更新

    1. 给父组件元素添加事件和处理方法

      <button @click="changeFn">say</button>
      
      changeFn() {
          // change为后面为子组件添加的事件名
          // "Hello"为要修改的值,也就是后面的形参newSay
          // 并不一定要传字符串,也可以将"Hello"改为变量传递
          this.$emit("change", "Hello");
      },
      
    2. 触发事件后,利用$emit将父组件发送改变数据的通知

    3. 在父组件中的子组件标签添加事件,调用修改属性的方法

      <MySon :title="say" @change="changeFn"></MySon>
      
      // 形参newSay为传递过来的值"Hello"
      changeFn(newSay) {
          this.say = newSay;
      },
      

3.2.非父子通信

3.2.1.事件总线

概念:创建创建一个都能访问的事件总线,发送方向事件总线发送,

接收方向事件总线发送监听

  1. 在src文件夹下创建一个utils文件夹,在该文件夹下创建一个js文件

  2. 创建一个空Vue实例(事件总线)

    import Vue from 'vue'
    const Bus = new Vue()
    export default Bus
    
  3. 接受方和发送方都将数据总线引入

    import Bus from '../utils/EventBus'
    
  4. A组件(发送方),触发Bus的$emit事件

    // 'sendMsg为发送的数据的标识
    Bus.$emit('sendMsg', '这是一个消息')
    
  5. B组件(接受方),监听Bus的 $on事件

    created () {
      // 形参msg为传递的信息('这是一个消息')
      Bus.$on('sendMsg', (msg) => {
        this.msg = msg
      })
    }
    
3.2.2.provide-inject

作用:跨层级共享数据
在这里插入图片描述

  1. 父组件 provide提供数据

    export default {
      provide () {
        return {
           // 普通类型【非响应式】
           color: this.color, 
           // 复杂类型【响应式】
           userInfo: this.userInfo, 
        }
      }
    }
    
  2. .子/孙组件 inject获取数据

    export default {
      inject: ['color','userInfo'],
      created () {
        console.log(this.color, this.userInfo)
      }
    }
    
  • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据
  • 子/孙组件通过inject获取的数据,不能在自身组件内修改

3.3.v-model详解

  • v-model本质上是一个语法糖。例如应用在输入框上,就是value属性 和 input事件 的合写

    <template>
      <div id="app" >
        <input v-model="msg" type="text">
        <!-- 等价于 -->
        <!-- 数据变,视图跟着变 :value -->
        <!-- 视图变,数据跟着变 @input -->
        <input :value="msg" @input="msg = $event.target.value" type="text">
      </div>
    </template>
    
  • $event 用于在模板中,获取事件的形参

  • $event.target.value即获取输入框的值

  • 将输入框的值赋值给data里的数据msg,再将msg通过:value赋值给输入框,从而实现数据的双向绑定。

注意

  1. 不同的表单元素, v-model在底层的处理机制是不一样的。

    比如给checkbox使用v-model,底层处理的是:checked属性和@change事件。

  2. v-model不能直接绑定父组件传过来的数据,因为父组件通过prop属性传过来的数据不能直接修改。

3.4.sync修饰符(已废弃)

  • 在上面的父子通信中,子组件不能直接修改父组件数据,而是通过$emit间接修改

  • 通过sync修饰符,子组件可以修改父组件传过来的props值

  • 以上面的父子通信为例

    父组件

    <!-- 完整写法 -->
    <MySon :title="say"  @update:title="isShow = $event" ></MySon>
    
    <!-- 简写 -->
    <MySon :title.sync="say"></MySon>
    

    子组件

    props: {
      title: Boolean
    },
    this.$emit('update:title', 'Hello')
    

3.5.(重点)ref和$refs

  • 利用ref 和 $refs 可以用于 获取 dom 元素组件实例(要在dom渲染完后才能获取)

  • 获取元素还可以通过document.querySeletctor()获取,但是此方法是从整个页面开始获取

    • 类名问题:比如我们在子组件中获取类名为app的元素,如果在此组件之前还有类名为app的元素,则会获取之前的类名为app的元素
    • 解决方法:如果我们利用ref 和 $refs 可以用于 获取 dom 元素,则会从当前组件开始获取,避免类名问题。
  • 示例

    1. 给要获取的盒子添加ref属性

      <div ref="demo">我是渲染图表的容器</div>
      
    2. 通过 this.$refs.demo 获取

      mounted(){
        console.log(this.$refs.demo)
      }
      

3.6.ref和$refs选择器

  • 利用ref 和 $refs 还可以用于 组件实例

    1. 在组件示例上,添加ref属性

      <MySon ref="demo" ></MySon>
      
    2. 通过 this.$refs.demo 获取,控制台会打印组件对象

      mounted(){
        console.log(this.$refs.demo)
        // 控制台
        // VueComponent {_uid: 2, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}
      }
      
    3. 我们可以通过this.$refs.demo.子组件方法名调用子组件方法,或者访问子组件属性,实现组件通信。

      注意:这种组件通信只是调用了子组件方法或者访问子组件属性,没有实现双向绑定

3.7.$nextTick

  • $nextTick用于实现vue的异步更新

  • 应用案例:编辑标题, 编辑框自动聚焦

    1. 效果:点击编辑,显示编辑框,并且让编辑框,立刻获取焦点

    2. 预想代码

      this.isShowEdit = true		// 显示输入框
      this.$ref.input.focus()		// 获取焦点
      
    3. 预想代码并不能实现该效果,因为:

      • 当执行显示输入框代码后,没等dom渲染出显示框,就执行到获取焦点的代码了(因为dom是异步更新),我们可以用$nextTick用于实现vue的异步更新。
      • vue异步更新的原因是提高性能,当点击编辑按钮的@click绑定的事件执行完毕后,才会更新视图,这样避免每执行完一行代码就更新一次视图。
    4. 利用$nextTick实现以上代码的异步更新

      this.isShowEdit = true		// 显示输入框
      this.$nextTick(() => {
        this.$refs.inp.focus()	// 获取焦点
      })
      
      • 当执行到$nextTick时,会更新渲染一次dom,输入框渲染出来,再向下执行代码
      • 说到dom异步更新,很多人想到利用延时器实现,但是延时器延迟时间是固定的,而执行到dom渲染的时间并不固定(和网络、设备性能有关)。

    注意:

    ​ $nextTick 内的函数体 一定是箭头函数,这样才能让函数内部的this指向Vue实例

4.自定义指令

  • 与$nextTick类似,inserted会在指令所在元素被插入页面时触发
  • 全局注册(下面以注册实现上面点击聚焦功能为例)

    //在main.js中
    Vue.directive('focus', {
      // el为指令绑定的元素 
      "inserted" (el) {
        el.focus()
      }
    })
    
  • 局部注册

    //在Vue组件的配置项中
    directives: {
      "focus": {
        inserted (el) {
          el.focus()
        }
      }
    }
    
  • 指令使用

    <input v-focus ref="inp" type="text">
    

4.1.指令的值

与vue内置指令相同,我们也可以为自定义指令设置值

  • 示例:我们定义一个v-color指令,v-color的值变化时,带有v-color指令的标签也会变化

  • 指令注册(局部注册)

    directives: {
      color: {
        inserted (el, binding) {
          el.style.color = binding.value
        },
        update (el, binding) {
          el.style.color = binding.value
        }
      }
    }
    
    1. binding.value为指令值
    2. 指令值修改会触发update函数(update也是一个生命周期钩子)
    3. 我们指令的值可以设置为变量,这时我们就需要设置update函数

4.2.封装v-loading指令

  • 在加载时,页面通常会有一个loading动画效果

  • 这个效果通常为一个蒙层(蒙层一般为伪元素)

  • loading的开启和关闭只需要添加移除类即可(因为伪元素是css生成的,自然也可以通过操作css移除)

    示例

    <template>
      <div class="main">
        <div class="box" v-loading = "isLoading">
          <ul>
            <li v-for="item in list" :key="item.id" class="news">
              <div class="left">
                <div class="title">{{ item.title }}</div>
                <div class="info">
                  <span>{{ item.source }}</span>
                  <span>{{ item.time }}</span>
                </div>
              </div>
              <div class="right">
                <img :src="item.img" alt="">
              </div>
            </li>
          </ul>
        </div>
      </div>
    </template>
    
    <script>
        import axios from 'axios'
    
        export default {
          data () {
            return {
              list: [],
              isLoading: true
            }
          },
          async created () {
            const res = await axios.get('http://hmajax.itheima.net/api/news')
            setTimeout(() => {
              this.list = res.data.data
              // 移除蒙层
              this.isloading = false
            }, 2000)
          },
          // 定义指令
          directives: {
              loading: {
                inserted (el, binding) {
                  binding.value?el.classList.add('loading'):el.classList.remove('loading')
                },
                update (el, binding) {
                  binding.value?el.classList.add('loading'):el.classList.remove('loading')
                }
              }
          }
        }
    </script>
    
    <style>
        /* 伪元素 */
        .loading:before {
          content: '';
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background: #fff url('./loading.gif') no-repeat center;
        }
        .box2 {
          width: 400px;
          height: 400px;
          border: 2px solid #000;
          position: relative;
        }
        .box {
          width: 800px;
          min-height: 500px;
          border: 3px solid orange;
          border-radius: 5px;
          position: relative;
        }
        .news {
          display: flex;
          height: 120px;
          width: 600px;
          margin: 0 auto;
          padding: 20px 0;
          cursor: pointer;
        }
        .news .left {
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          padding-right: 10px;
        }
        .news .left .title {
          font-size: 20px;
        }
        .news .left .info {
          color: #999999;
        }
        .news .left .info span {
          margin-right: 20px;
        }
        .news .right {
          width: 160px;
          height: 120px;
        }
        .news .right img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
    </style>
    

    知识点:

    • 安装axios yarn add axios npm i axios

    • 定义指令部分:

      directives: {
          loading: {
              inserted (el, binding) {
                  // 如果加载,显示蒙层(移除loading类),否则,显示蒙层
                  binding.value?el.classList.add('loading'):el.classList.remove('loading')
              },
              update (el, binding) {
                  binding.value?el.classList.add('loading'):el.classList.remove('loading')
              }
          }
      }
      
  • v-loading工作流程:有些同学看到这里可能有些疑问,组件定义里面的函数是什么时候执行的?

    1. 上面有提到,inserted会在指令所在元素被插入页面时触发
    2. 在上面示例中,先执行created生命周期钩子,向服务器发送获取数据请求,然后再将返回数据更新到 list 中,并改变isLoading

5.插槽

5.1默认插槽

  • 让组件内部的一些 结构 支持 自定义

  • 语法

    1. 组件内需要定制的结构部分,改用<slot></slot>占位
    2. 给插槽传入内容时,可以传入纯文本、html标签、组件
    3. 在标签内部, 传入结构替换slot
  • 示例:弹框插槽

    在这里插入图片描述

    在这里插入图片描述

5.2.后备内容

上面示例中,如果不传内容,则会不会显示

在这里插入图片描述

我们可以为插槽设置默认显示内容,如果不传内容,则会显示默认显示内容

  • 我们只需要在封装组件时,为预留的 <slot> 插槽提供后备内容即可(默认内容)

在这里插入图片描述

5.3.具名插槽

一个组件中,很多时候不单单只有一个插槽,这时我们需要使用name属性区分不同插槽。

  • 使用name属性区分不同插槽。

  • template配合v-slot:名字来分发对应标签

  • 为方便书写,上面可以将 v-slot: 替换为 #

    在这里插入图片描述

示例

  1. 根组件(App.vue)

    <div id="app">
        <HelloWorld>
          <template #age>年龄</template>
          <template #name>姓名</template>
          <template #gender>性别</template>
        </HelloWorld>
    </div>
    
  2. 子组件(HelloWorld.vue)

    <div>
    	<slot name="name"></slot>
        <hr />
        <slot name="age"></slot>
        <hr />
        <slot name="gender"></slot>
    </div>
    

    显示顺序取决于子组件的插槽位置

5.4.作用域插槽

  • 作用域插槽不属于插槽的一种分类

  • 定义slot插槽的同时,可以传值,给插槽绑定数据,这些数据与插槽绑定的组件也可以使用

    1. 给 slot 标签, 以 添加属性的方式传值(组件中)

      <slot :id="item.id" msg="测试文本"></slot>
      
    2. 在template中, 通过 #插槽名= "obj" 接收,默认插槽名为 default(根组件中)

      <MyTable :list="list">
        <template #default="obj">
          <button @click="del(obj.id)">删除</button>
        </template>
      </MyTable>
      
  • 所有添加的属性, 都会被收集到一个对象中,我们也可以将这个对象结构来使用

    <MyTable :list="list">
      <template #default="{id, msg}">
        <button @click="del(id)">删除</button>
      </template>
    </MyTable>
    

6.my-tag组件封装

实现功能

  1. 双击显示,自动聚焦
  2. 失去焦点,隐藏输入框
  3. 回显标签内容
  4. 内容修改,回车,修改标签信息

代码

  1. MyTag

    <template>
      <div class="my-tag">
        <input
          v-if="isEdit"	
          v-focus
          class="input"
          type="text"
          placeholder="输入标签"
          :value="value"
          @blur="isEdit = false"
          @keyup.enter="handleEnter"
        />
        <div 
          v-else
          @dblclick="handleClick"
          class="text">
          {{ value }}
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        value: String
      },
      data () {
        return {
          isEdit: false
        }
      },
      methods: {
        handleClick () {
          // 双击后,切换到显示状态 (Vue是异步dom更新)
          this.isEdit = true
        },
        handleEnter (e) {
          // 非空处理
          if (e.target.value.trim() === '') return alert('标签内容不能为空')
          // 由于父组件是v-model,触发事件,需要触发 input 事件
          this.$emit('input', e.target.value)
          // 提交完成,关闭输入状态
          this.isEdit = false
        }
      }
    }
    </script>
    
    <style lang="less" scoped>
    .my-tag {
      cursor: pointer;
      .input {
        appearance: none;
        outline: none;
        border: 1px solid #ccc;
        width: 100px;
        height: 40px;
        box-sizing: border-box;
        padding: 10px;
        color: #666;
        &::placeholder {
          color: #666;
        }
      }
    }
    </style>
    
  2. App.vue

    <template>
      <div>
           <MyTag v-model="item.tag"></MyTag>     
      </div>
    </template>
    
    <script>
    import MyTag from './components/MyTag.vue'
        
    export default {
      name: 'TableCase',
      components: {
        MyTag,
      },
      data () {
        return {
          // 测试组件功能的临时数据
          tempText: '水杯',    
        }
      }
    }
    </script>
    
    <style lang="less" scoped>
    .table-case {
      width: 1000px;
      margin: 50px auto;
      img {
        width: 100px;
        height: 100px;
        object-fit: contain;
        vertical-align: middle;
      }
    }
    
    </style>
    
  3. main.js

    import Vue from 'vue'
    import App from './App.vue'
    Vue.config.productionTip = false
    
    // 封装全局指令 focus
    Vue.directive('focus', {
      // 指令所在的dom元素,被插入到页面中时触发
      inserted (el) {
        el.focus()
      }
    })
    
    new Vue({
      render: h => h(App),
    }).$mount('#app')
    

知识点

  • 双击触发事件:@dblclick

  • 两种自动聚焦方法

    在实现点击盒子切换为inpu标签并自动聚焦时,我们可以通过ref和refs操作dom,再配合$nextTick异步实现,不过为了提高复用性,我们通过自定义指令,封装到mian.js实现该功能

  • 指令修饰符实现回车事件监听,@keyup.enter,由于该案例数据是由父组件传递过来的,所以还要将该值发送给父组件

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

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

相关文章

(PROFINET 转 EtherCAT)EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

型号 协议转换通信网关 PROFINET 转 EtherCAT MS-GW31 概述 MS-GW31 是 PROFINET 和 EtherCAT 协议转换网关&#xff0c;为用户提供两种不同通讯协议的 PLC 进行数据交互的解决方案&#xff0c;可以轻松容易将 EtherCAT 网络接入 PROFINET 网络中&#xff0c;方便扩展&…

关于sqlsugar实体多层List映射的问题

如上图所示&#xff0c;当一个主表&#xff08;crm_fina_pay_req&#xff09;的子表list<文件附件关系表>&#xff08; List<crm_fina_payreq_evidofpay_relation> &#xff09;中&#xff0c;还包含有sysfile&#xff08;SysFile SysFiles&#xff09;类型的文件信…

STM32 HAL库 CANFD配置工具

用法说明&#xff1a; 该工具适用于STM32HAL库&#xff0c;可一键生成CANFD的HAL库配置代码。计算依据为HAL库&#xff0c;并参考ZLG标准。 软件界面&#xff1a; 仓库地址&#xff1a; HAL CANFD Init Gen: 适用于STM32控制器的HAL库 版本说明&#xff1a; V1.2.0 &#x…

UIMeter-UI自动化软件(产品级)

前言&#xff1a;作为一个资深测试工程师&#xff0c;UI测试&#xff0c;webUI自动化测试是我们必备的技能&#xff0c;我们都知道常用的框架比如selenium、playwright、rebootframwork等等&#xff0c;但是无论哪一种框架&#xff0c;都需要测试人员去编写代码&#xff0c;进行…

企业级Java开发工具MyEclipse v2025.1——支持AI编码辅助

MyEclipse一次性提供了巨量的Eclipse插件库&#xff0c;无需学习任何新的开发语言和工具&#xff0c;便可在一体化的IDE下进行Java EE、Web和PhoneGap移动应用的开发&#xff1b;强大的智能代码补齐功能&#xff0c;让企业开发化繁为简。 立即获取MyEclipse v2025.1正式版 具…

【redis】简介及在springboot中的使用

redis简介 基本概念 Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 与MySQL数据库不…

隐私计算的崛起:数据安全的未来守护者

在信息技术&#xff08;IT&#xff09;的滚滚浪潮中&#xff0c;一种新兴技术正以惊人速度崭露头角——隐私计算&#xff08;Privacy-Preserving Computation&#xff09;。2025 年&#xff0c;随着数据泄露事件频发、全球隐私法规日益严格&#xff0c;以及企业对数据协作需求的…

【Vue-vue基础知识】学习笔记

目录 <<回到导览vue基础知识1.1.创建一个vue实例1.2.vue基础指令1.2.1.v-bind1.2.2.v-model1.2.3.常用事件1.2.4.指令修饰符 1.3.计算属性1.3.1.计算属性的完整写法1.3.2.【案例】成绩 1.4.watch1.4.1.watch属性1.4.2.翻译业务实现1.4.3.watch属性的完整写法1.4.4.【案例…

【Linux网络】网络套接字socket

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12891150.html 目录 Socket 编程预备 理解源 IP 地址和目的 IP 地址 认识端口号 端口号范围划分…

tomcat的负载均衡和会话保持

写你的想写的东西&#xff0c;写在tomcat的默认发布目录中 这里写了一个jsp的文件 访问成功 可以用nginx实现反向代理 tomcat负载均衡实现&#xff1a; 这里使用的算法是根据cookie值进行哈希&#xff0c;根据ip地址哈希会有问题.如果是同一台主机再怎么访问都是同一个ip。 t…

c++项目 网络聊天服务器 实现;QPS测试

源码 https://github.com/DBWGLX/SZU_system_programming 文章目录 技术设计编码JSON的替换Protobuf 网络线程池更高效率网络字节序的考虑send可能无法一次性发送全部数据&#xff01;EPOLLHUP , EPOLLERR 的正确处理 IO数据库操作的更高性能 开发日志2025.3a.粘包问题 2025.4b…

rnn的音频降噪背后技术原理

rnniose: 这个演示展示了 RNNoise 项目&#xff0c;说明了如何将深度学习应用于噪声抑制。其核心理念是将经典的信号处理方法与深度学习结合&#xff0c;打造一个小巧、快速的实时噪声抑制算法。它不需要昂贵的 GPU —— 在树莓派上就能轻松运行。 相比传统的噪声抑制系统&…

ubuntu 配置固定ip

在装服务器系统的时候&#xff0c;DHCP自动获取ip时&#xff0c;路由可能会重新分配ip&#xff0c;为避免产生影响&#xff0c;可以关闭DHCP将主机设置为静态ip。 系统环境 Ubuntu 22.04-Desktop 配置方式 一、如果是装的Ubuntu图形化&#xff08;就是可以用鼠标操作点击应用…

基于Coze平台实现工程项目管理SaaS软件的在线化客户服务

一、引言 在数字化转型浪潮下&#xff0c;SaaS&#xff08;软件即服务&#xff09;模式已成为企业级软件的主流交付方式。然而&#xff0c;随着用户规模的增长&#xff0c;传统人工客服模式面临响应速度慢、人力成本高、知识库更新滞后等痛点。如何利用AI技术实现客户服务的智…

批量图片文本识别重命名,批量ocr识别图片重命名,基于WPF和腾讯OCR云部署实,现批量对图片局部提取文字后重命名的操作详细步骤

​​1. 项目背景​​ 在日常工作中,我们经常需要处理大量图片文件,这些图片可能包含重要的文字信息。为了提高工作效率,我们需要一种自动化的方式,从图片中提取文字,并根据提取的文字对图片进行重命名。 本项目基于 ​​WPF​​ 框架开发桌面应用程序,结合 ​​腾讯 OCR…

Linux——冯 • 诺依曼体系结构操作系统初识

目录 1. 冯 • 诺依曼体系结构 1.1 冯•诺依曼体系结构推导 1.2 内存提高冯•诺依曼体系结构效率的方法 1.3 理解数据流动 2. 初步认识操作系统 2.1 操作系统的概念 2.2 设计OS的目的 3. 操作系统的管理精髓 1. 冯 • 诺依曼体系结构 1.1 冯•诺依曼体系结构推导 计算…

Vue3 实现进度条组件

样式如下&#xff0c;代码如下 <script setup> import { computed, defineEmits, defineProps, onMounted, ref, watch } from vue// 定义 props const props defineProps({// 初始百分比initialPercentage: {type: Number,default: 0,}, })// 定义 emits const emits…

35.[前端开发-JavaScript基础]Day12-for循环中变量-华为商城-商品列表-轮播图

for循环中监听函数中打印变量 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wi…

【蓝桥杯】十五届省赛B组c++

目录 前言 握手问题 分析 排列组合写法 枚举 小球反弹 分析 代码 好数 分析 代码 R 格式 分析 代码 宝石组合 分析 代码 数字接龙 分析 代码 拔河 分析 代码 总结 前言 主播这两天做了一套蓝桥杯的省赛题目&#xff08;切实感受到了自己有多菜&#x…

[Linux系统编程]多线程

多线程 1. 线程1.1 线程的概念1.2 进程与线程对比1.3 轻量级进程 2. Linux线程控制2.1 POSIX 线程&#xff08;pthread&#xff09;2.2 线程ID、pthread_t、和进程地址空间的关系2.2.1 pthread_self2.2.2 pthread_create2.2.3 pthread_join2.2.4 线程终止的三种方式2.2.5 pthre…