【前端学习指南】Vue computed 计算属性 watch 监听器

🍭 Hello,我是爱吃糖的范同学 

        🔴 想把自己学习技术的经历和一些总结分享给大家!

        🔴 通过这样的方式记录自己成长,同时沉淀自己的技术,我会把所有额外的时间和经历投放到CSDN和公众号(💥公号名:AIRC Team💥,欢迎关注,为大家准备了很多有关编程学习资料)文章的撰写。

        🔴 希望能通过这样的方式让大家认识我,和我一起学习编程,共同进步!😃

        希望能和大家一起进步和成长!坚持热爱!🎉🎉🎉


目录

✏️ computed 计算属性:

✏️  watch 监听器:

1.定义一个watch监听器:

2.immediate 选项:

3.deep 选项:

4.监听对象单个属性变化:

✏️  计算属性与监听器对比 :

1.适用场景

2. 特性对比

2.1 计算属性

2.2 监听器

3.何时选择计算属性,何时选择监听器

✏️ 写在最后:

✏️ 往期文章: 


✏️ computed 计算属性:

        计算属性本质上就是一个 function 函数,它可以实时监听 data 中的数据变化,并 return 一个计算后的新值提供给组件,组件会对这个新值进行 DOM 渲染。

1.声明一个计算属性:

        计算属性需要以 function 函数的形式声明到组件的 computed 选项中。

<template>
  <div>
    <h1>{{ fullName }}</h1>
    <input v-model="firstName" placeholder="Enter first name">
    <input v-model="lastName" placeholder="Enter last name">
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: '',
      lastName: ''
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

         data 中定义了 firstName 和 lastName,它们会绑定到两个输入框的值。computed 中定义了一个计算属性 fullName,它会根据 firstName 和 lastName 的值动态计算并返回一个拼接后的全名。当你输入名字时,fullName 会自动更新并显示在页面上。

        计算属性是基于依赖的响应式数据来缓存的,只有相关的数据发生变化时,它们才会重新计算,从而提高性能。

如果是使用的Vue3 的 setup 语法糖怎么进行声明捏???

        在 vue3 中,computed 可以在 setup 函数里实现。除了写法不一样,功能上与 vue2 中的 computed 是一致

  • 只有 getter 时,传入一个回调函数。

  • 有 getter 和 setter时,传入一个对象,有 get 和 set 两个属性方法。

  • 需要将处理后的值返回作为该计算属性的值。

在 setup 里使用 computed 的三种方式:

(1)直接在 setup 里使用 computed 函数;

<template>
  <div>{{ fullName }}</div>
</template>

<script>
  import { ref, computed } from 'vue'

  export default {
    setup() {
      const firstName = ref('hello')
      const lastName = ref('world')
      const fullName = computed(() => {
        return firstName.value + '-·-' + lastName.value
      })
      return {
        firstName,
        lastName,
        fullName
      }
    }
  }
</script>

(2)通过 defineComponent 函数在 setup 里使用 computed 函数

        defineComponent 函数是 vue3 的语法糖:

        PS:defineComponent 函数支持 TS 的 “参数类型推断”(如果你使用的是 vue3 + TS,那么使用 defineComponent 将会更友好。)

<template>
  <div>{{ fullName }}</div>
</template>

<script>
  import { defineComponent, ref, computed } from 'vue'

  export default defineComponent({
    setup() {
      const firstName = ref('hello')
      const lastName = ref('world')
      const fullName = computed(() => {
        return firstName.value + '-·-' + lastName.value
      })
      return {
        firstName,
        lastName,
        fullName
      }
    }
  })
</script>

(3)在 <script setup> 里使用 computed 函数

        <script setup> 是 vue3 的新的语法糖,之前的组合 API 相比:

  • 之前的组合 API 必须返回 return,使用 <script setup> 后就不必了。

  • 有更好的运行时性能。

<template>
  <div>{{ fullName }}</div>
</template>

<script setup>
  import { ref, computed } from 'vue'

  const firstName = ref('hello')
  const lastName = ref('world')
  const fullName = computed(() => {
    return firstName.value + '-·-' + lastName.value
  })
</script>

在 setup 里的 computed 的 getter 和 setter:

        当 computed 有 getter 和 setter 时,需要传入一个对象而不是一个函数作为 computed 的参数,然后在 computed 中实现 get 和 set 两个属性方法。

