简历考察点2_《CiCi-基于Vue3.0的智能音乐分享平台》

(1)项目初始化和推荐页面开发:

重点:轮播图、Scroll、下拉加载方法实现、

问题一:轮播图实现

① 获取轮播图数据:虽然找到接口了,但是由于XHR请求在浏览器端会有跨域的限制,不能直接请求QQ官网的接口地址,需要做一层Proxy代理:

 获取响应数据:

 获取轮播图数据,使用BetterScroll的基本配置项,监听slideWillChange事件

onMounted(() => {const sliderVal = slider.value = new BScroll(wrapperRef.value, {click: true,scrollX: true,scrollY: false,momentum: false,bounce: false,probeType: 2,slide: true})sliderVal.on('slideWillChange', (page) => {currentPageIndex.value = page.pageX})})

 问题二: 歌单列表 超过 recommend 页面时 不能滚动,如何解决?

添加 overflow: scroll;属性就可以滚动了

 支持slot 插槽的方式,滚动内容放入插槽中,外层可以和better-scroll做一些初始化联动

// 构造钩子 函数
import BScroll from '@better-scroll/core'
import ObserveDOM from '@better-scroll/observe-dom'
import { onMounted, onUnmounted, ref } from 'vue'BScroll.use(ObserveDOM)export default function useScroll(wrapperRef, options, emit) {const scroll = ref(null)onMounted(() => {const scrollVal = scroll.value = new BScroll(wrapperRef.value, {observeDOM: true,...options})if (options.probeType > 0) { scrollVal.on('scroll', (pos) => { // useScroll(rootRef, props, emit) 通过 emit 把位置信息派发出去emit('scroll', pos)})}})onUnmounted(() => {scroll.value.destroy()})return scroll
}

 Better-Scroll debugger发现容器高度和内容高度不一致时,采用observe-dom开启对content以及content子元素DOM改变的探测。当插件被使用后,当这些DOM元素发生变化时,将会触发scroll的refresh方法:

1. 针对改变频繁的CSS属性,增加debounce;

2. 如果改变发生在scroll动画过程中,则不会触发refresh

问题三:图片懒加载的实现> assets-js-create-loading-like-directive

vue2.0 vue-lazyload会实现图片懒加载的效果,默认先加载chicken图片,再去加载新的图片

/** 实现loading 加载的处理 */
import { createApp } from 'vue'
import { addClass, removeClass } from '@/assets/js/dom'/** * base.scss 定义的属性 ---  处理歌手详情页 边界效果的处理* .g-relative { position: relative; }*/const relativeCls = 'g-relative'export default function createLoadingLikeDirective(Comp) {return {mounted(el, binding) {const app = createApp(Comp)const instance = app.mount(document.createElement('div'))const name = Comp.nameif (!el[name]) {el[name] = {}}el[name].instance = instanceconst title = binding.argif (typeof title !== 'undefined') {instance.setTitle(title)}if (binding.value) {append(el)}},updated(el, binding) {const title = binding.argconst name = Comp.nameif (typeof title !== 'undefined') {el[name].instance.setTitle(title)}if (binding.value !== binding.oldValue) {binding.value ? append(el) : remove(el)}}}function append(el) {const name = Comp.nameconst style = getComputedStyle(el)if (['absolute', 'fixed', 'relative'].indexOf(style.position) === -1) {addClass(el, relativeCls)}el.appendChild(el[name].instance.$el)}function remove(el) {const name = Comp.nameremoveClass(el, relativeCls)el.removeChild(el[name].instance.$el)}
}

在组件中引入: 

(2)歌手页面开发:

问题:IndexList组件功能实现、use-fix歌手列表固定标题实现、use-shortcut歌手列表快速导航入口实现

问题一:IndexList组件功能 界面实现

歌手列表导航实现: 调用接口,获取封装后的数据,如何根据序列化找到对应歌手 

界面实现: 上方有固定标题栏,左侧  右侧是序列分成了不同组设置快速导航入口A-Z排序

<!-- 歌手列表 将数据呈现-->
<template><scroll class="index-list":probe-type="3"@scroll="onScroll"ref="scrollRef"><!-- 采用 groupRef 来获取DOM --><ul ref="groupRef"><li v-for="group in data":key="group.title"class="group"><h2 class="title">{{group.title}}</h2><ul><liv-for="item in group.list":key="item.id"class="item"@click="onItemClick(item)"><img class="avatar" v-lazy="item.pic"><span class="name">{{item.name}}</span></li></ul></li></ul><!-- 歌手列表固定标题 --><div class="fixed"v-show="fixedTitle":style="fixedStyle"><div class="fixed-title">{{fixedTitle}}</div></div><!-- 快速导航入口 设置 A-Z 排序 --><div class="shortcut"@touchstart.stop.prevent="onShortcutTouchStart"    @touchmove.stop.prevent="onShortcutTouchMove"@touchend.stop.prevent><ul><liv-for="(item, index) in shortcutList":key="item":data-index="index"         class="item":class="{'current': currentIndex === index}">{{ item }}</li></ul></div></scroll>
</template>

 问题二:use-shortcut 设置快速导航入口:

  function onShortcutTouchStart(e) { console.log(e.target)const anchorIndex = parseInt(e.target.dataset.index)touch.y1 = e.touches[0].pageYtouch.anchorIndex = anchorIndex// 滑动到目标锚点scrollTo(anchorIndex)}// 根据鼠标move 快速移动function onShortcutTouchMove(e) { touch.y2 = e.touches[0].pageY// 接近栏 距离 上一栏 距离 判断const delta = (touch.y2 - touch.y1) / ANCHOR_HEIGHT | 0const anchorIndex = touch.anchorIndex + delta// 滑动到目标锚点scrollTo(anchorIndex)}function scrollTo(index) { if (isNaN(index)) { return}// 设置index 的值index = Math.max(0, Math.min(shortcutList.value.length - 1, index))const targetEl = groupRef.value.children[index]const scroll = scrollRef.value.scrollscroll.scrollToElement(targetEl, 0)}

问题三:标题固定 

当calculate() 完成之后 设置nextTick 执行延迟回调

probeType

  • 类型:Number
  • 默认值:0
  • 可选值:1、2、3
  • 作用:有时候我们需要知道滚动的位置。
  • 当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;
  • 当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;
  • 当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。
  • 如果没有设置该值,其默认值为 0,即不派发 scroll 事件。

存储singer关键字

(3) 歌手页面开发 singer-detail

歌手的唯一标识  singerMid: req.requery.mid

异步获取关键歌手信息:

上推的时候 图层变模糊 列表往上滑动 overflow-hidden: false

需要设置图片层级 上面的标题 在上推的时候,标题不会被掩盖

下拉的时候 图片整体放大 有回弹效果

<scrollclass="list":style="scrollStyle"v-loading="loading"v-no-result:[noResultText]="noResult":probe-type="3"@scroll="onScroll"  //设置scroll 来监听事件>

 

核心代码:具体的含义是什么

为什么设置maxTranslateY

const RESERVED_HEIGHT = 40 作用是什么

Z-Index 折叠层 较大的元素会覆盖较小的元素在上层进行显示

const RESERVED_HEIGHT = 40 // 设置默认标签头高度export default {name: 'music-list',components: {SongList,Scroll},props: {songs: {type: Array,default() {return []}},title: String,pic: String,loading: Boolean,noResultText: {type: String,default: '抱歉,没有找到可播放的歌曲'},// rank  榜单标签 默认 booleanrank: Boolean  },data() {return {imageHeight: 0,scrollY: 0,maxTranslateY: 0}},computed: {noResult() {return !this.loading && !this.songs.length},playBtnStyle() {let display = ''if (this.scrollY >= this.maxTranslateY) {display = 'none'}return {display}},bgImageStyle() {const scrollY = this.scrollYlet zIndex = 0let paddingTop = '70%'let height = 0// 兼容 iPhone 设备let translateZ = 0// 可以滚动到的最大高度if (scrollY > this.maxTranslateY) {zIndex = 10paddingTop = 0height = `${RESERVED_HEIGHT}px`translateZ = 1}// 实现向上推的效果 默认值为1let scale = 1// 向下推 Y坐标为负数if (scrollY < 0) {scale = 1 + Math.abs(scrollY / this.imageHeight)}return {zIndex,paddingTop,height,backgroundImage: `url(${this.pic})`,transform: `scale(${scale})translateZ(${translateZ}px)`}},scrollStyle() {const bottom = this.playlist.length ? '60px' : '0'return {top: `${this.imageHeight}px`,bottom}},// 设置遮罩层filterStyle() {let blur = 0const scrollY = this.scrollYconst imageHeight = this.imageHeightif (scrollY >= 0) {blur = Math.min(this.maxTranslateY / imageHeight, scrollY / imageHeight) * 20  // 设置blur缩放比}return {backdropFilter: `blur(${blur}px)`}},...mapState(['playlist'])},mounted() {this.imageHeight = this.$refs.bgImage.clientHeightthis.maxTranslateY = this.imageHeight - RESERVED_HEIGHT  // 可以移动的最大高度},methods: {goBack() {this.$router.back()},onScroll(pos) {this.scrollY = -pos.y},//  学到这里的时候对其他部分进行处理selectItem({ index }) {this.selectPlay({list: this.songs,index})},random() {this.randomPlay(this.songs)},...mapActions(['selectPlay','randomPlay'])}}

(4)歌手详情页组件开发

问题一: 歌手详情页 详情页刷新 -- 刷新依然可以访问(有问题)-1:20

mid 总是加载不出来 依赖于传递的prop:singer 对象

分析 之前页面渲染会报错:现在的页面渲染依赖于prop singer这个数据,之前为什么可以 因为会通过歌手列表sing-list一级路由,点击某个歌手的时候 可以拿到这个歌手对应的singer对象,渲染二级路由的时候将singer对象进行传递,所以页面可以正常渲染,但是一旦页面进行刷新之后 内存中的数据都丢失了,因为刷新之后 没有经过一级路由 不知道点击了对应的哪个歌手,这样就拿不到对应的歌手对象 拿不到歌手对象 页面自然不能正常渲染 要保证可以正常渲染 借助浏览器的本地存储能力 使用存储一个使用localstorage和sessionstorage(关掉页面就没有了 但是刷新还是在的),当然 这里页面刷新使用sessionstorage 就足够实现

借助浏览器的本地存储能力 来解决这个问题:

使用 good-storage的方式

import storage from 'good-storage'

// localStorage

Storage.set(key, val)

Storage.get(key, def)

// sessionStorage

storage.session.set(key, val)

storage.session.get(key, val)

通过 constance.js 来存储项目中的共享常量

// 定义当前的singer_key 对象
export const SINGER_KEY = '__singer__'
export const FAVORITE_KEY = '__favorite__'
export const ALBUM_KEY = '__album__'
export const TOP_KEY = '__top__'
export const SEARCH_KEY = '__search__'
export const PLAY_KEY = '__play__'/*** 歌手详情页_音乐播放器PLAY_MODE* sequence 顺序播放* loop 循环播放* random 随机播放
*/
export const PLAY_MODE = {sequence: 0,loop: 1,random: 2
}

(2)问题二:transitions 实现歌手详情页路由的过渡效果 transform: translate3d(0, 0, 0);

<template><!-- 当singers数组为空的时候 加载loading --><div class="singer" v-loading="!singers.length"><index-list:data="singers"@select="selectSinger"></index-list><router-view v-slot="{ Component }"><transition appear name="slide"><!-- 传递 对应的singer数据 --><component :is="Component" :data="selectedSinger" />  </transition></router-view></div>
</template>

(3)歌手详情页歌曲列表随机播放 shuffle 函数引入 实现随机播放

// 实现shuffle 洗牌功能
export function shuffle(source) {const arr = source.slice()for (let i = 0; i < arr.length; i++) {const j = getRandomInt(i)swap(arr, i, j)}return arr
}function getRandomInt(max) {return Math.floor(Math.random() * (max + 1))
}function swap(arr, i, j) {const t = arr[i]arr[i] = arr[j]arr[j] = t
}

(5)播放器内核组件开发

 

 (6)歌单详情页与排行榜页面开发

 

歌单详情页: 歌手详情获取 sessionstorage

在渲染歌手详情页面 要获取到对应 歌曲的cached.id来拿到数据,对singer拿到数据是singer.mid

computedSinger() {let ret = nullconst data = this.dataif (data) {ret = data} else {const cached = storage.session.get(key)// 歌手详情获取的getSingerDetail.mid  但对于 歌曲详情 是数字id 这里需要转换成字符串 所以是catche.idif (cached && (cached.mid || cached.id + '') === this.$route.params.id) {ret = cached}}return ret}

歌单排行榜 top-list.vue 根据Key 值来获取到 排行榜列表 

排行榜 的编号:获取TopDetail 具体信息

export function getTopDetail(top) {return get('/api/getTopDetail', {id: top.id,period: top.period})
}

 歌手排行榜和 图标

<template><ul class="song-list"><liclass="item"v-for="(song, index) in songs":key="song.id"@click="selectItem(song, index)"><div class="rank" v-if="rank"><span :class="getRankCls(index)">{{ getRankText(index) }}</span></div><div class="content"><h2 class="name">{{song.name}}</h2><p class="desc">{{getDesc(song)}}</p></div></li></ul>
</template><script>export default {name: 'song-list',props: {songs: {type: Array,default() {return []}},rank: Boolean},emits: ['select'],methods: {getDesc(song) {return `${song.singer}·${song.album}`},selectItem(song, index) {this.$emit('select', { song, index })},getRankCls(index) {if (index <= 2) {return `icon icon${index}` // 在css中设置了对应的样式} else {return 'text'}},getRankText(index) {if (index > 2) {return index + 1}}}}
</script><style lang="scss" scoped>  省略一部分.icon {display: inline-block;width: 25px;height: 24px;background-size: 25px 24px;&.icon0 {@include bg-image('first');}&.icon1 {@include bg-image('second');}&.icon2 {@include bg-image('third');}}
<style>

 (7)搜索页面开发:

具备搜索框(在搜索框中输入文字 就会显示出歌曲或者歌手,向上滑动的时候就会进行歌单的加载-上拉加载)、热门搜索 点击表单会在输入框进行回显、搜索历史呈现

 v-model 监听事件 监听input框中数据的变化

v-model是双向绑定,当值进行传递的时候,会根据传输的值进行渲染,子组件是不能修改值的,子组件的值是从父组件而来。但是data中定义的变量是可以进行修改的,再设置watch进行监听

所以不能写成: v-model: modelValue

当输入框中频繁输入进行内容提交时

采用 throttle-debounce 实现节流效果 输入内容较多时候(JS高级 之 防抖 debounce - throttle 节流_js防抖debounce_玄鱼殇的博客-CSDN博客)

防抖 debounce

1. 概念

  • 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间
  • 当事件密集触发时,函数的触发会被频繁的推迟,并把上一次的给取消掉
  • 只有等待了一段时间也没有事件触发,才会真正的执行响应函数

2. 应用场景

  • 输入框中频繁的输入内容,搜索或者提交信息
  • 频繁的点击按钮,触发某个事件
  • 监听浏览器滚动事件,完成某些特定操作
  • 用户缩放浏览器的resize事件

节流 throttle 
1. 概念

  • 当事件触发时,会执行这个事件的响应函数
  • 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数
  • 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的


2. 应用场景

  • 监听页面的滚动事件
  • 鼠标移动事件
  • 用户频繁点击按钮操作
  • 轮播图的按钮滚动
this.$watch('query', debounce(300, (newQuery) => {this.$emit('update:modelValue', newQuery.trim())}))
<template><div class="search-input"><i class="icon-search"></i><inputclass="input-inner"v-model="query":placeholder="placeholder"/><iv-show="query"class="icon-dismiss"@click="clear"></i></div>
</template><script>import { debounce } from 'throttle-debounce'export default {name: 'search-input',props: {modelValue: String,placeholder: {type: String,default: '搜索歌曲、歌手'}},data() {return {query: this.modelValue}},created() {this.$watch('query', debounce(300, (newQuery) => {this.$emit('update:modelValue', newQuery.trim())}))this.$watch('modelValue', (newVal) => {this.query = newVal})},methods: {clear() {this.query = ''}}}
</script>

 ① 实现数据绑定:

1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

2.实现一个订阅者Watcher,每一个Watcher都绑定一个更新函数,watcher可以收到属性的变化通知并执行相应的函数,从而更新视图。

3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显示在视图上,然后初始化相应的订阅者(Watcher)。

搜索suggest完成组件化开发 (写完)

设置use-pull-up-load 进行下拉框加载

onMounted(() => {const scrollVal = scroll.value = new BScroll(rootRef.value, {pullUpLoad: true,observeDOM: true,click: true})scrollVal.on('pullingUp', pullingUpHandler)async function pullingUpHandler() {if (preventPullUpLoad.value) {scrollVal.finishPullUp()return}isPullUpLoad.value = trueawait requestData()scrollVal.finishPullUp()scrollVal.refresh()isPullUpLoad.value = false}})

设置use-search-history 获取搜索历史记录

export default function useSearchHistory() {const maxLen = 200const store = useStore()function saveSearch(query) {const searches = save(query, SEARCH_KEY, (item) => {return item === query}, maxLen)store.commit('setSearchHistory', searches)}function deleteSearch(query) {const searches = remove(SEARCH_KEY, (item) => {return item === query})store.commit('setSearchHistory', searches)}function clearSearch() {const searches = clear(SEARCH_KEY)store.commit('setSearchHistory', searches)}return {saveSearch,deleteSearch,clearSearch}
}

 (8)添加歌曲到用户中心

(9)性能优化

利用keep-alive实现组件应用:每次切换Tab的时候 都会重新渲染组件并发送异步请求,即使这个组件被访问过还是会重复这个逻辑。但这个项目要求没有这么高,所以下次重复访问的时候,存储的数据还是可以再次使用的

 Dom 随着Tab切换缓存依然存在,需要设置 重置onActivated和清理onDeactivated的工作-Scroll Slide use-mini-slide use-pull-up-load

<router-view :style="viewStyle" v-slot="{ Component }"><keep-alive><component :is="Component"/></keep-alive></router-view>

 (2)路由组件异步加载:实现非首屏代码异步加载,减缓首屏代码加载执行速率(路由懒加载)

依靠webpack+ES6的的方式

 在设置路由后 进行模式注释

configureWebpack: (config) => {if (process.env.npm_config_report) {const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginconfig.plugins.push(new BundleAnalyzerPlugin())}},

路由懒加载 

webpack提供的require.ensure()
vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。
这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

// 下面2行代码,没有指定webpackChunkName,每个组件打包成一个js文件。
/* const Home = () => import('@/components/home')
const Index = () => import('@/components/index')
const About = () => import('@/components/about') */
// 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。 把组件按组分块
const Home =  () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')
const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')
const About = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/about')

(3)通过webpack组件化管理进行项目部署

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

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

相关文章

2023 百度翻译 爬虫 js逆向 代码

js代码&#xff1a; const jsdom require("jsdom"); const {JSDOM} jsdom; const dom new JSDOM(<!DOCTYPE html><p>Hello world</p>); window dom.window; document window.document; XMLHttpRequest window.XMLHttpRequest;function n(t,…

【Java】树结构SQL数据的如何去实现搜索

这里写自定义目录标题 需要实现的效果前端需要的json格式&#xff1a;一定是一个完整的树结构错误错误的返回格式错误的返回格式实现的效果 正确正确的返回格式正确的展示画面 后端逻辑分析代码总览 数据库表结构 需要实现的效果 前端需要的json格式&#xff1a;一定是一个完整…

GAN:对抗生成网络,前向传播和后巷传播的区别

目录 GAN&#xff1a;对抗生成网络 损失函数 判别器开始波动很大&#xff0c;先调整判别器 生成样本和真实样本的统一&#xff1a;真假难辨​编辑 文字专图片​编辑 头像转表情包​编辑 头像转3D​编辑 后向传播 1. 前向传播&#xff08;forward&#xff09; 2. 反向传播&…

Googel Earth Engine 配置Python 环境

1. 安装并配置python环境 此处不再赘述 2. 安装 earthengine-api pip install earthengine-api C:\Users\xixi>pip install earthengine-api Collecting earthengine-apiUsing cached earthengine_api-0.1.363-py3-none-any.whl Requirement already satisfied: google-c…

大模型技术实践(二)|关于Llama 2你需要知道的那些事儿

在上期文章中&#xff0c;我们简要回顾了Llama模型的概况&#xff0c;本期文章我们将详细探讨【关于Llama 2】&#xff0c;你需要知道的那些事儿。 01-Llama 2的性能有多好&#xff1f; 作为Meta新发布的SOTA开源大型语言模型&#xff0c;Llama 2是Llama模型的延续和升级。Ll…

Java“牵手”虾皮商品列表数据,关键词搜索虾皮(Shopee)商品数据接口,虾皮API申请指南

虾皮&#xff08;SHOPEE&#xff09;商城是一个网上批发购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取虾皮商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问虾皮商城的网页来获取商品详情…

QT中资源文件resourcefile的使用,使用API完成页面布局

QT中资源文件resourcefile的使用 之前添加图标的方法使用资源文件的方法创建资源文件资源文件添加前缀资源文件添加资源使用资源文件中的资源 使用API完成布局使用QHBoxLayout完成水平布局使用QVBoxLayout完成垂直布局使用QGridLayout完成网格布局 在Qt中引入资源文件好处在于他…

数据结构:二叉树及相关操作

文章目录 前言一、树的概念及结构1.什么是树2. 树的相关概念3.树的表示 二、二叉树概念及结构1.二叉树概念2.特殊的二叉树3.二叉树的性质4.二叉树的存储结构 三、平衡二叉树实现1.创建树和树的前中后遍历1.前中后遍历2.创建树且打印前中后遍历 2.转换为平衡二叉树和相关操作1.转…

解密长短时记忆网络(LSTM):从理论到PyTorch实战演示

目录 1. LSTM的背景人工神经网络的进化循环神经网络&#xff08;RNN&#xff09;的局限性LSTM的提出背景 2. LSTM的基础理论2.1 LSTM的数学原理遗忘门&#xff08;Forget Gate&#xff09;输入门&#xff08;Input Gate&#xff09;记忆单元&#xff08;Cell State&#xff09;…

软件测试技术分享丨遇到bug怎么分析?

为什么定位问题如此重要&#xff1f; 可以明确一个问题是不是真的“bug” 很多时候&#xff0c;我们找到了问题的原因&#xff0c;结果发现这根本不是bug。原因明确&#xff0c;误报就会降低 多个系统交互&#xff0c;可以明确指出是哪个系统的缺陷&#xff0c;防止“踢皮球…

vue3范围选择组件封装

个人项目地址&#xff1a; SubTopH前端开发个人站 &#xff08;自己开发的前端功能和UI组件&#xff0c;一些有趣的小功能&#xff0c;感兴趣的伙伴可以访问&#xff0c;欢迎提出更好的想法&#xff0c;私信沟通&#xff0c;网站属于静态页面&#xff09; SubTopH前端开发个人站…

react 11之 router6路由 (两种路由模式、两种路由跳转、两种传参与接收参数、嵌套路由,layout组件、路由懒加载)

目录 react路由1&#xff1a;安装和两种模式react路由2&#xff1a;两种路由跳转 &#xff08; 命令式与编程式&#xff09;2-1 路由跳转-命令式2-2 路由跳转-编程式 - 函数组件2-2-1 app.jsx2-2-2 page / Home.jsx2-2-3 page / About.jsx2-2-4 效果 react路由3&#xff1a;函数…

mysql 8.0 窗口函数 之 分布函数 与 sql server (2017以后支持) 分布函数 一样

mysql 分布函数 percent_rank&#xff08;&#xff09; &#xff1a;等级值 百分比cume_dist() &#xff1a;累积分布值 percent_rank&#xff08;&#xff09; 计算方式 (rank-1)/(rows-1)&#xff0c; 其中 rank 的值为使用RANK()函数产生的序号&#xff0c;rows 的值为当前…

进行Stable Diffusion的ai训练怎么选择显卡?

Stable Diffusion主要用于从文本生成图像&#xff0c;是人工智能技术在内容创作行业中不断发展的应用。要在本地计算机上运行Stable Diffusion&#xff0c;您需要一个强大的 GPU 来满足其繁重的要求。强大的 GPU 可以让您更快地生成图像&#xff0c;而具有大量 VRAM 的更强大的…

奥威BI数据可视化工具:个性化定制,打造独特大屏

每个人都有自己独特的审美&#xff0c;因此即使是做可视化大屏&#xff0c;也有很多人希望做出不一样的报表&#xff0c;用以缓解审美疲劳的同时提高报表浏览效率。因此这也催生出了数据可视化工具的个性化可视化大屏制作需求。 奥威BI数据可视化工具&#xff1a;个性化定制&a…

在Linux系统上安装和配置Redis数据库,无需公网IP即可实现远程连接的详细解析

文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 Redis作为一款高速缓存的key value键值对的数据库,在…

消息队列——RabbitMQ(一)

MQ的相关概念 什么事mq MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff…

【Python爬虫案例】爬取大麦网任意城市的近期演出!

老规矩&#xff0c;先上结果&#xff1a; 含10个字段&#xff1a; 页码&#xff0c;演出标题&#xff0c;链接地址&#xff0c;演出时间&#xff0c;演出城市&#xff0c;演出地点&#xff0c;售价&#xff0c;演出类别&#xff0c;演出子类别&#xff0c;售票状态。 代码演示…

一款打工人必备的电脑端自律软件!!冲鸭打工人!!

你&#xff01;有没有渴望进步&#xff01;&#xff01; 你&#xff01;有没有渴望变强&#xff01;&#xff01;&#xff01; 成为大佬&#xff01;&#xff01;&#xff01;超越巨佬&#xff01;&#xff01;&#xff01; 这就是一款为这样的你量身定做的程序&#xff1a;输入…

vue3 tailwindcss的使用

首先安装依赖&#xff1a; npm install -D tailwindcsslatest postcsslatest autoprefixerlatestnpm i -D unocss 然后vite.config.ts中 引入 import Unocss from unocss/viteexport default defineConfig({plugins: [Unocss(),],})终端执行&#xff1a; npx tailwindcss in…