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

Vue3 - 小兔仙 - day2

0.学习大纲

1.pinia快速入门

pinia介绍和初始化

Pinia 是 Vue 的专属状态管理库,可以实现跨组件或页面共享状态,是 vuex 状态管理工具的替代品,和 Vuex相比,具备以下优势

  1. 提供更加简单的API (去掉了 mutation )

  2. 提供符合组合式API风格的API (和 Vue3 新语法统一)

  3. 去掉了modules的概念,每一个store都是一个独立的模块

  4. 搭配 TypeScript 一起使用提供可靠的类型推断

官方文档

介绍 | Pinia 中文文档您将喜欢使用的 Vue 存储库icon-default.png?t=O83Ahttps://pinia.web3doc.top/introduction.html安装 pinia 并注册

npm i pinia

在 main.js 中

import { createPinia } from 'pinia'

const app = createApp(App)
// 以插件的形式注册
app.use(createPinia())
app.use(router)
app.mount('#app')

counter案例

核心步骤:

  1. 定义store

  2. 组件使用store

示例

1.定义store

// counter.js
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useCounterStore = defineStore('counter', ()=>{
  // 数据 (state)
  const count = ref(0)

  // 修改数据的方法 (action)
  const increment = ()=>{
    count.value++
  }

  // 以对象形式返回
  return {
    count,
    increment
  }
})

2.组件使用store  

<script setup>
  // 1. 导入use方法
	import { useCounterStore } from '@/stores/counter'
  // 2. 执行方法得到store store里有数据和方法
  const counterStore = useCounterStore()
</script>

<template>
	<button @click="counterStore.increment">
    {{ counterStore.count }}
  </button>
</template>

实现getters

getters直接使用计算属性即可实现

// 数据(state)
const count = ref(0)
// getter (computed)
const doubleCount = computed(() => count.value * 2)

异步action

思想:action函数既支持同步也支持异步,和在组件中发送网络请求写法保持一致步骤:

  1. store中定义action

  2. 组件中触发action

1- store中定义action

const API_URL = 'http://geek.itheima.net/v1_0/channels'

export const useCounterStore = defineStore('counter', ()=>{
  // 数据
  const list = ref([])
  // 异步action
  const loadList = async ()=>{
    const res = await axios.get(API_URL)
    list.value = res.data.data.channels
  }
  
  return {
    list,
    loadList
  }
})

 2- 组件中调用action

<script setup>
	import { useCounterStore } from '@/stores/counter'
  const counterStore = useCounterStore()
  // 调用异步action
  counterStore.loadList()
</script>

<template>
	<ul>
    <li v-for="item in counterStore.list" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

storeToRefs保持响应式解构

直接基于store进行解构赋值,响应式数据(state和getter)会丢失响应式特性,使用storeToRefs辅助保持响应式

<script setup>
import { storeToRefs } from "pinia";
import { useCounterStore } from "@/stores/counter";
const counterStore = useCounterStore();
// 数据使用它storeToRefs包裹之后解构保持响应式
const { count } = storeToRefs(counterStore);
// 方法不用
const { increment } = counterStore;
</script>

<template>
  <button @click="increment">
    {{ count }}
  </button>
</template>

2.项目起步

项目创建+目录整理+git提交

项目创建

目录整理

git提交Gitee作为远程仓库保存Vue项目_本地vue项目配置gitee仓库-CSDN博客文章浏览阅读496次,点赞6次,收藏8次。【代码】Gitee作为远程仓库保存Vue项目。_本地vue项目配置gitee仓库https://blog.csdn.net/2301_76354366/article/details/135698204

jsconfig.json配置别名路径@提示符

新版本的vue3自己做了这个配置,现在不需要手动自己去配了

elementPlus引入

官方文档

安装 | Element PlusA Vue 3 based component library for designers and developersicon-default.png?t=O83Ahttps://element-plus-docs.bklab.cn/zh-CN/guide/installation.html装elementPlus和自动按需导入插件配置

npm i element-plus
npm install -D unplugin-vue-components unplugin-auto-import

配置自动按需导入,在 vite.config.js 中添加

// 引入插件
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'


export default defineConfig({
  plugins: [
    // 配置插件
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ]
})

