Vue之router和vuex

news2024/9/29 17:23:58

Vue之router和vuex

在学习之前,我们可以先安装一个插件,是一个浏览器插件,这个插件的作用是可以让我们更好的观察到数据的变化和状态的变更
在这里插入图片描述
他是一个github的链接,如果你没办法科学上网的话,也可以在
插件下载
上面这个链接下载后安装,安装就不讲了吧
对于router和vuex的安装,可以在创建项目的时候安装,也可以后续再加插件,比较无脑的办法就是启动cmd,启动vue的ui管理

vue ui

在这里插入图片描述
然后搜索安装即可
安装完成后会有这两个文件夹
在这里插入图片描述
我们先来看一下这两个文件
router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'  //1、引用了VueRouter这个库,就是咱们在创建项目的时候选择了VueRouter即可
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter) //2、引入了VueRouter这个官方插件

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]
//3、new VueRouter,创建了一个VueRouter的实例
const router = new VueRouter({
  routes
})
//4、导出这个实例,供项目使用
export default router

再来看store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
//和router/index.js是类似的
export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

那么,被创建的router和vuex的实例在哪里使用的呢
答案是根目录的main.js

在这里插入图片描述
这个时候,整个Vue项目就有了router个vuex的功能了

router

基础使用

接下来我们先讲解一下router基础的功能

import Vue from 'vue'
import VueRouter from 'vue-router'  
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter) 
const routes = [
  {
    // 3、path就是你跳转的路径
    path: '/',
    //4、这个name参数,是在比如说你的path很长的时候,例如 '/xxxx/eeee/cccc/vvv/vvv/ggg',可以通过name的value,也就是home来替代path,就比较方便跳转
    name: 'home',
    //5、这个地址对应的显示的组件是哪个,就由这个参数来决定,这个路径是通过import HomeView from '../views/HomeView.vue' import的方式来引用的
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    //6、这个是通过异步的方式,里面还有一个webpack的魔法注释,是为了让webpack打包的时候可以让多个组件统一打包
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]
const router = new VueRouter({
  //1、history,看起来更好看,IE10及以上支持,一下需要单独处理
  //mode设置为空.默认是hash模式的,或者设置成 mode: 'hash'  也可以,这种模式的优点在于兼容性更好
  mode: 'history',
  //2、这个routes就是上面const routes定义的变量,里面存放的是真正的路由信息
  routes
})
export default router

针对第一点
history模式
在这里插入图片描述
hash或者默认模式
在这里插入图片描述

针对第三点和第四点,包括这些组件是在哪里定义的,我们来看一下
在这里插入图片描述

<template>
  <div id="app">
    <nav>
      <!-- 1、这是一个链接的标签,外面显示的名字时Home,点击后,就根据router/index.js设置的路由跳转到了Home这个组件 -->
      <router-link to="/">Home</router-link> |
      <!-- 2、相应的,这个就是跳转到了AboutView这个组件 -->
      <router-link to="/about">About</router-link> |
      <!-- 3、还记得router/index.js的第三点和第四点,我们可以通过下面这种方式来替换上面的跳转方式,通过 :to来绑定,{name: 'about'}的name,就是表示我要用name的方式来跳转,后面的about就是router/index.js的第4点的name的value -->
      <router-link :to="{name: 'about'}">About2</router-link>
    </nav>
    <!-- 4、那上面这两个跳转的了对应的组件页面,展示在哪里呢,就是展示router-view标签的位置,也就是App这个组件,在这里留了一块地方,供子组件使用 
    它没有展示在上面,而是展示在了跳转链接的下面,就是在这里定义的-->
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

在这里插入图片描述
接下来我们可以自己写一个页面
在这里插入图片描述

<template>
    <h3>一级组件:视频信息</h3>
</template>
<script>
export default {
    name: 'VideoView'
}
</script>
<style>

</style>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'  
import HomeView from '../views/HomeView.vue'
// 1、引入我们新写的页面
import VideoView from '../views/VideoView.vue'

Vue.use(VueRouter) 
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  // 2、配置好跳转信息
  {
    path:'/video',
    name:'video',
    component: VideoView
  }
]
const router = new VueRouter({
  mode: 'history',
  routes
})
export default router

App.vue

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <!-- 1、配置好跳转链接 -->
      <router-link :to="{name: 'video'}">Video</router-link>
    </nav>
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

在这里插入图片描述