<template>
  <div> firstName: {{ firstName }} </div>
  <div> lastName: {{ lastName }} </div>
  <div> fullName: {{ fullName }} </div>
</template>

<script>
  import { reactive, toRefs, computed } from 'vue'

  export default {
    setup() {
      const user = reactive({
        firstName: 'hello',
        lastName: 'world'
      })
      const fullName = computed({
        get() {
          return user.firstName + '-·-' + user.lastName
        },
        set(val) {
          const nameList = val.split('-·-')
          user.firstName = nameList[0]
          user.lastName = nameList[1]
        }
      })
      return {
        ...toRefs(user),
        fullName
      }
    }
  }
</script>

2.计算属性与方法对比:

        计算属性会对计算执行结果进行缓存,只有计算属性的依赖项(原始数据来源)发生变化时,才会重新计算。否则,都是直接获取当前缓存的计算结果。而无需重新执行计算逻辑。相对于方法来说,计算属性的性能比方法更好。

  • 计算属性和方法的调用方式不同: 计算属性是通过对应名称直接访问的,而方法需要在模板中使用 v-on 指令或者 @ 符号进行调用。

  • 计算属性可以缓存结果,而方法不能: 计算属性的值会被缓存起来,只有在它所依赖的响应式数据变化时才会重新计算。而方法每次调用都要重新计算,无法被缓存。

  • 计算属性应该用于简单的计算,而方法用于复杂逻辑的处理: 如果需要对数据进行一些简单的计算或过滤,可以使用计算属性,因为它们比方法更高效。而如果需要进行一些复杂的逻辑处理,应该使用方法。


✏️  watch 监听器:

        watch 监听器允许开发者监视数据的变化,从而针对数据的变化进行特定的操作。例如可以监听输入框的输入信息,发起 Ajax 请求返回和输入内容相关的搜索信息。

1.定义一个watch监听器:

        message 被监听,一旦它的值发生变化,watch 会调用对应的回调函数,newValue 是新值,oldValue 是旧值。可以在这个回调中做其他逻辑操作,比如发起异步请求、验证数据、或者进行其他逻辑处理。

        这种方式适用于当你需要在数据变化时执行一些操作,且该操作不适合放在 computed 中的情况。

