VUE笔记(六)vue路由

news2024/12/26 10:58:17

一、路由的简介

1、实现生活中的路由

路由:路由其实就是一个key-value对应关系

路由器:用于管理多个路由关系的设备被称为路由器

2、前端的路由

目前使用的前端项目都是单页面的应用(SPA),一个项目中只有一个html页面,这种项目是由很多个组件组成,组件之间如果要跳转要依靠路由来完成,路由是由key和value组成一个对应关系,前端路由的key就是url地址,路由的value就是组件本身

keyvalue
http://localhost:8080/loginLogin.vue
http://localhost:8080/registerRegister.vue

总之:路由是实现多个组件之间进行跳转一种方式,使用路由将各组件之间联系起来

由于vue是一个渐进式的前端框架,vue的核心语法中不包括路由,路由以插件的形式存在,如果要去使用路由就要去将路由集成到vue项目中

二、路由的基本配置

1、路由的配置

由于路由不是vue的核心功能,大家如果要使用就需要去单独集成它,在vue中使用路由最多一个路由产品vue-router

vue-router的官网:Vue Router

注意:vue2的项目,匹配的路由版本是vue-router@3

配置的具体步骤如下

  • 安装vue-router的依赖包

npm install vue-router@3.5.1
  • 在src目录创建router的文件夹,在router文件夹下创建index.js文件,具体代码如下

//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
//将VueRouter作为插件设置到Vue中
Vue.use(VueRouter)
//创建路由器对象
const router=new VueRouter()
//将这个路由器对象导出
export default router
  • 将路由挂载到vue实例上,在main.js文件中

import Vue from 'vue'
import App from './App.vue'
import router from '@/router'
Vue.config.productionTip = false
​
new Vue({
  render: h => h(App),
  router
}).$mount('#app')
​

2、一级路由的配置

路由是一个key-value的对应关系

  • 创建组件

    在src/views目录下分别创建Login.vue、Register.vue、Home.vue

  • 路由配置

    在src/router/index.js进行如下配置

//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
//导入组件
import Login from '@/views/Login'
import Register from '@/views/Register'
import Home from '@/views/Home'
//将VueRouter作为插件设置到Vue中
Vue.use(VueRouter)
//创建routes数组
const routes=[
    {
        path:'/login',
        component:Login
    },
    {
        path:'/register',
        component:Register
    },
    {
        path:'/home',
        component:Home
    }
]
/*
  创建路由器对象
  const router=new VueRouter(config)
  config:路由的配置对象
  routes:路由配置的数组
*/
const router=new VueRouter({
    routes
})
//将这个路由器对象导出
export default router

3、路由的出口设置

如上已经将路由的规则配置成功了,如果要显示在页面上,就需要配置路由出口

在App.vue根组件中配置路由出口

<template>
    <router-view></router-view>
</template>

4、路由的跳转

使用vue-router进行路由跳转有两种方式

  • 标签式跳转方式:使用<router-link>这个标签进行跳转,一般使用在<template></template>模板之中,最终会编译成<a>标签

  • 编程式跳转方式:使用this.$router对象的push或者replace方法进行跳转的,这种跳转方式一般使用在组件的js代码部分

4.1、标签式路由跳转的案例
已有账号?<router-link to="/login">前往登录</router-link>
4.2、编程式路由跳转
  • 下载axios

npm i axios
  • 配置package.json

"scripts": {
    "serve": "vue-cli-service serve",
    "serve:production": "set NODE_ENV=production&vue-cli-service serve",
    "build": "vue-cli-service build"
 }
  • 封装auth.js方法,完成token获取和设置的封装

    位置:src/utils/auth.js

const tokenkey="admin-token"
// 保存token到localStorage中的方法
export const setToken=tokenval=>localStorage.setItem(tokenkey,tokenval)
// 从localStorage中获取token
export const getToken=()=>localStorage.getToken(tokenkey)
  • 封装axios

位置:src/api/request.js

import axios from 'axios'
import {getToken} from '@/utils/auth'