动态路由

上面这些都是基本的使用,下面我们来讲一下动态路由
比如说上面我们新建的视频组件,那我们可能有第一个视频第二个视频第三个视频

  {
    path:'/video/323',
    name:'video',
    component: VideoView
  }

就像上面一样,组件的内容是一样的,只是要处理的视频的id不一样,类似于商品id

我们首先对router/index.js修改

import Vue from 'vue'
import VueRouter from 'vue-router'  
import HomeView from '../views/HomeView.vue'
import VideoView from '../views/VideoView.vue'

Vue.use(VueRouter) 
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    // 1、当后面有:的时候,就代表是动态的,就是动态路由
    path:'/video/:id',
    name:'video',
    component: VideoView,
    // 2、当动态路由设置好之后,如果你想要在组件内部访问到这个id的话,就需要配置如下内容
    props: true
  }
]
const router = new VueRouter({
  mode: 'history',
  routes
})
export default router

再修改对应的组件VideoView.vue

<template>
    <div>
        <h3>一级组件:视频信息</h3>
        <!-- 2、这里只是为了方便展示而已,在这里打印出来 -->
        <p>视频id为:{{ id }}</p>
    </div>
</template>
<script>
export default {
    name: 'VideoView',
    // 1、在组件中通过props来承接链接中传进来的id这个值
    props:['id']
}
</script>
<style>

</style>

最后修改父组件传递动态信息

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <!-- 1、如果通过path的方式来传递值的话,就直接在路径中拼好 -->
      <router-link to="/video/321">VideoPath</router-link> |
      <!-- 2、通过:to的方式绑定的话, 需要通过params这个参数来传递值-->
      <router-link :to="{name: 'video',params:{id:28}}">VideoBind</router-link>
    </nav>
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

在这里插入图片描述
在这里插入图片描述

嵌套路由

比如说对于28这个视频id,我还要对这个视频进行一些分析,比如说点赞信息,还有二级功能,说人话就是
例如
视频的路径是 ‘video/30’
点赞信息的路径是’/video/30/info’
对于路径来说 ‘video/30’,这段是根基,info是在根基的基础上跳转的

我们先来修改router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'  
import HomeView from '../views/HomeView.vue'
import VideoView from '../views/VideoView.vue'
// 3、我们在这里也先引入,然后根据这个信息去写对应的component
import VideoInfo1 from '../views/video/VideoInfo1.vue'
import VideoInfo2 from '../views/video/VideoInfo2.vue'

Vue.use(VueRouter) 
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path:'/video/:id',
    name:'video',
    component: VideoView,
    props: true,
    // 1、通过children关键字来处理嵌套路由,你看这个结构,是不是和一般的路由是一样的,所以很好理解,只不过这里的children是一个list,方便配置多个嵌套路由
    children:[
      // 2、在这里我只是先随便配置上,现在对应的component还没有,稍后写,我们先放两个
      {path:'info1',
       name: 'video-info1',
       component:VideoInfo1
      },
      {path:'info2',
      name: 'video-info2',
      component:VideoInfo2
     },
    ]
  }
]
const router = new VueRouter({
  mode: 'history',
  routes
})
export default router

接下来写对应的组件
在这里插入图片描述

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1'
}
</script>
<style>

</style>
<template>
    <div>
        <h3>二级组件:互动情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo2'
}
</script>
<style>

</style>

写好了,我们放在哪里了,当然是放到子路由对应的父路由的组件上,也就是
在这里插入图片描述

<template>
    <div>
        <h3>一级组件:视频信息</h3>
        <p>视频id为:{{ id }}</p>
        <!-- 1、在这里配置好跳转的地方,这个params可以不传,毕竟咱们也没用,但是如果要传值的话,正常情况下是应该传的,要不你怎么知道是哪个视频的点赞呢,对不对,使用的方式就和动态路由一致 -->
        <router-link :to="{name: 'video-info1',params:{id:28}}">点赞</router-link> |
        <router-link :to="{name: 'video-info2',params:{id:28}}">互动</router-link>
        <!-- 2、我们的子组件总要有展示的地方对不对,就需要router-view来确定位置 -->
        <router-view/>
    </div>
</template>
<script>
export default {
    name: 'VideoView',
    props:['id']
}
</script>
<style>

</style>

效果如下
在这里插入图片描述
在这里插入图片描述

编程式导航的处理方式