<template>
  <div>
    <input v-model="message" placeholder="Enter a message">
    <p>Message: {{ message }}</p>
    <p>Message length: {{ messageLength }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  },
  computed: {
    messageLength() {
      return this.message.length;
    }
  },
  watch: {
    // 监听 message 的变化
    message(newValue, oldValue) {
      console.log(`Message changed from "${oldValue}" to "${newValue}"`);
      // 这里可以加入一些逻辑,比如发送请求或者做其他操作
    }
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

   data 中定义了 message,它会绑定到一个输入框,允许用户输入文本。computed 中定义了 messageLength,计算并返回 message 的长度。watch 监听器监听 message 的变化。当用户输入时,watch 会触发,打印出 message 之前和之后的值。

在 setup 语法糖中使用监听器:

        使用 watch 来监听 message 的变化。当 message 的值发生变化时,回调函数会触发,打印出旧值和新值。

        设置 immediate: true,使得监听器在组件创建时立即触发一次,打印出 message 的初始值变化。

        返回值:在 setup 中返回了 message 和 messageLength,这些值可以在模板中使用。

<template>
  <div>
    <input v-model="message" placeholder="Enter a message">
    <p>Message: {{ message }}</p>
    <p>Message length: {{ messageLength }}</p>
  </div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    // 定义响应式数据
    const message = ref('Hello, Vue!');

    // 计算属性的实现
    const messageLength = computed(() => message.value.length);

    // 使用 watch 监听 `message` 变化,immediate 设置为 true
    watch(
      message,
      (newValue, oldValue) => {
        console.log(`Message changed from "${oldValue}" to "${newValue}"`);
      },
      { immediate: true }  // 初始化时立即触发
    );

    // 返回需要在模板中使用的数据和方法
    return {
      message,
      messageLength
    };
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

2.immediate 选项:

        默认情况下,组件在初次加载完毕后不会调用 watch 监听器。如果希望 watch 监听器能够立即被调用,则需要使用 immediate 选项。

<template>
  <div>
    <input v-model="message" placeholder="Enter a message">
    <p>Message: {{ message }}</p>
    <p>Message length: {{ messageLength }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  computed: {
    messageLength() {
      return this.message.length;
    }
  },
  watch: {
    // 监听 message 的变化,immediate 设置为 true
    message: {
      handler(newValue, oldValue) {
        console.log(`Message changed from "${oldValue}" to "${newValue}"`);
      },
      immediate: true  // 在初始化时立即触发
    }
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

    handler 是实际的监听函数,它会打印出 message 的变化。immediate: true 会使得监听器在组件创建时就立即执行一次,而不仅仅是在 message 发生变化时。

3.deep 选项:

        当 watch 监听的是一个对象,如果对象的属性值发生了变化,上面的配置情况下是无法监听到变化的。此时需要使用 deep 选项。

<template>
  <div>
    <input v-model="user.name" placeholder="Enter your name" />
    <input v-model="user.age" placeholder="Enter your age" />
    <p>User Info: {{ user.name }} - {{ user.age }}</p>
  </div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    // 定义一个包含嵌套属性的响应式对象
    const user = ref({
      name: 'John Doe',
      age: 30
    });

    // 使用 deep 选项来监听对象的深层变化
    watch(
      user,
      (newValue, oldValue) => {
        console.log('User info changed:', newValue);
      },
      { deep: true }  // 开启深度监听
    );

    return {
      user
    };
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

        响应式对象user 是一个包含 name 和 age 属性的对象,通过 ref 包装为响应式对象。

  watch 使用:我们使用 watch 来监听 user 对象的变化,并设置了 { deep: true } 选项,意味着如果 user 对象的任何嵌套属性发生变化,监听器都会被触发。

        回调函数:每次 user 对象发生深层次变化时(比如修改了 name 或 age),回调函数就会打印新的 user 对象。

为什么使用 deep

  • 浅层监听:默认情况下,watch 只会监听对象或数组的引用变化。例如,如果你直接修改了 user.name 的值,watch 会被触发。

  • 深层监听:使用 deep: true 选项后,即使修改了嵌套的属性(例如 user.name 或 user.age),watch 也会检测到变化并触发回调。这对于复杂的数据结构非常有用,特别是当你需要监听嵌套的对象或数组时。

注意事项:

  • 开启 deep 选项会带来一定的性能开销,尤其是在对象或数组较大时,因为它需要对整个对象或数组进行递归遍历和监控。因此,在使用时要谨慎,避免不必要的性能损失。

  • 适合用于需要对深层次数据进行监控的场景,比如表单数据、复杂对象等。

4.监听对象单个属性变化:

        在使用 deep 选项后,会对整个对象中的所有属性值的变化进行监听,但是处于某种场景下,只希望对对象中某个属性进行监听,此时可以按照如下规则进行定义 watch 监听器:

<template>
  <div>
    <input v-model="user.name" placeholder="Enter your name" />
    <p>User Name: {{ user.name }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: 'John Doe',
        age: 30
      }
    };
  },
  watch: {
    // 监听 user.name 属性变化
    'user.name': function (newValue, oldValue) {
      console.log(`User name changed from "${oldValue}" to "${newValue}"`);
    }
  }
};
</script>

<style scoped>
/* Optional CSS styles */
</style>

        如果你想监听多个属性,并且希望在属性变化时做统一的处理,可以使用 watch对象形式,将多个属性的监听逻辑写在一个 handler 中。例如:

<script>
export default {
  data() {
    return {
      user: {
        name: 'John Doe',
        age: 30
      }
    };
  },
  watch: {
    // 监听 user 对象中的多个属性变化
    'user': {
      handler(newUser, oldUser) {
        if (newUser.name !== oldUser.name) {
          console.log(`Name changed: ${oldUser.name} -> ${newUser.name}`);
        }
        if (newUser.age !== oldUser.age) {
          console.log(`Age changed: ${oldUser.age} -> ${newUser.age}`);
        }
      },
      deep: true  // 深度监听整个 user 对象的变化
    }
  }
};
</script>