测试组件

<template>
  <el-button type="primary">i am button</el-button>
</template>

elementPlus主题替换(scss变量替换)

实现步骤

 安装sass

npm i sass -D

准备定制化的样式文件

// styles/element/index.scss
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'primary': (
      // 主色
      'base': #27ba9b,
    ),
    'success': (
      // 成功色
      'base': #1dc779,
    ),
    'warning': (
      // 警告色
      'base': #ffb302,
    ),
    'danger': (
      // 危险色
      'base': #e26237,
    ),
    'error': (
      // 错误色
      'base': #cf4444,
    ),
  )
)

自动导入配置

这里自动导入需要深入到elementPlus的组件中,按照官方的配置文档来

  1. 自动导入定制化样式文件进行样式覆盖

  2. 按需定制主题配置 (需要安装 unplugin-element-plus)

npm i unplugin-element-plus
// vite.config.js
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
// element-plus自动按需导入插件
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [
        ElementPlusResolver({ importStyle: "sass" }),
      ]
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  css: {
    preprocessorOptions: {
      scss: {
        // 自动导入定制化样式文件进行样式覆盖
        additionalData: `
          @use "@/styles/element/index.scss" as *;
        `,
      }
    }
  }
})

axios安装+基础封装

安装axios

npm i axios

基础配置

官方文档地址:起步 | Axios Docs

基础配置通常包括:

  1. 实例化 - baseURL + timeout

  2. 拦截器 - 携带token 401拦截等

// utils/http.js
import axios from 'axios'

// 创建axios实例
const http = axios.create({
  baseURL: 'http://pcapi-xiaotuxian-front-devtest.itheima.net',
  timeout: 5000
})

// axios请求拦截器
http.interceptors.request.use(config => {
  return config
}, e => Promise.reject(e))

// axios响应式拦截器
http.interceptors.response.use(res => res.data, e => {
  return Promise.reject(e)
})

 
export default http

封装请求函数

// apis/testAPI.js
import http from '@/utils/http'

export function getCategoryAPI () {
  return http({
    url: 'home/category/head'
  })
}

调用测试

// main.js
import { getCategoryAPI } from '@/apis/testAPI'

getCategoryAPI().then(res => console.log(res))

路由整体设计

路由设计原则:

找页面的切换方式,如果是整体切换,则为一级路由

如果是在一级路由的内部进行的内容切换,则为二级路由

<template>
  <div>
    <h1>这是首页</h1>
    <!-- 添加二级路由出口 -->
    <router-view></router-view>
  </div>
</template>
<template>
    <div>
        <h1>这是登录页</h1>
    </div>
</template>
<template>
    <h1>我是home页</h1>
</template>
<template>
    <h1>我是分类页</h1>
</template>

 配置路由

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      component: () => import('@/views/Layout/index.vue'),
      children:
        [
          {
            path: '',
            name: 'home',
            component: () => import('@/views/Home/index.vue')
          },
          {
            path: 'category',
            component: () => import('@/views/Category/index.vue')
          }
        ]
    },
    {
      path: '/login',
      component: () => import('@/views/Login/index.vue')
    }
  ],
})

export default router

静态资源初始化

静态资源引入

  1. 图片资源 - 把 images 文件夹放到 assets 目录下

  2. 样式资源 - 把 common.scss 文件放到 styles 目录下

Error Lens插件安装

scss共享样式文件自动导入

为什么要自动导入

在项目里一些组件共享的色值会以scss变量的方式统一放到一个名为 var.scss 文件中,正常组件中使用,需要先导入 scss 文件,比较繁琐,自动导入可以免去手动导入的步骤,直接使用内部的变量。

自动导入配置

1.新增一个 var.scss 文件,存入色值变量

$xtxColor: #27ba9b;
$helpColor: #e26237;
$sucColor: #1dc779;
$warnColor: #ffb302;
$priceColor: #cf4444;

2.通过 vite.config.js 配置自动导入文件

css: {
    preprocessorOptions: {
      scss: {
        // 自动导入scss文件
        additionalData: `
          @use "@/styles/element/index.scss" as *;
          @use "@/styles/var.scss" as *;
        `,
      }
    }
}

