当前位置: 首页 > news >正文

Day42:网易云项目,路由进阶

网易云项目

创建、启动项目并配置路由

npm init vite

npm i

npm i vue-router

npm i sass -D

在main.js中

import router from './router'
createApp(App).use(router).mount('#app')

在index中配置路由

import {createRouter,createWebHistory} from 'vue-router'
import Home from '../view/Home.vue'
import Search from '../view/Search.vue'
const router = createRouter ({history:createWebHistory(),routes:[{path:'/',name:'home',component:Home},{path:'/search',name:'search',component:Search}]
})
export default router

实现全局通用导航栏

写一个顶部的导航栏TopNav.vue在component文件夹中

<template><div class="top-nav"><div class="w content"><router-link to="/"><h1 class="logo"></h1></router-link><!-- 绑定一个导航,点击回到首页 --><div class="search-input"><input type="text" placeholder="请输入"v-model.trim="song"@keyup.enter="searchSong"/></div></div></div>
</template>
<script setup>import { ref } from "vue";import { useRouter } from "vue-router";const song = ref("")const router = useRouter()function searchSong(){router.push(`/search?song=${song.value}`)}
</script>
<style lang="scss" scoped>.top-nav {height: 70px;background-color: #242424;.content {display: flex;align-items: center;justify-content: space-between;h1 {width: 176px;height: 70px;background-image: url("https://s2.music.126.net/style/web2/img/frame/topbar.png?19dafe7dd55400ffec9b354833340e1f");background-position: 0 0;}.search-input {input {height: 40px;border-radius: 18px;padding: 5px 10px;outline: none;}}}}
</style>

useRoute和useRouter的区别,一个是获取全局路由,一个是获取当前页面的路由

在app中,将样式引入,并且去掉<style lang="scss" scoped>中的scoped,使导航栏能在全局应用

<template><div><top-nav/> <!-- 普通组件,不参与路由切换,是全局样式 --><router-view></router-view></div>
</template><script setup>
import TopNav from './components/TopNav.vue';
</script><style lang="scss">// scoped去掉,可以作为全局样式
* {padding: 0;margin: 0;box-sizing: border-box;
}
.w {width: 980px;margin: 0 auto;
}
</style>

获取axios请求的内容

在获取网易云数据的api中note app.js

在项目中

npm i axios

获取搜索的接口,放在search中,把连接板包裹在axios把获取的song.value拼接到链接后面,然后发axios请求

  const route = useRoute()const song = ref("")const lists = ref([])song.value = route.query.songaxios.get(`http://localhost:3000/search?keywords=${song.value}`).then((res) => {lists.value = res.data.result.songs})

查询到数据得到一个30长度的array

将array中需要的数据渲染到页面

<template><div class="search"><div class="w list"><ul><li v-for="(item, index) in lists" :key="item.id" :class="{ active: index % 2 === 1 }"><p>{{ item.name }}</p><span><span class="inner_span" v-for="_item, _index in item.artists" :key="_index">{{ _item.name }}{{ _index + 1 < item.artists.length ? "/" : "" }}</span></span><span>{{ item.album.name }}</span><span>{{ format(item.duration) }}</span><!-- 格式化毫秒 --></li></ul></div></div>
</template>

得到的歌手不换行,超出的部分省略号,给innerspan添加三个样式即可

overflow: hidden;

white-space: nowrap;

text-overflow: ellipsis;

给每个歌手添加后斜杠,如果索引值+1小于数组长度就加斜杠,如果索引值+1不小于数组长度就不加斜杠{{_index + 1 < item.artists.length ? "/" : ""}}

给li添加斑马条纹样式和鼠标hover样式

<style lang="scss" scoped>.search {background-color: #eee;.list {background-color: #fff;border-left: 1px solid #615f5f;border-right: 1px solid #615f5f;ul {list-style: none;padding: 20px;li {display: flex;align-items: center;padding: 12px;gap: 10px;&.active {background-color: #f9f5f5;}&:hover {background-color: #e0dbdb;cursor: pointer;}p {width: 40%;}& > span {flex: 1;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}}}}}
</style>

定义方法format用来毫秒值转分秒

分钟和秒如果不足10需要在前面添加字符串0。如果秒只有一位,获取秒数时只截取一位,然后添加字符串0;如果多于10,则截取前两位,后面多余的不要。

<script setup>import { useRoute } from "vue-router";import { ref } from "vue";import { format } from "path";import axios from "axios";function format(duration) {//毫秒转分秒let mins = Math.floor(duration / 1000 / 60)// 如果只有个位数要补一个0在前面if (mins < 10) {mins = "0" + mins}// 获取秒let secs = (duration / 1000) % 60// 字符串截取if (secs > 10) {secs = String(secs).slice(0, 2)} else {secs = "0" + String(secs)[0] // 只有一位前面加零,后面只截取一位}return mins + ':' + secs}const route = useRoute()const song = ref("")const lists = ref([])song.value = route.query.songaxios.get(`http://localhost:3000/search?keywords=${song.value}`).then((res) => {lists.value = res.data.result.songs})
</script>

在search页面重新搜索

需要监听song,如果song变化,需要重新发送请求,再把参数传给lists

封装axios请求为方法init(song)

在第一次加载的时候先运行一次init(song.value)

需要监听route.query.song的变化,变化了重新执行init

route.query是一个响应式对象,但route.query.song是一个响应式对象里的值,如果要对这个值进行监听,需要写一个函数包装他,并返回值,这样就不会出现报错了

封装了之后,axios请求中包裹的动态字符中的.value需要删除,因为监听已经直接针对song

const route = useRoute()
const song = ref("")
const lists = ref([]) 
song.value = route.query.song
function init(song) {axios.get(`http://localhost:3000/search?keywords=${song}`).then((res) => {lists.value = res.data.result.songs})
}
init(song.value) // 第一次加载的时候执行
watch(() => route.query.song,(newValue) => {song.value = newValueinit(song.value)})

登录页面项目

  1. 在login页面设置登录按钮,如果点击则传isLogin为true到本地存储,表示已经登录
<template><div>this is login<button @click="login">login</button></div>
</template>
<script setup>
function login() {//登录身份信息(token信息)只要登陆了,就在本地存,且设置为truelocalStorage.setItem('isLogin',true)// 在本地存储中找,如果有该字段且为true,则认为登录
}
</script>
  1. 在进入任何页面(除开login之外),要做一个身份认证,如果已经登录,可以进入这个页面,否则进入login身份认证
<template><div><router-view></router-view></div>
</template>
  1. 在生命周期钩子函数router.beforeEach进入到每个页面之前,都要进行钩子函数触发,被称为全局的前置路由导航守卫。
  2. 如果进入的页面不是login,或者没有登录(isLogin不是true),则强制回到login
    1. router.beforeEach((to,from) => {})参数to代表去哪个页面,from表示从哪里来
    2. 此代码写在路由页面router
router.beforeEach((to,from) => {// 如果进入了页面不是login,或者isLogin不是true,则强制回到loginif(to.name !== 'login' && !localStorage.getItem("isLogin")){return {name: "login"}}
})

单个路由导航守卫

router是全局路由,如果想精细化定制不同页面的跳转效果,可以在路由导航列表的对象里面书写路由导航守卫

localStorage.getItem("isLogin")需要用JSON包裹,否则可能会出现不能识别的情况

{path: '/detail',name: 'detail',component: Detail,// 单个路由对象的前置导航守卫beforeEnter (to, from) {if (to.name !== "/login" && !JSON.parse(localStorage.getItem("isLogin"))) {return {name: "login"}}}
},

前置导航守卫可以设置单个,但后置导航守卫可以设置全局的

前置导航守卫可以写在router的全局、局部,或者写在组件内部。推荐写在router

组件内部写法

setup语法糖无法触发beforeRouteEnter钩子函数,需要写完整格式

<script>
/* import { onBeforeEnter } from "vue-router";
onBeforeEnter() */
export default {beforeRouteEnter (to, from) {console.log('beforeenter')}
}
</script>

离开当前路由时触发导航守卫

<script>// 离开当前路由时,触发一个导航守卫beforeRouteLeave (to, from) {let res = window.confirm('您是否想离开本页面')if(!res) {return false // 如果是false,则留在本页面}}
}
</script>

路由进阶

1.路由导航守卫

顾名思义,路由导航守卫可以让每个页面完成跳转前后进行一些逻辑实现。vue-router提供了多种导航守卫:全局的,单个路由独享的,或者组件级的。现在来逐一说明。

路由导航守卫的详细说明

1.1 全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫,这样在匹配每个路由路径的时候都会进行一次进入前的"拦截",在某些需要验证登录状态的业务场景下应用极广。

我们仍然用示例来演示全局前置守卫的使用:

现在有3个页面,分别是登录页,首页,列表页。进入任何页面前都需要进行身份验证,必须本地存储中isLogin的字段为true时才可以进入,否则统一回到登录页。按照之前学习的内容快速完成路由信息的相关配置。

在配置完路由信息后,通过router.beforeEach 注册一个全局前置守卫,其中的守卫方法接受2个参数

  • to:表示当前导航即将进入的页面
  • from:表示当前导航即将离开的页面

前置守卫中通过返回的路由对象实现重定向。

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../components/Home.vue'
import Detail from '../components/Detail.vue'
import Login from '../components/Login.vue'const router = createRouter({history: createWebHistory(),routes: [{path: '/',name: 'home',components: Home,},{path: '/detail',name: 'detail',components: Detail,},{path: '/login',name: 'login',components: Login,},],
})
router.beforeEach((to, from) => {if (!localStorage.getItem('isLogin') && to.name !== 'login') {return {name: 'login',}}
})
export default router

在之前版本的路由中,还提供了第三个可选参数next,通过调用next方法也能进入到即将进入的路由页面,但新版本中不推荐这么做了。

1.2 全局后置守卫

和全局前置守卫类似,同样可以注册全局后置守卫,沿用上面的示例,在离开每个页面之前,都弹出一个提示框。

router.afterEach((to, from) => {alert('要离开此页面咯')
})

1.3 独享前置守卫

除了定义全局的路由守卫,还可以针对单个路由对象定义守卫:

{path: '/detail',name: 'detail',component: Detail,beforeEnter: (to, from) => {if (!localStorage.getItem('isLogin') && to.name !== 'login') {return {name: 'login',}}},
},

1.4 组件内部的路由守卫

除开在路由配置信息中定义导航守卫,还可以在组件内部定义守卫:

  • beforeRouteEnter 进入路由前调用
  • beforeRouteUpdate 动态参数改变时调用
  • beforeRouteLeave 离开路由前调用

2.路由元信息

meta叫路由元信息,可以存储当前路由对象的一些信息

可以将任意信息添加到路由对象上,比如页面标题,鉴权认证等,Vue中的路由提供了一个meta字段,可以通过给每个路由对象配置meta字段来添加信息。

{path: '/',name: 'home',component: Home,meta: {title: '首页',},
},

在组件的生命周期中,可以将meta信息合理地调用出来。

//Home中 组件挂载完毕后 将页面的标题内容改为meta中存放的信息
<script setup>import { onMounted } from 'vue'import { useRoute } from 'vue-router'onMounted(() => {document.title = useRoute().meta.title})
</script>

这里需要写setup语法糖,但是组件内守卫不要写。虽然最好也不要写组件内守卫啦

<script setup>import { onMounted } from 'vue'import { useRoute } from 'vue-router'const route = useRoute() // 最好写在外面,不要写在钩子里onMounted(() => {document.title = route.meta.title})
</script>

3.路由嵌套

某些复杂的组件关系存在层级更深的路由,这是可以利用路由嵌套来实现,给需要添加二级路由的路由对象添加children属性来配置二级路由,同样使用来渲染出口。

现在给Detail路由页面添加二级子路由,能够显示用户详情和头像详情,在对应的路由配置中添加children属性

// 不要忘记最上面的引入!!!
{path: '/detail',name: 'detail',component: Detail,meta: {title: '详情页',},children: [{ path: 'users', name: 'users', component: Users },{ path: 'profile', name: 'profile', component: Profile },],},

建立好对应的路由组件后,需要在Detail中添加二级路由的出口:

<template><h1>这是详情页</h1><router-link to="users"> <button>用户详情页</button></router-link><router-link to="profile"> <button>头像详情页</button></router-link><router-view></router-view> // 记得渲染出口
</template>

嵌套路由的使用规则跟一级路由保持一致,当然如果你的业务足够复杂,还可以嵌套三级,四级路由。

4.路由滚动行为

切换路由的过程中,VueRouter还提供了操作滚动条行为的方法,通过scrollBehavior方法可以在路由配置中规定滚动条行为

const router = createRouter({history: createWebHashHistory(),routes: [...],scrollBehavior (to, from, savedPosition) {// return 期望滚动到哪个的位置return {top:30 //滚动到距离顶部30}}
})

5.路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

首页不用做懒加载,除开首页对所有的路由都使用动态导入。

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:

const Detail = () => import('../components/Detail.vue')const router = createRouter({// ...routes: [{ path: '/detail',name:'detail', component: Detail }],
})
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../view/Home.vue'
const router = createRouter({history: createWebHistory(),routes: [{path: '/login',name: 'login',component: ()=>import('../view/Login.vue'), // 改为懒加载meta: {title: '登录',},},

6.动态路由 (路由权限)

在登录页点击登录后,button新增了一个vip的button,可以进入vip页面。登录之后,才能在路由映射关系中加上vip对象(不能是控制按钮显示隐藏

对路由的添加通常是通过 配置routes来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。例如在处理一些路由权限的场景下就需要动态增加路由。

6.1 增加路由

动态增加路由主要依靠router.addRoute()方法实现,获取到router实例后,可以在合理时机注册新的路由对象,

例如在登陆后新增一个Vip路由:

const login = () => {localStorage.setItem('isLogin', true)isVip.value = truerouter.addRoute({path: '/vip',name: 'vip',component: Vip,})
}

6.2 删除路由

动态删除路由最常用的方法是通过使用 router.removeRoute() 按名称删除路由,所以注册路由信息时添加name属性是一个好习惯,大家务必养成。

我们示例中登录退出希望将Vip路由删除掉:

const out = () => {localStorage.clear()isVip.value = falserouter.removeRoute('vip')
}

最终Login组件的页面代码会显得比较丰富完整:

<template><router-link to="/"><button>首页</button></router-link><router-link to="/detail"><button>详情页</button></router-link><router-link to="/vip" v-if="isVip"><button>Vip页</button></router-link><button @click="login">登录</button><button @click="out">退出登录</button>
</template><script setup>import { ref } from 'vue'import { useRouter } from 'vue-router'import Vip from '../components/Vip.vue'const router = useRouter()const login = () => {localStorage.setItem('isLogin', true)isVip.value = truerouter.addRoute({ // 登录成功后再添加路由映射关系path: '/vip',name: 'vip',component: Vip,})}const out = () => {localStorage.clear()// localStorage.removeItem('isLogin') //去掉登录身份信息isVip.value = falserouter.removeRoute('vip') // 退出登录后动态删除路由}let isVip = ref(localStorage.getItem('isLogin'))
</script><style></style>

6.3 查看当前路由

Vue Router 提供了两个功能来查看现有的路由:

  • router.hasRoute():检查路由是否存在。
  • router.getRoutes():获取一个包含所有路由记录的数组。
<template><div>this is login<button @click="login">login</button><button @click="logout">logout</button><button @click="$router.push('/')">首页</button><button @click="$router.push('/detail')">详情</button><router-link to="/vip" v-if="isVip"><button>Vip页</button></router-link></div>
</template>
<script setup>
import {onMounted,ref} from 'vue'
import { useRoute } from 'vue-router'
import { useRouter } from 'vue-router'
import Vip from './Vip.vue'
const router = useRouter()
// 使用json包裹,使isVip的状态依靠isLogin的状态改变
const isVip = ref(JSON.parse(localStorage.getItem("isLogin")))
function login() {//登录身份信息(token信息)只要登陆了,就在本地存,且设置为truelocalStorage.setItem('isLogin',true) // 在本地存储中找,如果有该字段且为true,则认为登录isVip.value = true// 登录之后,才在路由映射关系中加上vip对象router.addRoute({path: '/vip',name: 'vip',component: Vip,})
}
function logout() {//去掉登录身份信息localStorage.removeItem('isLogin')isVip.value = false// 动态删除路由router.removeRoute("vip")
}
const route = useRoute() // 最好写在外面,不要写在钩子里
onMounted(() => {document.title = route.meta.title
})
</script>

相关文章:

Day42:网易云项目,路由进阶

网易云项目 创建、启动项目并配置路由 npm init vite npm i npm i vue-router npm i sass -D 在main.js中 import router from ./router createApp(App).use(router).mount(#app) 在index中配置路由 import {createRouter,createWebHistory} from vue-router import H…...

Open3D(C++) 三维点云边界提取

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 见:PCL 点云边界提取 二、代码实现 BoundaryEstimation.h #pragma...

AUTOSAR汽车电子嵌入式编程精讲300篇-经典 AUTOSAR 安全防御能力的分析及改善

目录 前言 研究现状 经典 AUTOSAR 概述 2.1 经典 AUTOSAR 架构 2.2 经典 AUTOSAR 应用层...

LeetCode 1584. 连接所有点的最小费用【最小生成树】

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

超简单,几行js代码就实现一个 vue3 的数字滚动效果!

预览效果 1. 创建一个template <template><div class"num-warp"><template v-for"item in numStr"><div v-if"item ," class"dot">,</div><divv-elseclass"num-box":style"{transf…...

两阶段鲁棒优化matlab实现——CCG和benders

目录 1 主要内容 2 部分代码 3 程序结果 4 程序链接 1 主要内容 程序采用matlab复现经典论文《Solving two-stage robust optimization problems using a column-and-constraint generation method》算例&#xff0c;实现了C&CG和benders算法两部分内容&#xff0c;通过…...

二进制安全虚拟机Protostar靶场(4)写入shellcode,基础知识讲解 Stack Five

前言 这是一个系列文章&#xff0c;之前已经介绍过一些二进制安全的基础知识&#xff0c;这里就不过多重复提及&#xff0c;不熟悉的同学可以去看看我之前写的文章 二进制安全虚拟机Protostar靶场 安装,基础知识讲解,破解STACK ZERO https://blog.csdn.net/qq_45894840/artic…...

【Flink实战】玩转Flink里面核心的Source Operator实战

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;【Flink实战】玩转Flink里面核心的Source Operator实战 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目录导航 Flink 的API层级介绍Source Operator速览Flin…...

[2023-09-12]Oracle备库查询报ORA-01187

一个多表关联的语句在备库执行查询时提示ORA-01187: cannot read from file because it failed verification tests&#xff0c;单独对某一个表查询则正常返回&#xff08;因为不需要排序等&#xff0c;没有用到临时表空间&#xff09;。 查看报错信息发现是提示的临时数据文件…...

leetcode 16.最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4], target 1 输出&#xff1a;…...

antd table 自定义排序图标

要在Ant Design的Table组件中自定义排序图标&#xff0c;可以使用sorter和sortDirections属性来实现自定义排序逻辑和图标。以下是一个示例&#xff0c;演示如何在Ant Design的Table中自定义排序图标&#xff1a; import React, { useState } from react; import { Table, Spa…...

第十九章、【Linux】开机流程、模块管理与Loader

19.1.1 开机流程一览 以个人计算机架设的 Linux 主机为例&#xff0c;当你按下电源按键后计算机硬件会主动的读取 BIOS 或 UEFI BIOS 来载入硬件信息及进行硬件系统的自我测试&#xff0c; 之后系统会主动的去读取第一个可开机的设备 &#xff08;由 BIOS 设置的&#xff09; …...

GMAC PHY介绍

1.1PHY接口发展 &#xff08;1&#xff09;MII支持10M/100Mbps&#xff0c;一个接口由14根线组成&#xff0c;它的支持还是比较灵活的&#xff0c;但是有一个缺点是因为它一个端口用的信号线太多。参考芯片&#xff1a;DP83848 、DM900A&#xff08;该芯片内部集成了MAC和PHY接…...

华为OD机考算法题:最远足迹

目录 题目部分 解读与分析 代码实现 题目部分 题目最远足迹难度易题目说明某探险队负责对地下洞穴进行探险。 探险队成员在进行探险任务时&#xff0c;随身携带的记录器会不定期地记录自身的坐标&#xff0c;但在记录的间隙中也会记录其他数据。探索工作结束后&#xff0c;…...

QScrollBar滚动条、QSlider滑块、 QDial表盘

QAbstractSlider 类、 QSCrollBar 类、 QSlider 类 一、 基本原理 1、 QAbstractSlider 继承自 QWidget&#xff0c;该类主要用于提供一个范围内的整数值&#xff0c; 2、 QAbstractSlider 类是 QScrollBar 类(滚动条)、 QSlider 类(滑块)、 QDial 类(表盘)的父类&#xff0c;因…...

Prometheus+Grafana可视化监控【MySQL状态】

文章目录 一、安装Docker二、安装MySQL数据库(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装mysqld_exporter七、Grafana添加MySQL监控模板 一、安装Docker 注意&#xff1a;我这里使用之前写好脚本进行安装Docker&#xff0c;如果…...

五,编译定制rom并刷机实现硬改(二)

系列文章目录 第一章 安卓aosp源码编译环境搭建 第二章 手机硬件参数介绍和校验算法 第三章 修改安卓aosp代码更改硬件参数 第四章 编译定制rom并刷机实现硬改(一) 第五章 编译定制rom并刷机实现硬改(二) 第六章 不root不magisk不xposed lsposed frida原生修改定位 第七章 安卓…...

Modbus协议详解3:数据帧格式 - RTU帧 ASCII帧的区别

Modbus既然是一种通信协议&#xff0c;那它就应该有规定的通信格式用于在设备之间的指令接收与识别。 本文就着重讲讲Modbus协议的RTU帧和ASCII帧。 Modbus帧在串行链路上的格式如下&#xff1a; 在上图的格式中&#xff1a; 1&#xff09;地址域&#xff1a;指代的是子节点地址…...

认识数据分析

文章目录 1. 认识数据分析1.1 数据自身的三大属性1.2 建数仓 数据分析的工程技术1.3 数据分析解决问题的原理1.4 数据分析的具体流程1.5 数据的中心化和智能化1.6 数据分析的四种类型和六个方向 1. 认识数据分析 1.1 数据自身的三大属性 客观&#xff1a;用数字衡量和表现一件…...

Learn Prompt-ChatGPT 精选案例:写作博客

在 ChatGPT 的帮助下&#xff0c;文本内容的产出&#xff0c;尤其是撰写博客文章的过程得到了进一步的简化。你可以让 ChatGPT 激发你的灵感&#xff0c;也可以让它美化你的文章内容。 这里我们希望能通过prompt写出一篇以“ChatGPT对社会各行各业的影响”为主题的博客。 本页…...

《确保安全:PostgreSQL安全配置与最佳实践》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…...

Unity中Shader抓取屏幕并实现扭曲效果

文章目录 前言一、屏幕抓取&#xff0c;在上一篇文章已经写了二、实现抓取后的屏幕扭曲实现思路&#xff1a;1、屏幕扭曲要借助传入 UV 贴图进行扭曲2、传入贴图后在顶点着色器的输入参数处&#xff0c;传入一个 float2 uv : TEXCOORD&#xff0c;用于之后对扭曲贴图进行采样3、…...

深浅拷贝详解

深浅拷贝 经典真题 深拷贝和浅拷贝的区别&#xff1f;如何实现 深拷贝和浅拷贝概念 首先&#xff0c;我们需要明确深拷贝和浅拷贝的概念。 浅拷贝&#xff1a;只是拷贝了基本类型的数据&#xff0c;而引用类型数据&#xff0c;复制后也是会发生引用&#xff0c;我们把这种拷…...

@Scheduled 定时任务

Scheduled(cron"30 * * * * ?") 1.cron表达式格式&#xff1a; {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} 2.cron表达式各占位符解释&#xff1a; {秒数}{分钟} > 允许值范围: 0~59 ,不允许为空值&#xff0c;若值不合法&#xff0c;调度器将…...

丙烯酸共聚聚氯乙烯树脂

声明 本文是学习GB-T 42790-2023 丙烯酸共聚聚氯乙烯树脂. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了丙烯酸共聚聚氯乙烯树脂的外观、物化性能等技术要求&#xff0c;描述了相应的采样、试验方 法、检验规则、标志、包装、…...

Navicat导入Excel数据顺序变了

项目场景&#xff1a; Navicat导入Excel数据 问题描述 从Excel表格中导入数据到数据库中。但是&#xff0c;在导入的过程中&#xff0c;我们常会发现数据顺序出现了问题&#xff0c;导致数据错位&#xff0c;给数据的处理带来了极大的麻烦。 原因分析&#xff1a; 这个问题的…...

uni-app的生命周期

uni-app的生命周期包括应用生命周期和页面生命周期。 应用生命周期涵盖了整个uni-app应用的启动、运行和销毁过程&#xff0c;主要包括以下几个生命周期函数&#xff1a; onLaunch&#xff1a;应用初始化时触发&#xff0c;只触发一次。onShow&#xff1a;应用启动或从后台进…...

Vulnhub实战-DC9

前言 本次的实验靶场是Vulnhub上面的DC-9&#xff0c;其中的渗透测试过程比较多&#xff0c;最终的目的是要找到其中的flag。 一、信息收集 对目标网络进行扫描 arp-scan -l 对目标进行端口扫描 nmap -sC -sV -oA dc-9 192.168.1.131 扫描出目标开放了22和80两个端口&a…...

软件设计模式系列之七——原型模式

1 模式的定义 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;其主要目的是通过复制现有对象来创建新对象&#xff0c;而不是使用构造函数。原型模式将对象的创建委托给原型对象&#xff0c;通过克隆&#xff08;复制&#xff09;来生成新…...

PMP考试注意事项有哪些?

1. PMI明确规定&#xff1a;不允许考生使用自带文具&#xff0c;包括自带的笔、削笔刀、橡皮、笔袋、计算器和草稿纸等。 2. 本次考试考场内为每位考生配备2B铅笔、橡皮、计算器(若有需要)和草稿纸。如文具有缺损或考试过程中如需更换铅芯等&#xff0c;请向监考老师举手示意。…...

宁夏建设厅网站/搜关键词网站

1. 示例1 2. 示例2 3. 示例3...

wordpress图片属性添加图片/seo值怎么提高

中介者模式 用一个 中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用&#xff0c;从而使其耦合松散&#xff0c;可以独立地改变它们之间的交互。 适用场景 1、一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。 …...

辽宁省建设工程招标协会网站/广州:推动优化防控措施落地

一些知识点&#xff1a; 要将session进行持久化&#xff1a; 要将cookie进行持久化&#xff0c;则要将cookie中的JSSESSIONID进行持久化。这里要创建一个cookie来覆盖服务器之前自动生成的JSSESSIONID。 这里分为添加进购物车&#xff0c;查看购物车&#xff0c;和前端 前端…...

湖北省建设银行网站6/电子商务主要干什么

对于数据分析师来说&#xff0c;可视化永远是一门不过时的学问&#xff0c;不仅因为上到企业领导、下到业务分析都要用到可视化&#xff0c;更因为它是分析师手中的优秀工具&#xff0c;它向我们揭示了数据背后的规律。 但很多人又会问&#xff0c;自己做的数据可视化丑出天际&…...

微信做明天展现网站要多少钱/免费推广自己的网站

大致思路&#xff1a; 后序遍历用栈来实现&#xff1a; 逆后序遍历前序遍历的左右子树入栈顺序交换&#xff1b;逆后序->后序&#xff0c;采用栈2来倒置输出 需要注意的是&#xff0c;如何定义栈。之前用stack<TreeNode* >来定义&#xff0c;但是总会出现什么编译错…...

wordpress如何添加首页图片/抖音黑科技引流推广神器

今天调试代码的过程中&#xff0c;F8失效 解决办法 关掉有道词典&#xff01;...