✏️  计算属性与监听器对比 :

        计算属性(computed)和监听器(watch)是 Vue 中用于处理数据变化的两种常用方式。它们各自有不同的用途和特性,理解它们的差异能帮助你在开发中做出更合适的选择。

  • 计算属性(computed):

    • 用于基于已有数据计算派生数据(例如,多个数据项的组合结果)。

    • 计算属性会缓存计算结果,只有当其依赖的数据变化时才会重新计算。这使得它们在性能上更加高效,避免不必要的计算。

    • 计算属性是 惰性求值,即只有在它们被访问时才会计算,并且会缓存直到依赖项发生变化。

  • 监听器(watch):

    • 用于在数据变化时执行 异步操作 或执行副作用(比如向服务器发起请求)。

    • 监听器可以监听 某个数据属性的变化,并在变化时执行指定的回调函数。

    • 监听器是 立即执行 的,即数据变化后会立即触发回调函数。

1.适用场景

  • 计算属性:当你需要根据一个或多个数据属性的值进行计算,且计算结果依赖的数据不经常变化时,使用计算属性更合适。它主要用于:

    • 从已有数据计算出新的值(例如,格式化日期、计算总金额等)。

    • 需要缓存计算结果,避免重复计算的场景。

  • 监听器:当你需要执行异步操作、或者某些副作用操作时(如发起 HTTP 请求、操作 DOM 或者调用外部 API),使用监听器更为合适。它适用于:

    • 监控数据变化并执行副作用(例如,当某个输入框的值变化时触发表单提交)。

    • 需要对某些数据变化进行处理,而不仅仅是计算派生数据。

2. 特性对比

特性

计算属性 (computed)

监听器 (watch)

主要用途

计算派生数据,避免重复计算。

监听数据变化并执行副作用(如异步操作)。

缓存

会缓存计算结果,只有依赖的数据变化时才重新计算。

不缓存,每次数据变化都会执行回调函数。

执行时机

在模板渲染时或者访问时计算。

在数据变化时立即执行回调函数。

返回值

必须返回一个值,这个值通常用在模板中或其他计算属性中。

无返回值,通常用来触发副作用(如发起请求、修改 DOM)。

异步操作

不适合处理异步操作。

非常适合处理异步操作。

复杂计算

适合简单的、基于已有数据的计算。

不适合做复杂的计算,更多用于处理副作用。

性能

性能较好,因其计算结果会被缓存。

每次数据变化都会执行,可能影响性能。

2.1 计算属性

<template>
  <div>
    <p>{{ fullName }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    fullName() {
      // 计算并返回 fullName,只会在 firstName 或 lastName 改变时重新计算
      return this.firstName + ' ' + this.lastName;
    }
  }
};
</script>
  • 解释fullName 是一个计算属性,它基于 firstName 和 lastName 来计算,并且会在这两个数据发生变化时重新计算。计算属性会缓存计算结果,避免多次计算。

2.2 监听器

<template>
  <div>
    <input v-model="name" placeholder="Enter your name">
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: ''
    };
  },
  watch: {
    // 监听 name 的变化,并在变化时执行回调函数
    name(newName) {
      console.log('Name changed to: ' + newName);
      // 可以在这里执行异步操作,比如发起 HTTP 请求等
    }
  }
};
</script>
  • 解释watch 监听 name 的变化,当 name 的值发生变化时,会执行指定的回调函数。在这个例子中,我们简单地打印了新值,但也可以在回调中执行更复杂的操作,比如向服务器发送请求。

3.何时选择计算属性,何时选择监听器

选择计算属性

  • 当你需要在模板中显示一个基于其他数据的计算值时。

  • 当你需要避免重复计算时(缓存计算结果)。

  • 当你不需要执行副作用(例如异步操作或修改外部状态)时。

选择监听器

  • 当你需要在数据变化时执行副作用操作时(如发送 HTTP 请求、修改 DOM、触发动画等)。

  • 当你需要在数据变化后进行复杂的操作,而不仅仅是计算派生数据时。

  • 当你需要监听的数据是动态变化的,不适合缓存时。

组合使用:

        有时,你可能需要同时使用计算属性和监听器。例如,可以使用计算属性来生成数据,使用监听器来处理外部副作用。