3.Layout模块

 组件结构快速熟悉搭建

// LayoutNav.vue
<script setup>
</script>

<template>
  <nav class="app-topnav">
    <div class="container">
      <ul>
        <template v-if="true">
          <li><a href="javascript:;"><i class="iconfont icon-user"></i>周杰伦</a></li>
          <li>
            <el-popconfirm title="确认退出吗?" confirm-button-text="确认" cancel-button-text="取消">
              <template #reference>
                <a href="javascript:;">退出登录</a>
              </template>
            </el-popconfirm>
          </li>
          <li><a href="javascript:;">我的订单</a></li>
          <li><a href="javascript:;">会员中心</a></li>
        </template>
        <template v-else>
          <li><a href="javascript:;">请先登录</a></li>
          <li><a href="javascript:;">帮助中心</a></li>
          <li><a href="javascript:;">关于我们</a></li>
        </template>
      </ul>
    </div>
  </nav>
</template>


<style scoped lang="scss">
.app-topnav {
  background: #333;
  ul {
    display: flex;
    height: 53px;
    justify-content: flex-end;
    align-items: center;
    li {
      a {
        padding: 0 15px;
        color: #cdcdcd;
        line-height: 1;
        display: inline-block;

        i {
          font-size: 14px;
          margin-right: 2px;
        }

        &:hover {
          color: $xtxColor;
        }
      }

      ~ li {
        a {
          border-left: 2px solid #666;
        }
      }
    }
  }
}
</style>
// LayoutHeader.vue
<script setup>
</script>

<template>
  <header class="app-header">
    <div class="container">
      <h1 class="logo">
        <RouterLink to="/">小兔鲜</RouterLink>
      </h1>
      <ul class="app-header-nav">
        <li class="home">
          <RouterLink to="/">首页</RouterLink>
        </li>
        <li><RouterLink to="/">居家</RouterLink></li>
        <li><RouterLink to="/">美食</RouterLink></li>
        <li><RouterLink to="/">服饰</RouterLink></li>
      </ul>
      <div class="search">
        <i class="iconfont icon-search"></i>
        <input type="text" placeholder="搜一搜" />
      </div>
      <!-- 头部购物车 -->
    </div>
  </header>
</template>


<style scoped lang='scss'>
.app-header {
  background: #fff;

  .container {
    display: flex;
    align-items: center;
  }

  .logo {
    width: 200px;

    a {
      display: block;
      height: 132px;
      width: 100%;
      text-indent: -9999px;
      background: url("@/assets/images/logo.png") no-repeat center 18px /
        contain;
    }
  }

  .app-header-nav {
    width: 820px;
    display: flex;
    padding-left: 40px;
    position: relative;
    z-index: 998;

    li {
      margin-right: 40px;
      width: 38px;
      text-align: center;

      a {
        font-size: 16px;
        line-height: 32px;
        height: 32px;
        display: inline-block;

        &:hover {
          color: $xtxColor;
          border-bottom: 1px solid $xtxColor;
        }
      }

      .active {
        color: $xtxColor;
        border-bottom: 1px solid $xtxColor;
      }
    }
  }

  .search {
    width: 170px;
    height: 32px;
    position: relative;
    border-bottom: 1px solid #e7e7e7;
    line-height: 32px;

    .icon-search {
      font-size: 18px;
      margin-left: 5px;
    }

    input {
      width: 140px;
      padding-left: 5px;
      color: #666;
    }
  }

  .cart {
    width: 50px;

    .curr {
      height: 32px;
      line-height: 32px;
      text-align: center;
      position: relative;
      display: block;

      .icon-cart {
        font-size: 22px;
      }

      em {
        font-style: normal;
        position: absolute;
        right: 0;
        top: 0;
        padding: 1px 6px;
        line-height: 1;
        background: $helpColor;
        color: #fff;
        font-size: 12px;
        border-radius: 10px;
        font-family: Arial;
      }
    }
  }
}
</style>
// LayoutFooter.vue
<template>
  <footer class="app_footer">
    <!-- 联系我们 -->
    <div class="contact">
      <div class="container">
        <dl>
          <dt>客户服务</dt>
          <dd><i class="iconfont icon-kefu"></i> 在线客服</dd>
          <dd><i class="iconfont icon-question"></i> 问题反馈</dd>
        </dl>
        <dl>
          <dt>关注我们</dt>
          <dd><i class="iconfont icon-weixin"></i> 公众号</dd>
          <dd><i class="iconfont icon-weibo"></i> 微博</dd>
        </dl>
        <dl>
          <dt>下载APP</dt>
          <dd class="qrcode"><img src="@/assets/images/qrcode.jpg" /></dd>
          <dd class="download">
            <span>扫描二维码</span>
            <span>立马下载APP</span>
            <a href="javascript:;">下载页面</a>
          </dd>
        </dl>
        <dl>
          <dt>服务热线</dt>
          <dd class="hotline">
            400-0000-000 <small>周一至周日 8:00-18:00</small>
          </dd>
        </dl>
      </div>
    </div>
    <!-- 其它 -->
    <div class="extra">
      <div class="container">
        <div class="slogan">
          <a href="javascript:;">
            <i class="iconfont icon-footer01"></i>
            <span>价格亲民</span>
          </a>
          <a href="javascript:;">
            <i class="iconfont icon-footer02"></i>
            <span>物流快捷</span>
          </a>
          <a href="javascript:;">
            <i class="iconfont icon-footer03"></i>
            <span>品质新鲜</span>
          </a>
        </div>
        <!-- 版权信息 -->
        <div class="copyright">
          <p>
            <a href="javascript:;">关于我们</a>
            <a href="javascript:;">帮助中心</a>
            <a href="javascript:;">售后服务</a>
            <a href="javascript:;">配送与验收</a>
            <a href="javascript:;">商务合作</a>
            <a href="javascript:;">搜索推荐</a>
            <a href="javascript:;">友情链接</a>
          </p>
          <p>CopyRight © 小兔鲜儿</p>
        </div>
      </div>
    </div>
  </footer>
