Vue2高级篇

Vue高级

Vue生命周期

生命周期又称为生命周期回调函数、生命周期函数、生命周期钩子, 是Vue在运行过程中的关键时刻帮我们调用的一些指函数, 生命周期函数名字不可修改, 其中的this指向的是vm或组件实例对象.

常用的生命周期钩子:

  • mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等初始化操作
  • beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等收尾工作

在这里插入图片描述

关于销毁Vue实例

  • 销毁后借助Vue开发者工具开不到任何信息
  • 销毁后自定义事件会失效, 但原生DOM事件依然有效
  • 一般不会在beforeDestroy操作数据, 因为即便操作数据, 也不会再触发更新流程了

组件

组件的定义——实现应用中局部功能代码和资源集合, 使用组件化可以复用代码, 简化项目编码, 提高运行效率

  • 模块化: 当应用中的js都以模块来编写的, 那这个应用就是一个模块化的应用
  • 组件化: 当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用

在这里插入图片描述

通过Vue.extend(options)可以创建一个组件, 其中options和new Vue(options)时传入的options几乎一样, 但也有点区别:

  • el不能写, 最后所有的组件都要经过一个vm的管理, 由vm中的el决定服务于那个容器
  • data必须写成函数, 因为组件通常都是复用的, 数据存在引用关系

注册组件的方式分为:

  1. 局部注册: 通过new Vue时传入components选项
  2. 全局注册: 通过Vue.component('组件名', 组件)
<div id="app"><!-- 3. 使用组件 --><school></school>
</div>
<script>// 1. 声明一个组件 可以不写Vue.extend, 直接写对象const school = Vue.extend({template: `<div><h1>{{ name }}</h1><h1>{{ address }}</h1></div>`,data() {return {name: 'putian',address: 'fujian'}}})new Vue({el: '#app',// 2. 注册组件components: {school}})
</script>

使用Vue组件时, 大驼峰式()的组件或单标签的写法都需要Vue脚手架支持.

Vue组件本质上是一个名为VueComponent的构造函数, 通过Vue.extend()生成的, 不同类型的组件对应的VueComponent构造函数不同(虽然名字都是同一个). 当我们使用组件时, 即在模板中声明<school></school>后, Vue解析时会帮我们创建school组件的实例对象. 也就是new VueComponent(options)

关于this指向问题

  • 组件配置中: data函数、methods中的函数、watch中的函数、computed中的函数都是VueComponent实例对象
  • new Vue(options)配置中: data函数、methods中的函数、watch中的函数、computed中的函数都是Vue实例对象

VueComponent.prototype._proto_ === Vue.prototype

有个如上的关系, 才能让组件实例对象可以访问到Vue原型上的属性、方法, 如图:

在这里插入图片描述

组件标识ref

ref被用来给元素或者子组件注册引用信息(id的替代者). 当ref应用在html标签上时, 获取的时真实DOM元素, 当应用在组件标签上时则是组件实例对象.

使用方式:

  • 声明标识
<h1 ref="xxx">...</h1>
<School ref=""></School>
  • 获取组件
this.$refs.xxx //xxx为ref的值

例如:

<School ref="school"></School>export default {name: 'App',components: {School},methods: {showInfoApp() {console.log(this.$refs.school);}}
}
组件通信props

功能: 让组件接收外部传过来的数据(可以是函数)

语法: 使用组件时:

​ 组件定义时:

写法一: 简单接收声明接收——数组

new Vue({props: ['name', 'key2', 'key3']
})

写法二: 接收的同时对数据进行类型限制 简单对象

new Vue({props: {name: String,age: Number}
})

写法三: 接收的同时对数据进行类型限制 复杂对象, 默认值指定+必要性限制+类型限制