我们刚刚实现的是通过手动点击的方式来跳转的,那如果类似于你登录信息过期了,你再点击这个互动链接,就应该给你跳转到登录页面让你去登录,也就是主动跳转

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    // 1、created()涉及到了生命周期的内容,可以去看看,大致就是当组件创建完毕以后会执行的一个声明周期钩子
    created(){
        // 2、如果你要使用router的功能,可以通过this.$router访问到router实例,通过push去跳转到对应的地方,比如说我们就是跳转到了about页面,至于setTimeout,其实就是为了三秒后再跳转,要不直接跳转到的不就看不到过程了么
        setTimeout(()=>{
            this.$router.push({name:'about'})
        },3000)
    }
}
</script>
<style>

</style>

效果,我就不做动图了
下面这张是刚开始点击的样子
在这里插入图片描述
3秒钟后自动跳转
在这里插入图片描述
那我们在跳转的时候我还要做数据的传递怎么办

我们先看来数据如何传递

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    created(){
        setTimeout(()=>{
            // 1、我们这次修改为跳转到video-info2,然后通过query的方式来传递信息,也就是3秒后会跳转到video-info2,并做一些数据传递
            this.$router.push({name:'video-info2',query:{someData:'video-info1传递的信息'}})
        },3000)
    }
}
</script>
<style>

</style>

接下来看数据的接收

<template>
    <div>
        <h3>二级组件:互动情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo2',
    created(){
        // 1、如果你要操作路由的话,那就是router,但是如果你要看路由相关的数据,例如地址呀,响应的参数呀,通过route来操作,就是在这里接收数据的
        // 但是需要注意的是,只有通过info1跳转过来的时候加了,其他的位置是没有加的
        console.log(this.$route.query)
    }
}
</script>
<style>

</style>

在这里插入图片描述
在这里插入图片描述

导航守卫

import Vue from 'vue'
import VueRouter from 'vue-router'  
import HomeView from '../views/HomeView.vue'
import VideoView from '../views/VideoView.vue'
import VideoInfo1 from '../views/video/VideoInfo1.vue'
import VideoInfo2 from '../views/video/VideoInfo2.vue'

Vue.use(VueRouter) 
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path:'/video/:id',
    name:'video',
    component: VideoView,
    props: true,
    children:[
      {path:'info1',
       name: 'video-info1',
       component:VideoInfo1
      },
      {path:'info2',
      name: 'video-info2',
      component:VideoInfo2
     },
    ]
  }
]
const router = new VueRouter({
  mode: 'history',
  routes
})

// 比如说我要在每次路由跳转的时候都做一些操作,比如说加一个进度条啊什么的,那么就需要这个导航守卫,导航守卫有三个参数,to,from,next,to代表去哪里,from代表来自哪里,next,如果你不加next就不会跳转页面,也就什么都不渲染
router.beforeEach((to,from,next)=>{
    console.log('路由触发了')
    next()
})
export default router

结果就是每跳转一次路由,都会出发守卫
在这里插入图片描述

vuex

就是一个统一的数据存储方式,一共就提供了五个功能

数据的存储

store/index.js文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
//和router/index.js是类似的
export default new Vuex.Store({
  // state,存储数据的地方,全局数据,其他任意组件的位置都可以来访问,但是建议将官方的注释掉,用下面这种方式
  // state: {
  // },
  state(){
    return{
      loginStatus:'用户已经登录'
    }
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

那我们想要访问的话,比如说我想要在video-info1里访问

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    created(){
        // 通过this.$store来访问store
        console.log(this.$store.state.loginStatus)
    }
}
</script>
<style>

</style>

在这里插入图片描述

数据的变更

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state(){
    return{
      loginStatus:'用户已经登录',
      // 1、新增一个count值,方便后续修改操作
      count: 0
    }
  },
  getters: {
  },
  //2、 如果你要修改数据的话,就在mutations里操作,因为虽然可以直接通过赋值的方式来修改,但是不建议这么做,因为如果数据变了,有N个组件,你不知道是哪个组件变更了这个数据,不好维护全局的状态数据
  // 这个里面就是一个个方法,封装了对每一个state中存储的全局变量做变更的方法供所有组件使用,就相当于一个method
  mutations: {
    // 3、这个state就是上面的state,存储数据的state,你看得vue的组件里,我们都是用this.来访问组件里的数据,但是在vuex里,我们用的是state来代替this
    changeCount(state,num){
      // 4、这里就是传入多少,就为count加多少
      state.count+=num
      console.log('mutations执行了,count的值为:',state.count)
    }
  },
  actions: {
  },
  modules: {
  }
})