/* 
    基础路由的配置
*/
switch(process.env.NODE_ENV){
    case 'production':
        axios.defaults.baseURL="http://47.98.128.191:3000/"
        break;
    default:
        axios.defaults.baseURL="http://www.zhaijizhe.cn:3005"
        break
}
/* 
    设置请求拦截器
*/
axios.interceptors.request.use(config=>{
    //获取token的信息,然后将token信息携带到请求头信息中
    if(getToken){
        config.headers.Authorization=getToken()
    }
    return config
})
/* 
   设置响应拦截器
*/
axios.interceptors.response.use(response=>{
    return response.data
},err=>{
    if(err.response){
        switch(err.response.status){
            case 401:
                break
            case 404:
                break
            case 500:
                break
        }
    }
})

export default axios
  • 编写登录api方法

位置:src/api/modules/users.js

import request from '@/api/request'
export default{
    login:(data)=>request.post('/users/login',data)
}
  • 汇总模块

位置:src/api/api.js

import users from "./modules/users";
export default{
    users
}
  • 挂载api到Vue原型上

位置:src/main.js

import api from '@/api/api'
Vue.prototype.$api=api
  • 组件中完成登录

位置:src/views/Login.vue

<template>
    <div>
        <h1>登录</h1>
        <div>
            没有账号?<router-link to="/register">前往注册</router-link>
        </div>
        <div>
            <div>
                <label for="username">姓名:</label>
                <input id="username" type="text" placeholder="请输入登录账户" v-model="user.username">
            </div>
             <div>
                <label for="password">密码:</label>
                <input id="password" type="text" placeholder="请输入登录账户" v-model="user.password">
            </div>
            <div>
                <button @click="login">登录</button>
            </div>
        </div>
    </div>
</template>

<script>
import {setToken} from '@/utils/auth'
export default {
    data(){
        return{
            user:{
                username:'admin',
                password:'123'
            }
        }
    },
    methods:{
        async login(){
           let {code,message,token}=await this.$api.users.login(this.user)
           /* 
             登录成功后,要完成的事项有两个
             1、保存token到localStorage中
             2、使用路由进行跳转
           */
          setToken(token)
          if(code){
            alert(message)
            //跳转到后台,使用编程式路由跳转
            this.$router.replace('/home')
          }
        }
    }
}
</script>

<style>

</style>

5、路由的嵌套

  • 如果要配置二级路由,需要在相应的一级路由对象上添加children属性,然后进行配置

位置:src/router/index.js

{
        path:'/home',
        component:Home,
        children:[
            {
               path:'workplace',//二级路由的path的前不要带/
               component:workplace
            },
            {
                path:'analysis',
                component:analysis
            },
            {
                path:'studentList',
                component:studentList
            }
        ]
    }
  • 静态菜单

位置:src/views/Home.vue

<template>
    <div class="container">
       <div class="header">
            <div class="logo">学苑BOSS系统</div>
       </div>
       <div class="main">
            <div class="silder">
                <ul>
                    <li>
                        <span>控制面板</span>
                        <ul class="sul">
                            <li>
                                <router-link to="/home/workplace">工作台</router-link>
                            </li>
                            <li>
                                <router-link to="/home/analysis">统计报表</router-link>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <span>学员管理</span>
                        <ul class="sul">
                            <li>
                                <router-link to="/home/studentList">学生列表</router-link>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <span>系统管理</span>
                        <ul class="sul">
                            <li>班主任管理</li>
                            <li>教师管理</li>
                            <li>专业管理</li>
                            <li>班级管理</li>
                        </ul>
                    </li>
                </ul>
            </div>
            <div class="content">
                <!-- 设置二级路由的出口 -->
                <router-view></router-view>
            </div>
       </div>
    </div>
</template>

<script>
export default {

}
</script>

三、路由的其他配置

1、路由的重定向

所谓的路由重定向就是指当你输入一个路由的路径时候,它会自动重新跳转到另外一个路由上这种行为称为路由重定向

 {
        path:'/',
        redirect:'/home'
 },

2、路由懒加载

为了提高首屏加载速度,可以采用路由懒加载的方式,提升加载性能,避免白屏现象出现