</template>
  
  <style scoped lang='scss'>
.app_footer {
  overflow: hidden;
  background-color: #f5f5f5;
  padding-top: 20px;

  .contact {
    background: #fff;

    .container {
      padding: 60px 0 40px 25px;
      display: flex;
    }

    dl {
      height: 190px;
      text-align: center;
      padding: 0 72px;
      border-right: 1px solid #f2f2f2;
      color: #999;

      &:first-child {
        padding-left: 0;
      }

      &:last-child {
        border-right: none;
        padding-right: 0;
      }
    }

    dt {
      line-height: 1;
      font-size: 18px;
    }

    dd {
      margin: 36px 12px 0 0;
      float: left;
      width: 92px;
      height: 92px;
      padding-top: 10px;
      border: 1px solid #ededed;

      .iconfont {
        font-size: 36px;
        display: block;
        color: #666;
      }

      &:hover {
        .iconfont {
          color: $xtxColor;
        }
      }

      &:last-child {
        margin-right: 0;
      }
    }

    .qrcode {
      width: 92px;
      height: 92px;
      padding: 7px;
      border: 1px solid #ededed;
    }

    .download {
      padding-top: 5px;
      font-size: 14px;
      width: auto;
      height: auto;
      border: none;

      span {
        display: block;
      }

      a {
        display: block;
        line-height: 1;
        padding: 10px 25px;
        margin-top: 5px;
        color: #fff;
        border-radius: 2px;
        background-color: $xtxColor;
      }
    }

    .hotline {
      padding-top: 20px;
      font-size: 22px;
      color: #666;
      width: auto;
      height: auto;
      border: none;

      small {
        display: block;
        font-size: 15px;
        color: #999;
      }
    }
  }

  .extra {
    background-color: #333;
  }

  .slogan {
    height: 178px;
    line-height: 58px;
    padding: 60px 100px;
    border-bottom: 1px solid #434343;
    display: flex;
    justify-content: space-between;

    a {
      height: 58px;
      line-height: 58px;
      color: #fff;
      font-size: 28px;

      i {
        font-size: 50px;
        vertical-align: middle;
        margin-right: 10px;
        font-weight: 100;
      }

      span {
        vertical-align: middle;
        text-shadow: 0 0 1px #333;
      }
    }
  }

  .copyright {
    height: 170px;
    padding-top: 40px;
    text-align: center;
    color: #999;
    font-size: 15px;

    p {
      line-height: 1;
      margin-bottom: 20px;
    }

    a {
      color: #999;
      line-height: 1;
      padding: 0 10px;
      border-right: 1px solid #999;

      &:last-child {
        border-right: none;
      }
    }
  }
}
</style>
// index.vue
<script setup>
import LayoutNav from './components/LayoutNav.vue'
import LayoutHeader from './components/LayoutHeader.vue'
import LayoutFooter from './components/LayoutFooter.vue'
</script>