<template>
  <div>
    <input v-model="name" placeholder="Enter your name">
    <p>{{ greeting }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: ''
    };
  },
  computed: {
    // 使用计算属性生成问候语
    greeting() {
      return this.name ? `Hello, ${this.name}!` : 'Hello!';
    }
  },
  watch: {
    // 监听 name 的变化,触发异步请求
    name(newName) {
      if (newName) {
        this.fetchGreeting(newName);
      }
    }
  },
  methods: {
    async fetchGreeting(name) {
      // 假设这里发起了一个异步请求
      console.log(`Fetching greeting for ${name}...`);
    }
  }
};
</script>


✏️ 写在最后:

        学习是通往未来的桥梁,是打开世界大门的钥匙。每一步的坚持,都是向梦想迈进的一小步。即使今天的努力看不见回报,明天的你会感谢今天的自己。记住,每一个挑战都是成长的机会,每一次进步都是成功的积累。别怕慢,只有不前行才会停滞。相信自己的潜力,勇敢追求知识,你将会看到一个不一样的、更强大的自己!


✏️ 往期文章: 

2024年还在问前端怎么学?一份前端学习指南_web前端怎么学习人工智能-CSDN博客

【前端学习指南】基础开发环境搭建_前端项目搭建环境-CSDN博客

【前端学习指南】开启 Vue 的学习之旅_前端vue 学习之旅-CSDN博客

【前端学习指南】第一站 Vue 生命周期初探_vue 前端学习-CSDN博客

【前端学习指南】第二站 Vue 工程化开发-CSDN博客

【前端学习指南】第三站 Vue 组件之间通信-CSDN博客

【前端学习指南·番外篇】Node.js 安装及环境配置_node前端运行环境-CSDN博客

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

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

相关文章

自动驾驶合集(更新中)

文章目录 车辆模型控制路径规划 车辆模型 车辆模型基础合集 控制 控制合集 路径规划 规划合集

vcenter service基本异常处理

服务&#xff1a;vcenter service 版本&#xff1a; 7.0.3 问题描述&#xff1a;无法访问vcenter ui 排障思路&#xff1a; 1. 登入vcenter所在服务器执行基础排查&#xff1a;内存、cpu、磁盘、网络等&#xff0c;发现磁盘日志目录已经爆满&#xff0c;删除180天前的日志恢…

Background Tasks Kit(后台任务开发服务)

11_13日学习笔记 Background Tasks Kit&#xff08;后台任务开发服务&#xff09; Background Tasks Kit简介 设备返回主界面、锁屏、应用切换等操作会使应用退至后台。 应用退至后台后&#xff0c;如果继续活动&#xff0c;可能会造成设备耗电快、用户界面卡顿等现象。 为了…

modbus协议 Mthings模拟器使用

进制转换 HEX 16进制 (0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F表示0-15) dec 10进制 n(16进制) -> 10 abcd.efg(n) d*n^0 c*n^1 b*n^2 a*n^3 e*n^-1 f*n^-2 g*n^-3&#xff08;10&#xff09; 10 -> n(16进制) Modbus基础概念 高位为NUM_H&…

Python多进程间通讯(包含共享内存方式)

文章目录 1 通过非共享内存配合队列方式2 通过共享内存配合队列方式 注&#xff1a;本博文测试环境为Linux系统。 1 通过非共享内存配合队列方式 下面是一个常见的生产者与消费者的模式示例&#xff0c;这里分别启动了两个子进程&#xff0c;一个为生产者&#xff08;producer…

YOLOv11实战宠物狗分类

本文采用YOLOv11作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv11以其高效的特征提取能力&#xff0c;在多个图像分类任务中展现出卓越性能。本研究针对5种宠物狗数据集进行训练和优化&#xff0c;该数据集包含丰富的宠物狗图像样本…

游戏引擎学习第八天

视频参考: https://www.bilibili.com/video/BV1ouUPYAErK/ 理解下面的代码 关于虚函数 代码分解 结构体 foo 的定义&#xff1a; struct foo {int32 X;int64 Y;virtual void Bar(int c); };foo 结构体有两个成员变量&#xff1a;X&#xff08;int32 类型&#xff09;和 Y&…

我要学kali-linux之shell脚本编程1

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

尽量通俗易懂地概述.Net U nity跨语言/跨平台相关知识

本文参考来自唐老狮,Unity3D高级编程:主程手记,ai等途径 仅作学习笔记交流分享 目录 1. .Net是什么? 2. .Net框架的核心要点? 跨语言和跨平台 .Net x Unity跨平台发展史 Net Framework 2002 Unity跨平台之 Mono 2004 Unity跨平台之 IL2CPP 2015 二者区别 .NET Core …