//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//创建routes数组
const routes=[
    {
        path:'/login',
        component:()=>import('@/views/Login')
    },
    {
        path:'/register',
        component:()=>import('@/views/Register')
    },
    {
        path:'/',
        redirect:'/home'
    },
    {
        path:'/home',
        component:()=>import('@/views/Home'),
        children:[
            {
               path:'workplace',//二级路由的path的前不要带/
               component:()=>import('@/views/dashboard/workplace.vue')
            },
            {
                path:'analysis',
                component:()=>import('@/views/dashboard/analysis.vue')
            },
            {
                path:'studentList',
                component:()=>import('@/views/students/studentList.vue')
            }
        ]
    }
]
const router=new VueRouter({
    routes
})
//将这个路由器对象导出
export default router

3、缓存路由

  • 为需要设计缓存组件取一个名称

export default {
    name:'analysis'
}
  • 在路由的出口的地方设置keep-alive

 <keep-alive exclude="analysis">
         <router-view></router-view>
 </keep-alive>
  • exclude:该组件不被缓存

  • include:该组件会被缓存

4、路由的元信息

路由对象有很多属性,核心有两个,一个就是path,表示的路由的路径,component表示的是路由的对应的组件,除此之外还有其他的属性,比如meta属性,可以设置路由的额外信息,这里以两个例子给大家讲解

4.1、面包屑的功能
  • 需要在路由定义的时候在相应的路由配置对象中添加meta属性,配置面包屑的具体配置

{
       path:'workplace',//二级路由的path的前不要带/
       component:()=>import('@/views/dashboard/workplace.vue'),
       meta:{
          firstTitle:'控制面板',
          secondTitle:'工作台'
      }
},
  • 自定义面包屑组件

在src/components目录下创建BreadCrumb组件

<template>
    <div>
        <span>{{$route.meta.firstTitle}}</span>&gt;<span>{{$route.meta.secondTitle}}</span>
    </div>
</template>
  • 在需要的组件中引入面包屑组件

<template>
    <div>
        <bread-crumb></bread-crumb>
        <h1>学生列表</h1>
    </div>
</template>
4.2、路由缓存状态设置
  • 在路由配置中为meta属性设置isKeepAlive属性

{
        path:'workplace',//二级路由的path的前不要带/
        component:()=>import('@/views/dashboard/workplace.vue'),
        meta:{
            firstTitle:'控制面板',
            secondTitle:'工作台',
            iskeepAlive:true
      }
 },
  • 在路由出口的地方通过v-if指令来完成设置

 <keep-alive>
    <router-view v-if="$route.meta.iskeepAlive"></router-view>
 </keep-alive>
 <router-view v-if="!$route.meta.iskeepAlive"></router-view>

说明:这种设置方式较之前使用include或者exclude方式的更加合理。

四、路由传参

1、学生列表

  • 编写获取学生的api方法

import request from '@/api/request'
export default{
    getStudents:params=>request.get('/students/getStudents',{params})
}
  • 汇总api

import users from "./modules/users";
import students from "./modules/students";
export default{
    users,students
}

2、query传参

vue-router这个路由操作中,要进行传参有多种方式,比较常用的方式有两种

  • query传参方式

  • params传参方式

query传参的步骤

第1步:创建页面组件,配置路由

 {
        path:'studentDetail',
        component:()=>import('@/views/students/studentDetail.vue'),
        meta:{
            firstTitle:'学生管理',
            secondTitle:'学生详情'
        }
 }

第2步:进行传参

  • 标签跳转的方式

<router-link :to="`/home/studentDetail?_id=${item._id}`"><button class="btn detal">查看</button></router-link>
<router-link :to="'/home/studentDetail?_id='+item._id"><button class="btn detal">查看</button></router-link>
<router-link :to="{path:'/home/studentDetail',query:{_id:item._id}}"><button class="btn detal">查看</button></router-link>
//命名路由
<router-link :to="{name:'xsxq',query:{_id:item._id}}"><button class="btn detal">查看</button></router-link>

最后一种写法是使用了命名路由的写法,命名路由的好处就是使用name来指定要跳转位置

  • 编程方式进行跳转

goStudentDetail(_id){
      this.$router.push(`/home/studentDetail?_id=${_id}`)
}
goStudentDetail(_id){
    this.$router.push('/home/studentDetail?_id='+_id)
}
goStudentDetail(_id){
      this.$router.push({
        path:'/home/studentDetail',
        query:{
          _id
        }
      })
 }
 goStudentDetail(_id){
      this.$router.push({
        name:'xsxq',
        query:{
          _id
        }
      })
    }