<template>
  <LayoutNav />
  <LayoutHeader />
  <RouterView />
  <LayoutFooter />
</template>

注意要把 main.js 里原来的css文件删除,不要会移位

运行项目

阿里字体图标引入

官网地址

iconfont-阿里巴巴矢量图标库iconfont-国内功能很强大且图标内容很丰富的矢量图标库,提供矢量图标下载、在线存储、格式转换等功能。阿里巴巴体验团队倾力打造,设计和前端开发的便捷工具icon-default.png?t=O83Ahttps://www.iconfont.cn/字体图标采用的是阿里的字体图标库,样式文件已经准备好,在 index.html文件中引入即可

  <link rel="stylesheet" href="//at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">

使用的时候按需引入

 一级导航数据渲染

实现步骤

  1. 封装接口函数

  2. 调用接口函数

  3. v-for渲染模版

 封装接口函数

// /apis/layout.js
import http from '@/utils/http'

export function getCategoryAPI() {
    return http({
        url: '/home/category/head'
    })
}

调用接口函数

// LayoutHeader.vue
<script setup>
import { ref, onMounted } from "vue";
import { getCategoryAPI } from "@/apis/Layout";

const categoryList = ref([]);
const getCategory = async () => {
  const res = await getCategoryAPI();
  categoryList.value = res.result;
};

onMounted(() => getCategory());
</script>

列表渲染

// LayoutHeader.vue
<template>
  <header class="app-header">
    <div class="container">
      <h1 class="logo">
        <RouterLink to="/">小兔鲜</RouterLink>
      </h1>
      <ul class="app-header-nav">
        <li class="home" v-for="item in categoryList" :key="item.id">
          <RouterLink to="/">{{ item.name }}</RouterLink>
        </li>
      </ul>
      <div class="search">
        <i class="iconfont icon-search"></i>
        <input type="text" placeholder="搜一搜" />
      </div>
      <!-- 头部购物车 -->
    </div>
  </header>
</template>

 吸顶导航交互实现

要求:浏览器在上下滚动的过程中,如果距离顶部的滚动距离大于 78px,吸顶导航显示,小于 78px隐藏。

 准备组件静态结构

// LayoutFixed.vue
<script setup>
</script>

<template>
  <div class="app-header-sticky show">
    <div class="container">
      <RouterLink class="logo" to="/" />
      <!-- 导航区域 -->
      <ul class="app-header-nav">
        <li class="home">
          <RouterLink to="/">首页</RouterLink>
        </li>
        <li>
          <RouterLink to="/">居家</RouterLink>
        </li>
        <li>
          <RouterLink to="/">美食</RouterLink>
        </li>
        <li>
          <RouterLink to="/">服饰</RouterLink>
        </li>
        <li>
          <RouterLink to="/">母婴</RouterLink>
        </li>
        <li>
          <RouterLink to="/">个护</RouterLink>
        </li>
        <li>
          <RouterLink to="/">严选</RouterLink>
        </li>
        <li>
          <RouterLink to="/">数码</RouterLink>
        </li>
        <li>
          <RouterLink to="/">运动</RouterLink>
        </li>
        <li>
          <RouterLink to="/">杂项</RouterLink>
        </li>
      </ul>

      <div class="right">
        <RouterLink to="/">品牌</RouterLink>
        <RouterLink to="/">专题</RouterLink>
      </div>
    </div>
  </div>
</template>