大陆 ARS513 / ARS510 标准雷达(解析二)

1。GW_ACU (0x40) • GW_ACU_LongAccel Longitudinal acceleration of ego vehicle. • GW_ACU_LongAccel_ValidFlag Valid flag of signal “GW_ACU_LongAccel”. • GW_ACU_LateralAccel Lateral acceleration of ego vehicle. Signal quality requirements for “GW_ACU_La…

【游戏引擎之路】登神长阶(十四)——OpenGL教程:士别三日,当刮目相看

【游戏引擎之路】登神长阶&#xff08;十四&#xff09;——OpenGL教程&#xff1a;士别三日&#xff0c;当刮目相看 2024年 5月20日-6月4日&#xff1a;攻克2D物理引擎。 2024年 6月4日-6月13日&#xff1a;攻克《3D数学基础》。 2024年 6月13日-6月20日&#xff1a;攻克《3D…

【C++动态规划】2304. 网格中的最小路径代价|1658

本文涉及知识点 C动态规划 LeetCode2304. 网格中的最小路径代价 给你一个下标从 0 开始的整数矩阵 grid &#xff0c;矩阵大小为 m x n &#xff0c;由从 0 到 m * n - 1 的不同整数组成。你可以在此矩阵中&#xff0c;从一个单元格移动到 下一行 的任何其他单元格。如果你位…

数据中台解决方案

文件是关于数据中台解决方案的详细介绍&#xff0c;内容涵盖了数据中台的定义、建设方案、实施步骤、以及在数字化转型中的作用。以下是对文件内容的分析和总结&#xff1a; 1. 数字化转型背景 国家政策支持&#xff1a;提到了《中华人民共和国国民经济和社会发展第十四个五年…

JS 实现WebSocket通讯和什么是WebSocket

WebSocket 介绍&#xff1a; WebSocket 是一种网络传输协议&#xff0c;可在单个 TCP 连接上进行全双工通信。它允许服务器主动向客户端推送信息&#xff0c;客户端也能实时接收服务器的响应。 客户端 这里实现了将input内的内容发送给客户端&#xff0c;并将接收到的服务器的…

K8S单节点部署及集群部署

1.Minikube搭建单节点K8S 前置条件&#xff1a;安装docker&#xff0c;注意版本兼容问题 # 配置docker源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo# 安装docker环境依赖 yum install -y yum-utils device-m…

算法闭关修炼百题计划(六)

塔塔开(滑稽 1.删除排序链表中的重复元素2.删除排序链表中的重复元素II3.字典序的第k小数字4.下一个排列5.排序链表6.随机链表的复制7.数据流的中位数 1.删除排序链表中的重复元素 使每个元素就出现一次 class Solution { public:ListNode* deleteDuplicates(ListNode* head)…

PH热榜 | 2024-11-13

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 在线预览 1. Agree.com 标语&#xff1a;人人免费电子签名&#xff01; 介绍&#xff1a;Agree&#xff0c;这款由人工智能驱动的平台…

PTE-中间件安全

DOCKER环境&#xff0c;一般是80 8080 8081端口 1 apache位置扩展名解析漏洞 cd vulhub-master/httpd/apache_parsing_vulnerability/ docker-compose up -d 修改一句话的后缀 直接上传 蚁剑 2 CVE-2017-15715 docker-compose stop cd .. cd CVE-2017-15715/ dock…

【Linux】Github 仓库克隆速度慢/无法克隆的一种解决方法,利用 Gitee 克隆 Github 仓库

Github 经常由于 DNS 域名污染以及其他因素克隆不顺利。 一种办法是修改 hosts sudo gedit /etc/hosts加上一行 XXX.XXX.XXX.XXX github.comXXX 位置的 IP 可以通过网站查询 IP/服务器github.com的信息-站长工具 这种方法比较适合本身可以克隆&#xff0c;但是速度很慢的…

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)

作者&#xff1a;来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ&#xff08;Better Binary Quantization - 更好的二进制量化&#xff09;—— 一种压缩向量化数据的创新方法&#xff0c;其性能优于传统方法&#xff0c;例如乘积量化 (Product Qu…