在哪里调用呢

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
        <button v-on:click="handler">调用全局方法</button>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    created(){
        console.log(this.$store.state.loginStatus)
    },
    methods:{
        // 1、我们加methods,因为全局变量一般都是在主逻辑的某一个地方,要用的时候才去使用,比如说点击了某个按钮
        handler(){
            // 2、注意,不是直接去访问mutations,而是通过commit的方式来做一个提交,第一个参数是方法的名称,第二个参数就是方法的入参了
            this.$store.commit('changeCount',1)
            this.$store.commit('changeCount',1)
            this.$store.commit('changeCount',1)
        }
    }
}
</script>
<style>

</style>

结果
在这里插入图片描述
还记得当时安装的插件么,现在可以用上了
在这里插入图片描述
里面还有一个重要的功能叫TimeLine
比如我们先刷新一下页面
再点击按钮,观察TimeLine
在这里插入图片描述
它记录了状态的变更,以及对应的时间,但是只能记录同步的,如果是异步的话,就只能记录一个结果

异步结果的变更

import Vue from 'vue'
import Vuex, { Store } from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state(){
    return{
      loginStatus:'用户已经登录',
      count: 0
    }
  },
  getters: {
  },
  mutations: {
    changeCount(state,num){
      state.count+=num
      console.log('mutations执行了,count的值为:',state.count)
    }
  },
  actions: {
    delayChangeCount(store,num){
      // 1、还记得上面说的,要修改数据,只能在mutations里,而且是通过commit的方式,那actions也不例外,和组件一样,也是调用mutations的方法  ,action里面全是异步的操作   
      setTimeout(()=>{
        store.commit('changeCount',num)
      },3000)
    }
  },
  modules: {
  }
})


我们还在VideoInfo1中使用

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
        <button v-on:click="handler">调用全局方法</button>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    created(){
        console.log(this.$store.state.loginStatus)
    },
    methods:{
        handler(){
            this.$store.commit('changeCount',1)
            this.$store.commit('changeCount',2)
            // 这次不是用commit了,而是用dispatch,执行、发送的意思
            this.$store.dispatch('delayChangeCount',10)
            this.$store.commit('changeCount',3)
        }
    }
}
</script>
<style>

</style>

结果
在这里插入图片描述
顺序是,先调用了2次changeCount,然后执行第三个也就是异步方法delayChangeCount的时候,需要等待三秒,就先执行了第四次changeCount,等三秒,执行了delayChangeCount方法里的changeCount,通过参数也可以看到

计算属性

import Vue from 'vue'
import Vuex, { Store } from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state(){
    return{
      loginStatus:'用户已经登录',
      count: 0
    }
  },
  // 1、就相当于我们的计算属性,是带有缓存属性的,就像插件的computed方法,如果参数不变,不管调用几次,只计算一次
  getters: {
    len(state){
      console.log('getters执行了')
      // 2、返回了state.loginStatus的长度
      return state.loginStatus.length
    }
  },
  mutations: {
    changeCount(state,num){
      state.count+=num
      console.log('mutations执行了,count的值为:',state.count)
    }
  },
  actions: {
    delayChangeCount(store,num){
      setTimeout(()=>{
        store.commit('changeCount',num)
      },3000)
    }
  },
  modules: {
  }
})

调用方法

<template>
    <div>
        <h3>二级组件:点赞情况分析</h3>
        <button v-on:click="handler">调用全局方法</button>
    </div>
</template>
<script>
export default {
    name: 'VideoInfo1',
    created(){
        console.log(this.$store.state.loginStatus)
    },
    methods:{
        handler(){
            this.$store.commit('changeCount',1)
            this.$store.commit('changeCount',2)
            this.$store.dispatch('delayChangeCount',10)
            this.$store.commit('changeCount',3)
            // 这次也不是commit也不是dispatchle ,而是使用getters.方法名来调用对应方法了
            console.log(this.$store.getters.len)
            console.log(this.$store.getters.len)
            console.log(this.$store.getters.len)
            console.log(this.$store.getters.len)
            console.log(this.$store.getters.len)
        }
    }
}
</script>
<style>

</style>

结果
在这里插入图片描述
打印了5次,没错,但真正调用只调用了一次

模块管理

import Vue from 'vue'
import Vuex, { Store } from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state(){
    return{
      loginStatus:'用户已经登录',
      count: 0
    }
  },
  getters: {
    len(state){
      console.log('getters执行了')
      return state.loginStatus.length
    }
  },
  mutations: {
    changeCount(state,num){
      state.count+=num
      console.log('mutations执行了,count的值为:',state.count)
    }
  },
  actions: {
    delayChangeCount(store,num){
      setTimeout(()=>{
        store.commit('changeCount',num)
      },3000)
    }
  },
  modules: {
    // 1、比如说state中的两个值,可能只是和user有关的,在一个app里很多功能,比如购物功能等,那如果不同的功能有不同的全局处理,比如说a里面有两个值,这两个值又不想被b用,这种情况下为乐避免混乱,
    //让数据更好管理,就需要使用模块,也就是modules
    a:{
      state, 
      getters,
      mutations,
      actions,
      modules
    },
    // 2、里面的内容就和store/index.js几乎是一样的,按需添加
    b:{
      state, 
      getters,
      mutations,
      actions,
      modules
    }
  }
})

使用
调用前,加上对应模块的名称即可
在这里插入图片描述
但是既然已经模块化了,那就索性再模块一下,在store模块下面再新建一个modules文件夹,下面新建a.js、b.js, 里面的内容替换掉modules中对应模块的内容
在这里插入图片描述

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

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

相关文章

CodeQL在代码审计中的应用

一、CodeQL简介 CodeQL是一种基于静态分析的程序分析工具&#xff0c;由GitHub开发和维护。截止到此刻&#xff0c;CodeQL在Github上已经有超过6100个Star。它可以用于发现代码中的漏洞、代码质量问题和安全问题。CodeQL使用了一种特殊的编程语言QL&#xff08;查询语言&#…

【Unity项目】Unity实现 双屏显示效果

需求&#xff1a;两个屏显示项目&#xff0c;一个屏显示列表&#xff0c;一个屏显示列表按钮点击后的效果。 最近在修改一个项目&#xff0c;是要求分屏显示项目&#xff0c;一个一体机&#xff0c;一个大屏&#xff0c;一体机当作目录界面&#xff0c;大屏当作模型显示界面&am…

NC140 排序