第3步:接收路由参数

使用this.$route.query方式获取参数

export default {
    components:{BreadCrumb},
    created(){
        console.log(this.$route.query._id);
    }
}

$router和$route

面试题(简单的面试题)

  • router:它是一个VueRouter类型的一个对象,通过new VueRouter构造函数方式将其创建出来,它是一个全局对象

    • 设置路由模式

    • 实现路由跳转:通过该对象中push或者replace方法来实现跳转的

  • route:路由信息对象,它属于一个局部对象,该对象主要用来描述路由信息的

    • 获取该路由path路径

    • 获取该路由的传递的参数(query参数,params参数)

    • 获取该路由的meta信息(用户自定义的信息)

4、params传参

动态路由概念:所谓的动态路由是指路由地址的一部分是变化的,像这种我们将其称为动态路由

http://localhost:8080/#/home/studentUpadate/10001
http://localhost:8080/#/home/studentUpadate/10002
http://localhost:8080/#/home/studentUpadate/10003

如上操作,如果有多条信息,就需要在router/index.js中配置多个路由信息对象,这种做法不可取,原因有两个

  • 配置信息量特别大

  • 这种配置不灵活

为了解决这个问题,我们可以动态路由的方式进行配置,具体配置步骤如下

第1步:在路由配置文件中配置如下

 {
     path:'studentUpdate/:id',
     component:()=>import('@/views/students/studentUpdate.vue'),
     meta:{
         firstTitle:'学生管理',
         secondTitle:'修改学生'
     }
 }

第2步:路由跳转传参

根据跳转方式的不同

  • 标签方式跳转

 <router-link :to="`/home/studentUpdate/${item._id}`"><button class="btn detal">修改</button></router-link>
 <router-link :to="'/home/studentUpdate/'+item._id"><button class="btn detal">修改</button></router-link>
  • 编程方式跳转

 this.$router.push('/home/studentUpdate/'+_id)
  this.$router.push(`/home/studentUpdate/${_id}`)
 goStudentUpdate(_id){
       this.$router.push({
         name:'xsxg',
         params:{
           id:_id
         }
       })
    }

注意:如果要使用push方法的参数是配置对象形式参数,这种params只能和命名路由结合使用,不能和path一起使用

第3步:接收params参数

接收params参数有两个方法

  • 使用this.$route.params.参数名

 console.log(this.$route.params.id);
  • 使用props方式传参

配置步骤

首先:在路由对象设置可以使用props方式接收

{
                name:'xsxg',
                path:'studentUpdate/:id',
                component:()=>import('@/views/students/studentUpdate.vue'),
                meta:{
                    firstTitle:'学生管理',
                    secondTitle:'修改学生'
                },
                props:true 
}

其次:在接收参数的组件中设置props选项

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

最后,在组件中使用

export default {
   props:['id'],
   components:{
      BreadCrumb
   },
   created(){
      // console.log(this.$route.params.id);
      console.log('id:',this.id);
   }
}

5、修改学生

  • 页面返回和页面刷新

<button @click="$router.go(-1)">返回</button>
<button @click="$router.go(0)" >刷新</button>

五、路由模式【面试题】

由于Vue项目为单页面应用,所以整个项目在开发和构建过程中,仅存在一个HTML物理文件,通过路由系统可以实现将项目的组件与可访问的URL路径进行绑定。由于Vue项目只有一个HTML物理文件,切换页面时既需要让访问的URL路径发生变化,又不能触发HTML物理文件的重新加载,这就使得VueRouter的跳转模式不能使用普通的超链接方式。

VueRouter为了支持单页面应用的页面管理和页面跳转,提供了两种页面跳转和加载模式:

  • hash:在浏览器 URL 路径中会有一个'#'

  • history:在浏览器 URL 路径中没有'#'

1、hash模式

hash模式使用了锚点技术重写URL访问路径,会在原有的URL路径后拼接/#/xx,这种方式可以在不重新加载原有HTML文件的基础上,实现切换URL路径的目的,hash模式的原理案例,代码如下