<style scoped lang='scss'>
.app-header-sticky {
  width: 100%;
  height: 80px;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 999;
  background-color: #fff;
  border-bottom: 1px solid #e4e4e4;
  // 此处为关键样式!!!
  // 状态一:往上平移自身高度 + 完全透明
  transform: translateY(-100%);
  opacity: 0;

  // 状态二:移除平移 + 完全不透明
  &.show {
    transition: all 0.3s linear;
    transform: none;
    opacity: 1;
  }

  .container {
    display: flex;
    align-items: center;
  }

  .logo {
    width: 200px;
    height: 80px;
    background: url("@/assets/images/logo.png") no-repeat right 2px;
    background-size: 160px auto;
  }

  .right {
    width: 220px;
    display: flex;
    text-align: center;
    padding-left: 40px;
    border-left: 2px solid $xtxColor;

    a {
      width: 38px;
      margin-right: 40px;
      font-size: 16px;
      line-height: 1;

      &:hover {
        color: $xtxColor;
      }
    }
  }
}

.app-header-nav {
  width: 820px;
  display: flex;
  padding-left: 40px;
  position: relative;
  z-index: 998;

  li {
    margin-right: 40px;
    width: 38px;
    text-align: center;

    a {
      font-size: 16px;
      line-height: 32px;
      height: 32px;
      display: inline-block;

      &:hover {
        color: $xtxColor;
        border-bottom: 1px solid $xtxColor;
      }
    }

    .active {
      color: $xtxColor;
      border-bottom: 1px solid $xtxColor;
    }
  }
}
</style>

获取滚动距离

使用 VueUse ,官方定义的一系列函数

官网地址

nullCollection of essential Vue Composition Utilitiesicon-default.png?t=O83Ahttps://v4-11-2.vueuse.org/

npm i @vueuse/core

 以滚动距离做判断条件控制组件盒子展示隐藏

核心逻辑:根据滚动距离判断当前show类名是否显示,大于78显示,小于78,不显示

<script setup>
// vueUse
import { useScroll } from '@vueuse/core'
const { y } = useScroll(window)
</script>

<template>
  <div class="app-header-sticky" :class="{ show: y > 78 }">
    <!-- 省略部分代码 -->
  </div>
</template>

 Pinia优化重复请求

结论:两个导航中的列表是完全一致的,但是要发送两次网络请求,存在浪费。通过Pinia集中管理数据,再把数据给组件使用。

定义 pinia 进行状态管理

// /stores/category.js
import { defineStore } from 'pinia'
import { getCategoryAPI } from "@/apis/layout";
import { ref } from 'vue'

export const useCategoryStore = defineStore('category', () => {
    // state 导航列表数据
    const categoryList = ref([]);

    // action 获取导航列表方法
    const getCategory = async () => {
        const res = await getCategoryAPI();
        categoryList.value = res.result;
    };


    return { categoryList, getCategory }
})

 在 index.vue 中进行触发

在需要用的地方进行导入调用


http://www.kler.cn/a/390434.html

相关文章:

  • 【C++】C++11特性(上)
  • 「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
  • 猿创征文|Inscode桌面IDE:打造高效开发新体验
  • 解决表格出现滚动条样式错乱问题
  • power bi中的related函数解析
  • 操作系统离散存储练习题
  • 面试经典 150 题:121,125
  • 批量混剪矩阵发布助力短视频营销快速获客
  • 深度学习服务器租赁AutoDL
  • 使用git进行多人协作开发项目流程
  • Android WebSocket ping pong机制
  • MySQL如何利用索引优化ORDER BY排序语句
  • 【博主推荐】VUE开发常用技术点收集
  • QT中使用图表之QChart绘制动态折线图
  • Sam Altman:年底将有重磅更新,但不是GPT-5!
  • C# 有趣的小程序—桌面精灵详细讲解
  • docker save 和 docker load介绍
  • CTF记录
  • Chromium 中chrome.tabs扩展接口定义c++
  • C语言之简单的获取命令行参数和环境变量
  • 进程 线程 和go协程的区别
  • C++ 内联函数 详解分析 (含代码分析)
  • 深入 JVM 调优:全面提升 Java 应用性能
  • python获取iOS最近业务日志的两种方法
  • 2024华为OD机试真题---中文分词模拟器
  • C/C++基础知识复习(15)