冒泡排序 public int[] BubbleSort(int[] arr) {// write code herefor (int i 0; i < arr.length - 1; i) {for (int j 0; j < arr.length - 1 - i; j) {if (arr[j] > arr[j 1]) {int temp arr[j];arr[j] arr[j 1];arr[j 1] temp;}}}return arr;}插入排序 p…

HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0的关系和区别

文章目录 一、对比二、HTTP1.0三、HTTP1.1四、HTTP2.0四、HTTP/3.0五、总结 一、对比 二、HTTP1.0 浏览器的每次请求都需要与服务器建立一个TCP连接&#xff0c;服务器处理完成后立即断开TCP连接&#xff08;无连接&#xff09;&#xff0c;服务器不跟踪每个客户端也不记录过去…

如何使用js对图像进行压缩

JavaScript 可以使用类似于 canvas 和 web workers 来实现图像压缩。 使用 canvas&#xff0c;可以将图像绘制到 canvas 上&#xff0c;然后使用 canvas 提供的 toBlob() 或 toDataURL() 方法将其转换为不同格式的图像。在这些方法中指定图像质量参数即可实现压缩。 使用 web…

python接口自动化(二十)--token登录(详解)

简介 为了验证用户登录情况以及减轻服务器的压力&#xff0c;减少频繁的查询数据库&#xff0c;使服务器更加健壮。有些登录不是用 cookie 来验证的&#xff0c;是用 token 参数来判断是否登录。token 传参有两种一种是放在请求头里&#xff0c;本质上是跟 cookie 是一样的&…

【JS】自调用函数(自执行函数)

文章目录 自调用函数&#xff1a;只能自己在定义的同时调用自己一次&#xff0c;对外界不可见。 语法 // 函数名加与不加都可以 (function 函数名(形参){console.log(11); })(实参)使用&#xff1a; // 用法一 const str 流星; (function (params){console.log(params); // …

33.RocketMQ之Broker启动源码

highlight: arduino-light Broker启动流程:BrokerStartup#main java public static void main(String[] args) { //手动指定了 nameServer start(createBrokerController(args)); } java public static BrokerController start(BrokerController controller)…

Docker开启远程端口访问2375

开启方法&#xff1a; 1、修改/etc/default/docker下的配置 cat >> /etc/default/docker <<EOF DOCKER_OPTS"-H tcp://0.0.0.0:2375" EOF systemctl restart docker 2、修改/usr/lib/systemd/system/docker.service配置 cat >> /usr/lib/systemd/s…

第四章 网络层【计算机网络】

第四章 网络层【计算机网络】 前言推荐第四章 网络层4.1 网络层的几个重要概念4.1.1 网络层提供的两种服务4.1.2 网络层的两个层面 4.2网际协议IP4.2.1 虚拟互连网络4.2.2 IP地址4.2.3IP地址与硬件地址4.2.4地址解析协议ARP4.2.5IP数据报的格式 4.3 IP层转发分组的过程4.3.1 基…

个人域名邮箱无法给gmail发邮件

问题描述 我注册了一个域名 mydomain.com, 并在此域名下创建了 mailbox&#xff0c;从该邮箱向外发送邮件和接收邮件会失败。 主要是一些配置工作没有做好。 接收邮件 当创建邮箱 xxxmydomain.com&#xff0c;尝试向该邮箱发送邮件时&#xff0c;邮件会被拒收&#xff0c;并…

选择正确的负载均衡器:LVS还是Nginx?

选择正确的负载均衡器&#xff1a;LVS还是Nginx&#xff1f; 博主简介一、前言二、什么是LVS&#xff1f;2.1、LVS的架构 三、什么是Nginx&#xff1f;3.1、Nginx 特性3.2、Nginx 架构 四、LVS和Nginx的区别五、总结 博主简介 &#x1f4a1;一个热爱分享高性能服务器后台开发知…

windows环境下根据端口号查询进程编号并杀掉此进程

说在前面 当端口号备占用时&#xff0c;我们需要找到占用端口的进程&#xff0c;然后杀掉该进程&#xff0c;即可 开干 1、找占用端口的进程&#xff0c;比如现在是3306端口备占用了 netstat -nao|findstr 3306运行如下&#xff1a; 2、杀掉进程&#xff0c;比如进程号为…

【InnoDB 存储引擎】15.4 InnoDB Architecture

文章目录 1 InnoDB 存储引擎结构2 参考资料 1 InnoDB 存储引擎结构 下面的图显示了内存和磁盘结构组成InnoDB存储引擎架构 内存结构&#xff1a;Section 15.5, “InnoDB In-Memory Structures” Buffer Pool&#xff08;缓冲池&#xff09;Change Buffer&#xff08;修改缓冲&…

JavaScript笔记——快速了解 ES6 新增字符串方法,开箱即用(含案例)

文章目录 &#x1f4cb;前言&#x1f3af;includes() 方法&#x1f3af;startsWith() 方法&#x1f3af;endsWith() 方法&#x1f3af;repeat() 方法&#x1f3af;padStart() 方法&#x1f3af;padEnd() 方法&#x1f3af;trim() 方法&#x1f3af;trimStart() 或 trimLeft() 方…

Atlassian Jira敏感信息获取

我是一个平凡的人&#xff0c;但一个平凡的人&#xff0c;也可以过得不平凡。 漏洞复现 构造payload /secure/ViewUserHover.jspa?usernameadmin用户名存在会返回&#xff0c;且版本在影响范围之内 用户名不存在会返回&#xff0c;且版本在影响范围之内 文笔生疏&#xff…

【雕爷学编程】Arduino动手做(155)---2262/2272四键无线遥控套件模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

基于单片机的教室智能照明台灯控制系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前时间、年月日、时分秒、前教室人数&#xff1b;2路红外探头用来感应当前教室进出人数&#xff1b;按键可以设置当前时间、自动手动模式、开启和关闭教室灯光时间&#xff1b;在手动模式下&#xff0c;可以通过按…

OpenCV图像金字塔pyrDown下采样

#include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp>using namespace cv;int main() {// Load the original imageMat srcImage

【C++ OJ练习】3.反转字母

1.题目链接 力扣 2.解题思路 前后分别给两个指针 进行遍历 找到字母后就交换 然后往下走 没找到就直接往下走 注意双循环条 件 3.代码 class Solution { public://判断是不是字符bool IsChar(char ch){if ((ch > a && ch < z)|| (ch > A && ch …