<a href="#/index">首页</a>
    <a href="#/about">关于我们</a>
    <div class="page index">
        我是首页
    </div>
    <div class="page about">
        我是关于页面
    </div>
    <script>
        window.onhashchange=function(event){
            var newURL=event.newURL.split("#/")[1]
            var oldURL=event.oldURL.split("#/")[1]
            var newPage=document.querySelector('.'+newURL)
            var oldPage=document.querySelector('.'+oldURL)
            newPage.style.display="block"
            oldPage.style.display="none"
        }
    </script>

hash模式利用了纯静态技术,解决了单页面应用的页面划分,它可以在不触发网页重新加载的情况下切换URL路径,配合onhashchange可以实现,一旦URL中的hash部分发生变化,就触发函数通知,通过javascript编程便可以很快速的实现DOM对象的切换显示。

hash模式同时也存在着不足之处,如在分布式微前端项目中,嵌套的子应用和主应用都使用hash模式时,由于hash模式的URL路径只能存在一个#,会导致子应用和主应用在定义URL路径上存在着困难,hash模式的URL路径中包含#,也会在视觉上导致URL路径不美观

2、history模式

histroy模式是VueRouter中常用的一种路由模式,它与hash模式不同,不需要借助锚点技术重写URL路径,所以history模式使用的URL路径中不存在#,在视觉上更加美观,histroy模式采用histroy对象中的pushState()函数重写函数URL路径,可在触发重新加载的情况下变更URL路径,history的原理,代码如下

 <a href="javascript:jump('/index')">跳转到首页</a>
    <a href="javascript:jump('/about')">跳转到about页</a>
    <div class="page index">
        我是首页
    </div>
    <div class="page about">
        我是关于页面
    </div>
    <script>
       function jump(path){
        history.pushState(null,'page',path)
        var pages=document.querySelectorAll('.page')
        var newPage=document.querySelector(path.replace("/","."))
        pages.forEach(item=>item.style.display='none')
        newPage.style.display='block'
       }
    </script>

history模式重写URL路径的解决方案与hash模式现象类似,但本质不同,虽然histroy模式可以重写URL路径,但是重写后的新路径中并不包含原有HTML物理文件的访问路径,所以history模式在重写URL路径后,一旦刷新网页会造成404无法访问的效果,VueCli在开发环境中解决了history模式的刷新问题,不过项目发布到生产环境时,由于histroy模式的URL路径问题,还需要配合生产服务器的转发规则重写,用以支持history模式的路由加载。

可以在路由的配置文件中更改路由模式:

const router = new VueRouter({
    routes: routes,
    mode: 'history'
})

不设置 mode 属性,则默认为 hash 模式。

六、路由守卫

1、什么是路由守卫

当路由发生变化的时候,会触发的一些函数,我们这些函数中编写一定业务逻辑,这种函数称为路由守卫函数,也有人称为导航守卫

按照类型将导航守卫分为三大类

  • 全局前置守卫:当所有路由被触发的时候,在进入指定组件之前所触发的守卫函数

  • 路由独享守卫:触发指定路由的路由的时候触发

  • 组件内守卫:当离开组件的时候,或者进入组件的时候触发的守卫函数

2、全局前置守卫

2.1、语法
router.beforeEach((to,from,next)=>{
    
})

参数说明:

  • to:即将要进入目标路由对象

  • from:当前导航正要离开的路由

  • next:是一个函数,该函数的作用是进入到目标路由所指定的组件,或者按照要求进入到指定的组件

案例:防止没有token直接进入后台

第1步:在router/index.js中编写路由全局前置守卫函数,完成token验证

router.beforeEach(async(to,from,next)=>{
    console.log('********进入路由全局前置守卫************');
    if(to.path=="/login"||to.path=="/register"){
        console.log('即将要进入的是登录或者注册组件');
        //放行进入
        next()
    }else{
        //获取token
        let token=getToken()
        if(token){
            let result=await api.users.getUserInfo()
            if(result.code){
                next()//放行进入
            }
        }else{
            alert('您还没有登录,请先登录')
            next('/login')
        }
    }
})

第2步:在二次封装axios的文件中request.js中补全401状态时的执行业务逻辑

axios.interceptors.response.use(response=>{
    return response.data
},err=>{
    if(err.response){
        switch(err.response.status){
            case 401:
                console.log('进入到拦截器的401处理中');
                //弹框提示
                alert('您的token已失效,请重新登录') 
                //进行路由跳转
                router.push('/login')
                break
            case 404:
                break
            case 500:
                break
        }
    }
})