new Vue({props: {name: {type: String,// required: false,default: 'wang'}}
})

props是只读的, Vue会监测对props的修改, 如果进行了修改, 就会发出警告. 若业务需求确实需要修改, 那么需要复制props的内容到data中一份, 然后去修改data中的数据即可

混入mixin

功能: 可以把多个组件公用的配置提取成一个混入对象

  • 定义混合
// 定义一个混入js文件并导出对象
export const mixin = {methods: {showInfo() {alert(this.name)}}
}
  • 使用混入
// 1.导入混入
import {mixin} from "@/mixin";
// 2.使用混入(局部混入)
new Vue({mixins: ['mixin']
})
// 全局混入
Vue.mixin(xxx)

混入即将内容与组件内的内容合并, 当data产生冲突时, 会以组件内部声明的为主. vue的声明周期函数也可以使用混入, 这时会先调用混入的生命周期函数, 然后才调用组件内部的.

插件plugins

插件可以增强Vue, 其本质是包含install方法的一个对象, install的第一个参数是Vue, 第二个以后的参数是插件使用者传递的自定义参数.

  • 定义插件
对象.install = function(Vue, options) {// 1. 添加全局过滤器Vue.filter(...)// 2. 添加全局指令           Vue.directive(...)// 3. 配置全局混入(合)Vue.mixin(...)// 4. 添加实例方法Vue.prototype.$myMethod = function() {...}Vue.prototype.$myProperty = xxx
}
  • 使用插件
import plugins from ''
Vue.use('plugins', 'xx', 'xxx')
组件化编码流程
  1. 拆分静态组件: 组件要按照功能点拆分, 命名不能跟html元素冲突
  2. 实现动态组件: 需要考虑数据的存放位置, 数据是一个组件在用, 还是多个组件在用
    • 一个组件在用: 放在组件自身即可
    • 多个组件共用: 放在组件共同的父组件上(状态提升)
  3. 实现交互: 从绑定事件开始

案例: 组件化编码TODO

当数据在多个组件共用时, 会涉及组件的通信问题, props配置项适用于父子组件之间的通信, 这个通信是双向的, 既可以父传子, 也可以子向父组件传递信息(父组件传递函数给子组件)

使用v-model时, v-model绑定的值不能时props传递过来的值, 因为props是不可以修改的, 它是只读的

组件的自定义事件

组件的自定义事件是一种组件之间通信的方式, 适用于子组件向父组件传递信息.

使用场景: A是父组件, B时子组件, B想给A穿数据, 那么就要在A中给B绑定自定义事件(事件的回调函数在A中)

  1. 绑定自定义事件的两种方式(在使用到该组件的组件上绑定):
<!-- 方式一 -->
<Demo @testEvent='func'/>
<Demo v-on:testEvent='func'/>  
// 方式二
<Demo ref='demo'/>mounted() {this.$refs.demo.$on('testEvent', this.func)
}

若只想让自定义事件只能触发一次, 可以使用once修饰符, 或者方式二中$on换成$once

  1. 触发自定义事件(在子组件中触发):
this.$emit('eventName', 参数)
  1. 解绑自定义事件:
this.$off('eventName') // 解绑一个事件
this.$off(['eventName1', 'eventName2']) // 解绑多个事件
this.$off() // 解绑所有事件

组件上也可以绑定原生DOM事件, 需要使用native修饰符

通过this.$ref.xxx.$on('eventName', func)绑定自定义事件时, 回调要配置在methods中, 要么使用箭头函数, 否则this指向会有问题

全局事件总线

全局事件总线是一种组件之间通信的方式, 适用于任意组件之间通信

  1. 安装全局事件总线
new Vue({// ...beforeCreate() {Vue.prototype.$bus = this // 安装全局实现总线, ¥bus就是当前正在创建的vm}
})
  1. 使用事件总线
  • 接收数据: A组件想要接收数据, 则在A组件中给$bus绑定自定义事件, 事件的回调留在A组件自身
methods: {// 声明回调demo(param) {// ..}
}
mounted() {this.$bus.$on('xxx', this.demo)
}
  • 提供数据
this.$bus.$emit('xxxx', 数据)

在beforeDestroy钩子中, 记得使用*$off*去解绑当前组件所用到的事件

消息订阅与发布

消息订阅发布也是一种组件间通信的方式, 适用于任意间组件的通信

  1. 安装pubsub库:
npm i pubsub-js
  1. 引入模块
import pubsub from 'pubsub-js'
  1. 订阅消息: A组件向接收数据, 则在A组件中订阅消息, 订阅的回调留在A组件自身
methods: {// 第一个参数是消息名称, 第二个开始才是真正的参数demo(msgName, data) {//...}
}
mounted() {this.pid = pubsub.subscribe('xxx', this.demo) // 订阅消息
}

发布订阅消息并不是Vue中的内容, 因此直接写普通函数时, this并不是vm实例对象, 此时可以写成箭头函数, 或者在methods中声明的函数

  1. 发布消息
pubsub.publish('xxx', 数据)
  1. 取消订阅
beforeDestroy: {pubSub.unsubscribe(pid)
}
$nextTick

语法: this.$nextTick(回调函数)

作用: 在下一次DOM更新结束后执行其指定的回调

当数据改变后, 要基于更新后的新DOM进行某些操作时, 要在nextTick所指定的回调函数中执行

插槽

作用: 让父组件可以向子组件指定位置插入html结构, 也是一种组件间通信的方式, 适用于父组件 => 子组件

  1. 默认插槽
<!-- parent -->
<Category><div>html...</div>
</Category>
<!-- child -->
<template><div><!-- define slot --><slot>default content</slot></div>
</template>
  1. 具名插槽
<!-- parent -->
<Category><template slot='center'><div>html tag</div></template><template v-slot:footer><div>html tags</div></template>
</Category>
<!-- child -->
<template><div><slot name='center'>defaut content</slot><slot name='footer'>defaut content</slot></div>
</template>
  1. 作用域插槽
<!-- parent -->
<Category><!-- receive data here --><template scope='scopeData'><!-- ul --><ul><li v-for='g in scopeData.games' :key='g'>{{ g }}</li></ul></template>
</Category><Category><template scope='scopeData'><!-- ol --><ol><li v-for='g in scopeData.games' :key='g'>{{ g }}</li></ol></template>
</Category>
<!-- child -->
<template><div><!-- scope slot --><slot :games="games"></slot></div>
</template><script>export deafault{name: 'Category',data() {// 数据在子组件中, 结构由使用者决定return {games: ['game1', 'game2']}}}
</script>

数据在组件自身, 但根据数据生成的结构需要组件的使用者来决定时才使用作用域插槽

Vuex

Vuex时专门在Vue中实现集中式状态(数据)管理的一个Vue插件, 对vue应用中多个组件的共享状态进行集中式的管理(读/写), 也是一种组件间通信的方式, 且适用于任意组件间的通信

在这里插入图片描述

  1. 多组件共享数据——全局事件总线

当涉及组件太多, 全局事件总线实现共享数据就很麻烦了.

在这里插入图片描述

  1. 多组件共享数据——vuex实现
  • 多个组件依赖于同一状态
  • 来自不同组件的行为需要变更同一状态

在这里插入图片描述

vuex基本使用
  1. 创建配置文件: src/store/index.js
import Vue from "视频笔记/前端/Vue/VueJunior"
import Vuex from "vuex"// 应用vuex插件, 无法在App.vue中使用Vuex, 模块里的代码会先被执行, 然后才Vue.use
Vue.use(Vuex)// 用于响应组件中的动作(业务逻辑)
const actions = {}
// 用于操作数据(方法名通常大写)
const mutations = {}
const state = {}export default new Vuex.Store({actions, mutations, state
})
  1. 使用store
import store from "@/store";export default {name: 'App',components: {HelloWorld,store}
}
  1. actions中的参数
// 第一个参数为上下文对象, 包含了dispach和commit等对象, 第二个为值
oddAdd(context, value) {if (context.state.sum % 2) context.commit('ADD', value)
}
  1. mutations中的参数
// 真正操作state的地方, 第一个参数为state对象
ADD(state, value) {state.sum += value
}

若没有网络请求或其他业务逻辑, 组件中也可以越过actions, 即不写dispatch 直接编写commit

getters配置项

当state中的数据需要加工后再使用时(逻辑复杂, 并且需要复用时), 可以使用getters加工.

  1. store.js中追加getters配置
const getters = {// 第一个参数就是数据源bigSum(state) {return // ...}
}
  1. 组件中读取数据
$store.getters.bigSum

可以将state和getters类比为vue中的data和computed之间的关系

Vuex的四个map方法的使用
  1. mapState方法: 用于映射state中的数据为计算属性
import { mapState } from Vuexcomputed: {// 借助mapState生成计算属性: 对象写法...mapState({ add:'add'})// 数组写法...mapState(['add'])
}
  1. mapGetters方法: 映射getters中的数据为计算属性
computed: {...mapGetters({bigSum:'bigSum'})// 数组写法...mapGetters(['bigSum'])
}
  1. mapActions方法: 用于在组件中生成与actions 对话的方法, 即包含$store.dispatch(xxx)的函数
methods: {...mapActions({ incrementOdd: 'incrementOdd', incrementWait:'incrementWait'})// 数组写法...mapActions(['incrementOdd', 'incrementWait'])
}
  1. mapMutations方法: 用于生成在组件中与mutations对话的方法, 即包含$store.commit(xxx)的函数
methods: {...mapMutations({increment: 'INCREMENT', decrement:'DECREMENT'})// 数组写法...mapMutations('INCREMENT', 'DECREMENT')
}

mapActionsmapMutations使用时, 若需要传递参数, 在模板中绑定事件时需要传递好参数, 否则参数时事件对象

模块化与命名空间

可以将一类功能的配置项放到一个对象中, 并用命名空间将其标识

const countAbout = {namespaced: true,state: { x: 1},mutations: {...},actions: {...},getters: {...}
}const personAbout = {namespaced: true,state: { x: 1},mutations: {...},actions: {...},getters: {...}       
}new Vuex.Store({modules: {countAbout,personAbout       }            
})            
  1. 开启命名空间后, 组件中读取state数据:
// 方式一:
this.$store.state.personAbout.x
// 方式二:
...mapState('namespace', ['x'])
  1. 读取getters数据
// 方式一:
this.$store.getters['personAbout/firstPersonName']
// 方式二:
...mapGetters('countAbout', ['bigSum'])
  1. 组件中调用dispatch
// 方式一
this.$store.dispatch('personAbout/xxx')
...mapActions('countAbout', ['xxx'])
  1. 组件中调用commit
// 方式一
this.$store.commit('personAbout/xxx', value)
...mapMutations('countAbout', ['xxx'])

路由

一个路由(route)就是一组映射关系, 多个路由需要路由器(router)进行管理

路由的基本使用
  1. 安装vue-router, 命令: npm i vue-router

  2. 应用插件: Vue.use(VueRouter)

  3. 配置路由

import VueRouter from 'vue-router'export default new VueRouter({routes: [{name: 'xxx', // 路由命名(使用路由时方便编码)path: '/about',component: About,children: [{path: 'news', // 此处路由不需要再写’/‘component: News}]},// ...]
})
  1. 实现切换路由(active-class可配置高亮样式)
<router-link active-class='active' to='/about'>About</router-link>

路由跳转时, to属性还能写成对象形式, 如果路由有name属性, 可以不写路径, 通过name也能跳转

  1. 指定展示位置
<router-view></router-view>

几个注意点

  • 路由组件通常放在pages文件夹, 一般组件通常存放在components文件夹
  • 通过切换, “隐藏”了的路由组件, 默认是被销毁的, 需要的时候会重新挂载
  • 每个组件都有自己的$route属性, 里面存储着自己的路由信息
  • 整个应用只有一个router, 可以通过组件的$router属性获取到
路由传参
通过query传参
  1. 传递参数
<!-- 方式一:字符串写法 -->
<router-link :to='/home/message/detail?id=xxx&title=xxx'></router-link><!-- 方式二:对象写法 -->
<router-link :to='{path: `/home/message/detail`,query: {id: xxx,title: xxx}}'
  1. 接收参数
$route.query.xxx
通过params传参
  1. 配置路由, 声明接收params参数
new VueRouter({path: '/home',component: Home,children: [{path: 'news/:id/:title', //使用占位符声明接收params参数component: News}]
})
  1. 传递参数
<router-link :to='/home/message/detail/xxx/xxx'></router-link>

路由携带params参数时, 如果使用to的对象写法, 则不能使用path配置项, 必须使用name配置!

路由的props配置

通过配置props配置项可以使组件更方便地接收路由参数

{name: 'route1',path: '/detail/:id',component: Detail,// 第一种写法: props值为对象, 该对象中所有的k-v最终都会通过props传给detail组件props: {a:900}// 第二种写法: boolean, 把路由中的所有params参数通过props传给Detail组件props: true// 第三种写法: props值为函数, 会把函数返回的对象的所有k-v通过props传给Detail组件props(route) {return {id: route.query.id,title: route.query.title}}
}
<router-link>的replace属性

浏览器的历史记录有两种写入方式分别是pushreplace, push是追加历史记录, replace则是替换当前记录. 路由跳转时候默认是push. 可以通过以下配置开启repalce模式

<router-link replace ...>News</router-link>
编程式路由导航

编程式路由可以不借助<router-link>实现路由跳转, 让路由跳转更加灵活

this.$router.push({name: 'path',params: {id: xxx,title: xxx}
})this.$router.replace({name: 'path',params: {id: xxx}
})this.$router.back()
this.$router.forward()
this.$router.go(3) // 正数前进, 负数后退
缓存路由组件

让不展示的路由组件保持挂载, 不被销毁. 缓存多个组件可以写数组

<!-- 要写组件名称 --> 
<keep-alice include="News"><router-view></router-view>
</keep-alice>
两个新的生命周期钩子

路由组件独有的两个钩子, 用于捕获路由组件的激活状态

  1. activated: 路由组件被激活时触发
  2. deactivated: 路由组件失活时触发
路由守卫

路由守卫可以对路由进行权限控制, 包括全局守卫、独享守卫、组件内守卫.

// 前置全局守卫 初始化时执行、每次路由切换前执行
router.beforeEach((to, from, next) => {if(to.meta.isAuth) {if(condition) {next() // 满足条件放行,}}
})// 后置
router.afterEach((to, from) => {if(to.meta.title) {// ...}
})// 独享守卫, 在具体的路由配置项中配置
beforeEnter(to, from, next) {}

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

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

相关文章

【Web安全】SQL各类注入与绕过

【Web安全】SQL各类注入与绕过 【Web安全靶场】sqli-labs-master 1-20 BASIC-Injection 【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection 【Web安全靶场】sqli-labs-master 38-53 Stacked-Injections 【Web安全靶场】sqli-labs-master 54-65 Challenges 与62关二…

python并发编程:IO模型

一 IO模型 二 network IO 再说一下IO发生时涉及的对象和步骤。对于一个network IO \(这里我们以read举例\)&#xff0c;它会涉及到两个系统对象&#xff0c;一个是调用这个IO的process \(or thread\)&#xff0c;另一个就是系统内核\(kernel\)。当一个read操作发生时&#xff…

无代理方式实现VMware的迁移?详细解析

在当今数字化时代&#xff0c;数据的安全性和可用性对于企业至关重要。尤其是在VMware转变订阅策略后&#xff0c;原本永久订阅的产品转变为以年付费订阅的形式&#xff0c;导致客户不得不支付更多的费用&#xff0c;大幅增加了成本。同时&#xff0c;客户也对VMware未来发展前…

k8s-kubeapps图形化管理 21

结合harbor仓库 由于kubeapps不读取hosts解析&#xff0c;因此需要添加本地仓库域名解析&#xff08;dns解析&#xff09; 更改context为全局模式 添加repo仓库 复制ca证书 添加成功 图形化部署 更新部署应用版本 再次进行部署 上传nginx 每隔十分钟会自动进行刷新 在本地仓库…

人人都写过的6个bug

大家好&#xff0c;我是知微。 程序员写bug几乎是家常便饭&#xff0c;也是我们每个人成长过程中难以避免的一部分。 为了缓解这份“尴尬”&#xff0c;今天想和大家分享一些曾经都会遇到过的bug&#xff0c;让我们一起来看看这些“经典之作”。 1、数组越界 #include <…

Python爬虫:http和https介绍及请求

HTTP和HTTPS 学习目标&#xff1a; 记忆 http、https的概念和区别记忆 浏览器发送http请求的过程记忆 http请求头的形式记忆 http响应头的形式了解 http响应状态码 1 为什么要复习http和https 在发送请求&#xff0c;获取响应的过程中 就是发送http或https的请求&#xff0c…

DMA 链表模式(LLI)深度解析

在进行一次 DMA 读或者写的时候&#xff0c;可以配置多个链表&#xff0c;从而当一个链表的数据传输完成时&#xff0c;会跳到下一个链表的起始地址&#xff0c;并继续传输数据&#xff0c;直到链表的下一个地址为 0。如果 DMA 使能了完成中断&#xff0c;则当 DMA 发送或者接收…

程序计数器介绍

程序计数器是计算机处理器中的寄存器&#xff0c;它包含当前正在执行的指令的地址(位置)。当每个指令被获取&#xff0c;程序计数器的存储地址加一。在每个指令被获取之后&#xff0c;程序计数器指向顺序中的下一个指令。当计算机重启或复位时&#xff0c;程序计数器通常恢复到…

java微服务技术选型,Java学习的三个终极问题及学习路线规划

前言 在网络技术中基于浏览器的B/S结构无论在PC端还是手机端都充当着至关重要的角色。 PC端自不必说&#xff0c;手机中很多应用虽然是以APP的形式存在&#xff0c;但它采用的还是B/S结构。如今日头条、微信的朋友圈等&#xff0c;这些应用在内部封装了浏览器&#xff0c;后端…

宠物的异味,用空气净化器可以解决吗?宠物空气净化器品牌推荐

养猫的人都了解&#xff0c;一个养猫家庭的环境卫生和气味问题与主人的关系密切相关。主人的勤劳程度和对卫生的重视程度直接影响着家中的气味。尽管主人通常会经常更换猫砂&#xff0c;但有时候仍然会存在一些难闻的气味。事实上&#xff0c;忙碌的猫主人可能会因为没有足够的…

MySQL Strict Mode is not set for database connection ‘default‘

在使用 DJango 框架执行迁移文件的命令时&#xff0c;可以看到出现如下警告&#xff1a; (ll_env) D:\workspace\workspace-mengll\learning-log>python manage.py migrate System check identified some issues: WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set …

【yolov8自带脚本划分数据集】yolov8自己数据集训练

1. 命令 ultralytics.data.utils.autosplit(pathDATASETS_DIR / coco8/images, weights(0.9, 0.1, 0.0), annotated_onlyFalse)from ultralytics.data.utils import autosplitautosplit( path"path/to/images",weights(0.9, 0.1, 0.0), # (train, validation, test)…

利用Python爬取高德地图全国地铁站点信息

利用Python中的requests库进行地铁站点信息的获取,同时将数据保存在本机excel中 # 首先引入所需要的包 import requests from bs4 import BeautifulSoup import pandas as pd import json# 发送 GET 请求获取网页内容 url http://map.amap.com/subway/index.html response r…

腾讯云服务器99元一年是真的吗?又降价,现在只要61元

腾讯云服务器99元一年是真的吗&#xff1f;又降价&#xff0c;现在只要61元。腾讯云服务器多少钱一年&#xff1f;61元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器165元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;…

LiveGBS流媒体平台GB/T28181功能-集中录像存储前端设备录像回看解决方案设备录像|云端录像|实时录像说明

LiveGBS集中录像存储前端设备录像回看解决方案设备录像|云端录像|实时录像说明 1、平台概述2、视频录像2.1、设备录像2.1.1、存储位置2.1.1.1、下级硬件设备2.1.1.2、下级国标平台 2.1.2、页面操作2.1.2.1、国标设备2.1.2.1.1、查看通道2.1.2.1.1.1、设备录像 2.1.2.1.2、配置中…

分布式事务(SeataClient)

问题场景 元数据 库存 100订单记录为空下单操作 @AutowiredRestTemplate restTemplate;/*** 下单** @return*/@Transactional // 开启事务 异常后触发数据库回滚操作@Overridepublic Order create(Order order) {// 插入订单orderMapper.insert(order);// 扣减库存 MultiValu…

前缀和+哈希表:联手合击Leetcode 560.和为k的子数组

题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,2…

IP劫持的危害及应对策略

随着互联网的发展&#xff0c;网络安全问题日益凸显&#xff0c;其中IP劫持作为一种常见的网络攻击手段&#xff0c;对个人和企业的信息安全造成了严重的威胁。IP数据云将分析IP劫持的危害&#xff0c;并提出相应的应对策略。 IP地址查询&#xff1a;IP数据云 - 免费IP地址查询…

Android开发经典实战,Android面试题目

关于Android的近况 大家都知道&#xff0c;今年移动开发不那么火热了&#xff0c;完全没有了前两年Android开发那种火热的势头&#xff0c;如此同时&#xff0c;AI热火朝天&#xff0c;很多言论都说Android不行了。其实不光是Android&#xff0c;iOS也有类似的言论。 那么到底…

java多线程编程(四)-----线程池

一.线程池的介绍 java中的池是非常重要的思想方法&#xff0c;比如内存池&#xff0c;进程池&#xff0c;连接池&#xff0c;常量池等等。本篇重点介绍java中的线程池。这里的这些池的概念都是一样的&#xff0c;比如做饭的时候&#xff0c;有烧水&#xff0c;切菜&#xff0c…