【Vue-组件】学习笔记

目录

  • <<回到导览
  • 组件
    • 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"><inputv-if="isEdit"	v-focusclass="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.mzph.cn/diannao/77118.shtml

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

相关文章

【Kafka基础】单机安装与配置指南,从零搭建环境

学习Kafka&#xff0c;掌握Kafka的单机部署是理解其分布式特性的第一步。本文将手把手带你完成Kafka单机环境的安装、配置及基础验证&#xff0c;涵盖常见问题排查技巧。 1 环境准备 1.1 系统要求 操作系统&#xff1a;CentOS 7.9依赖组件&#xff1a;JDK 8&#xff08;Kafka …

OpenCV 图形API(21)逐像素操作

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在OpenCV的G-API模块中&#xff0c;逐像素操作指的是对图像中的每个像素单独进行处理的操作。这些操作可以通过G-API的计算图&#xff08;Graph …

CubeMX配置STM32VET6实现网口通信(无操作系统版-附源码)

下面是使用CubeMX配置STM32F407VET6,实现以太网通讯(PHY芯片为LAN8720)的具体步骤总结: 一、硬件连接方式: 硬件原理图: 使用外部晶振为PHY芯片提供时钟。 STM32F407VET6 与 LAN8720 采用 RMII 模式连接。STM32F407VET6引脚功能(RMII)LAN8720引脚PA1ETH_REF_CLKREF_CL…

Android Compose 中获取和使用 Context 的完整指南

在 Android Jetpack Compose 中&#xff0c;虽然大多数 UI 组件不再需要直接使用 Context&#xff0c;但有时你仍然需要访问它来执行一些 Android 平台特定的操作。以下是几种在 Compose 中获取和使用 Context 的方法&#xff1a; 1. 使用 LocalContext 这是 Compose 中最常用…

在VMware下Hadoop分布式集群环境的配置--基于Yarn模式的一个Master节点、两个Slaver(Worker)节点的配置

你遇到的大部分ubuntu中配置hadoop的问题这里都有解决方法&#xff01;&#xff01;&#xff01;&#xff08;近10000字&#xff09; 概要 在Docker虚拟容器环境下&#xff0c;进行Hadoop-3.2.2分布式集群环境的配置与安装&#xff0c;完成基于Yarn模式的一个Master节点、两个…

PID灯控算法

根据代码分析&#xff0c;以下是针对PID算法和光敏传感器系统的优化建议&#xff0c;分为算法优化、代码结构优化和系统级优化三部分&#xff1a; 一、PID算法优化 1. 增量式PID 输出平滑 // 修改PID计算函数 uint16_t PID_calculation_fun(void) {if(PID_Str_Val.Tdata >…

文件映射mmap与管道文件

在用户态申请内存&#xff0c;内存内容和磁盘内容建立一一映射 读写内存等价于读写磁盘 支持随机访问 简单来说&#xff0c;把磁盘里的数据与内存的用户态建立一一映射关系&#xff0c;让读写内存等价于读写磁盘&#xff0c;支持随机访问。 管道文件&#xff1a;进程间通信机…

在 Java 中调用 ChatGPT API 并实现流式接收(Server-Sent Events, SSE)

文章目录 简介OkHttp 流式获取 GPT 响应通过 SSE 流式推送前端后端代码消息实体接口接口实现数据推送给前端 前端代码创建 sseClient.jsvue3代码 优化后端代码 简介 用过 ChatGPT 的伙伴应该想过自己通过调用ChatGPT官网提供的接口来实现一个自己的问答机器人&#xff0c;但是…

硬盘分区格式之GPT(GUID Partition Table)笔记250407

硬盘分区格式之GPT&#xff08;GUID Partition Table&#xff09;笔记250407 GPT&#xff08;GUID Partition Table&#xff09;硬盘分区格式详解 GPT&#xff08;GUID Partition Table&#xff09;是替代传统 MBR 的现代分区方案&#xff0c;专为 UEFI&#xff08;统一可扩展固…

Vite环境下解决跨域问题

在 Vite 开发环境中&#xff0c;可以通过配置代理来解决跨域问题。以下是具体步骤&#xff1a; 在项目根目录下找到 vite.config.js 文件&#xff1a;如果没有&#xff0c;则需要创建一个。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 选项来…

交换机与ARP

交换机与 ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff09; 的关系主要体现在 局域网&#xff08;LAN&#xff09;内设备通信的地址解析与数据帧转发 过程中。以下是二者的核心关联&#xff1a; 1. 基本角色 交换机&#xff1a;工作在 数据链…

【Spring】小白速通AOP-日志记录Demo

这篇文章我将通过一个最常用的AOP场景-方法调用日志记录&#xff0c;带你彻底理解AOP的使用。例子使用Spring BootSpring AOP实现。 如果对你有帮助可以点个赞和关注。谢谢大家的支持&#xff01;&#xff01; 一、Demo实操步骤&#xff1a; 1.首先添加Maven依赖 <!-- Sp…

git功能点管理

需求&#xff1a; 功能模块1 已经完成&#xff0c;已经提交并推送到远程&#xff0c;准备交给测试。功能模块2 已经完成&#xff0c;但不提交给测试&#xff0c;继续开发。功能模块3 正在开发中。 管理流程&#xff1a; 创建并开发功能模块1&#xff1a; git checkout main…

QGIS实战系列(六):进阶应用篇——Python 脚本自动化与三维可视化

欢迎来到“QGIS实战系列”的第六期!在前几期中,我们从基础操作到插件应用逐步提升了 QGIS 技能。这一篇,我们将迈入进阶领域,探索如何用 Python 脚本实现自动化,以及如何创建三维可视化效果,让你的 GIS 项目更高效、更立体。 第一步:Python 脚本自动化 QGIS 内置了 Py…

高德地图 3D 渲染-区域纹理图添加

引入-初始化地图&#xff08;关键代码&#xff09; // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…

ffmpeg视频转码相关

ffmpeg视频转码相关 简介参数 实战举栗子获取视频时长视频转码mp4文件转为hls m3u8 ts等文件图片转视频抽取视频第一帧获取基本信息 转码日志输出详解转码耗时测试 简介 FFmpeg 是领先的多媒体框架&#xff0c;能够解码、编码、 转码、复用、解复用、流、过滤和播放 几乎所有人…

【ISP】HDR技术中Sub-Pixel与DOL的对比分析

一、原理对比 Sub-Pixel&#xff08;空间域HDR&#xff09; • 核心机制&#xff1a;在单个像素内集成一大一小两个子像素&#xff08;如LPD和SPD&#xff09;&#xff0c;利用其物理特性差异&#xff08;灵敏度、满阱容量&#xff09;同时捕捉不同动态范围的信号。 ◦ 大像素&…

Vulnhub-IMF靶机

本篇文章旨在为网络安全渗透测试靶机教学。通过阅读本文&#xff0c;读者将能够对渗透Vulnhub系列IMF靶机有一定的了解 一、信息收集阶段 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/imf-1,162/ 因为靶机为本地部署虚拟机网段&#xff0c;查看dhcp地址池设置。得…

Linux内核中TCP协议栈的实现:tcp_close函数的深度剖析

引言 TCP(传输控制协议)作为互联网协议族中的核心协议之一,负责在不可靠的网络层之上提供可靠的、面向连接的字节流服务。Linux内核中的TCP协议栈实现了TCP协议的全部功能,包括连接建立、数据传输、流量控制、拥塞控制以及连接关闭等。本文将深入分析Linux内核中tcp_close…

java+postgresql+swagger-多表关联insert操作(七)

入参为json&#xff0c;然后根据需要对多张表进行操作&#xff1a; 入参格式&#xff1a; [{"custstoreName":"swagger-测试经销商01","customerName":"swagger-测试客户01","propertyNo":"swaggertest01",&quo…