3、路由独享守卫

这种守卫函数,只针对于进入该路由所触发

{
        path:'/home',
        component:()=>import('@/views/Home'),
        children:[
        ],
        //如果进入该路由或者该路由下的子路由都会进入到这个守卫函数
        beforeEnter:async function(to,from,next){
           let token=getToken()
           if(token){
             let {code}=await Vue.prototype.$api.users.getUserInfo()
             if(code){
                next()
             }
           }else{
             alert('您还没有登录,请登录')
             next('/login')
           }
        }
    }

4、组件内守卫

写在组件中

   beforeRouteEnter:async function(to,from,next){
        console.log('------进入该组件---------');
        let result=await Vue.prototype.$api.users.getUserInfo()
        if(result.data.auth==1){
            console.log('------我是超级管理员-----------');
            next()
        }else if(result.data.auth==2){
            console.log('-------我是普通管理员----------------------');
            alert('您没有权限进入,请联系系统管理,为您开设权限')
        }
        // let result=await this.$api.users.getUserInfo()
        // console.log('result',result);
    },
    beforeRouteLeave(to,from,next){
        console.log('------离开该组件----------');
        if(this.name==''||this.fcz==''||this.startTime==''){
           if(window.confirm('您还没有输入完所有的信息,您确认你要离开吗?')){
             next()
           }
        }
    }

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

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

相关文章

网络学生用品商店系统设计与实现(论文+源码)_kaic

摘 要 随着互联网的发展&#xff0c;人们的生活发生了巨大的变化&#xff0c;给人们的生活、工作等方面带来了相当大的提高&#xff0c;电子化成为了节约成本、调高效率的代名词。电子商务是利用微电脑技术和网络通讯技术进行的商务活动&#xff0c;买卖双方通过网络所进行各…

亚马逊云科技 云技能孵化营 初识机器学习

目录 前言 一、课程介绍 二、什么是机器学习 三、机器学习算法进阶过程 四、亚马逊云科技能给我们什么 总结 前言 近期参加了“亚马逊云科技 云技能孵化营”&#xff0c;该孵化营的亚马逊云科技培训与认证团队为开发者准备了云从业者的精要知识及入门课程&#xff0c;帮助…

python 面试题--3(15题)

目录 Python中的生成器是什么&#xff1f;如何创建一个生成器&#xff1f; 解释Python中的递归函数及其使用场景。 Python中的迭代器和可迭代对象有什么区别&#xff1f; 什么是Python中的模块和包&#xff1f;它们有什么区别&#xff1f; 如何在Python中处理异常&#xf…

提升团队效率!探索多款热门一站式团队协作工具

“常见的几种团队协作工具有&#xff1a;Zoho Projects、Slack、Microsoft Teams、Asana、Trello等。” 团队协作已经成为了企业、组织和个人工作的重要组成部分。为了提高工作效率和协同能力&#xff0c;各种团队协作工具应运而生。本文将介绍团队协作工具的功能以及常见的几种…

E. Nastya and Potions - 记忆化搜索

分析&#xff1a; dfs永远都需要记忆化搜索&#xff0c;也算是优化技巧吧&#xff0c;首先不知道哪种方法更加好&#xff0c;本质就是找每种材料的最小费用&#xff0c;能通过几种费用更少的材料代替就可以将费用优化成更小&#xff0c;这也就需要dfs来找最小费用&#xff0c;但…

vue 实现word文档页面内预览docx-preview 和 vue-office

1.先下载引入 npm i docx-preview --save import { renderAsync } from docx-preview;2.使用 fetch(url) .then((response) > {let docData response.blob(); //将文件转换成bolb形式//选择要渲染的元素let childRef document.getElementsByClassName("childRef&qu…

单片机学习-蜂鸣器如何发出声音

硬件电路 软件编写 ①发出声音 #include "reg52.h" typedef unsigned int u16; // 重新定义 类型 typedef unsigned char u8; // 重新定义 类型sbit BEEP P2^5; //定义 P2第五个管教 为BEEP // 延时函数 void delay_time(u16 times) {while(times--); } vo…

从探索到明确,比特币与美股等传统资产相关性如何?

早期阶段&#xff0c;比特币经历了一段摸索和模仿的时期&#xff0c;这是因为当比特币刚刚出现时&#xff0c;比特币的价值和用途在这一阶段并不明确&#xff0c;人们对其性质和潜力还不太了解。 然而&#xff0c;随着时间的推移&#xff0c;比特币去中心化、固定供应上限等特点…

jmeter 性能测试用 csv

⏩很多人在使用 jmeter 做接口测试、自动化测试和性能测试时&#xff0c;都喜欢用 CSV 数据文件设置功能&#xff0c;来读取准备好的测试数据。虽然这种方法并不是最优方案&#xff0c;在我们的性能测试课程中&#xff0c;讲解了更优的方案&#xff0c;但是&#xff0c;没有上过…

红蓝攻防:浅谈削弱WindowsDefender的各种方式

前言 随着数字技术的日益进步&#xff0c;我们的生活、工作和娱乐越来越依赖于计算机和网络系统。然而&#xff0c;与此同时&#xff0c;恶意软件也日趋猖獗&#xff0c;寻求窃取信息、破坏系统或仅仅为了展现其能力。微软Windows&#xff0c;作为世界上最流行的操作系统&…

关于JAVA程序的内存分布

目录 1.Java程序运行时内存说明 2.JVM内存划分 3.Java中数据类型 4.Java中的String 5.结合HelloWorld分析java程序内存分布 1.Java程序运行时内存说明 编写的.java程序文件需要java编译器javac转成.class文件&#xff0c;然后通过jvm&#xff08;名为java的可执行程序&…

智慧能源助力绿色发展

居民生活是碳排放的重要贡献源&#xff0c;作为居民生活的主要场所&#xff0c;社区是低碳城市建设的重要空间载体。推动低碳社区建设&#xff0c;逐渐打造低碳生活方式&#xff0c;是低碳社会建设的重要内容之一。智慧新能源公共设施助力碳中和&#xff0c;用于各社区改造&…

【RuoYi移动端】uni-app如何发布h5网站?

一、登录D-Cloud开发者中心 开发者中心https://dev.dcloud.net.cn/二、创建应用 三、填写和提交创建应用 四、复制APPID

strcmp 的使用和模拟

目录 函数介绍&#xff1a; 头文件&#xff1a; 语法&#xff1a; 代码演示&#xff1a; 函数模拟&#xff1a; 函数介绍&#xff1a; strcmp是比较大小的函数。从字符串开始进行比较&#xff0c;如果两个相同位置的字符相同&#xff0c;那么继续往下进行比较&#xff0c;…

最大子数组和【贪心算法】

最大子数组和 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 class Solution {public int maxSubArray(int[] nums) {//记录最大结果&…

数据结构—循环队列(环形队列)

循环队列&#xff08;环形队列&#xff09; 循环队列的概念及结构循环队列的实现 循环队列的概念及结构 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。…

W25Q64 驱动--基于SPI2接口

前言 &#xff08;1&#xff09;本系列是基于STM32的项目笔记&#xff0c;内容涵盖了STM32各种外设的使用&#xff0c;由浅入深。 &#xff08;2&#xff09;小编使用的单片机是STM32F105RCT6&#xff0c;项目笔记基于小编的实际项目&#xff0c;但是博客中的内容适用于各种单片…

使用Miniconda

Conda是一个开源的包和环境管理器&#xff0c;使用它可以在同一台机器上安装不同版本的Python软件包和依赖了。Anaconda和Miniconda都集成了Conda,Anaconda包括更多的工具包&#xff0c;Miniconda则只包括Conda和Python。 在很奇葩的Deepin下Miniconda安装之旅 中&#xff0c;…

React + Next.js 搭建项目(配有对比介绍一起食用)

文章标题 01 Next.js 是什么02 Next.js 搭建工具 create-next-app03 create-react-app 与 create-next-app 的区别04 快速构建 Next.js 项目05 App Router 与 Pages Router 的区别 01 Next.js 是什么 Next.js 是一个 React 框架&#xff0c;它允许你使用 React 框架建立超强的…

sin(A)的意义

若存在矩阵A&#xff0c;则sin(A)表示对于矩阵A的每一个元素&#xff0c;进行对应的函数运算。 如: