React antd的datePicker自定义,封装成组件

一、antd的datePicker自定义
需求:用户需要为日期选择器的每个日期单元格添加一个Tooltip,当鼠标悬停时显示日期、可兑换流量余额和本公会可兑流量。这些数据需要从接口获取。我需要结合之前的代码,确保Tooltip正确显示,并且数据来自接口。

主要汉化点:

  1. 整个日期选择器面板中文化
  2. 星期显示为中文(周一 到 周日)
  3. 月份显示为中文格式
  4. 操作按钮汉化("确定"、"现在" 等)
  5. 日期格式统一使用中文年月日
  6. 加载提示中文化
  7. Tooltip内容中文化

效果包含:

  • 月份显示为 "2024年5月"
  • 星期列显示为 "一、二、三、四、五、六、日"
  • 今天按钮显示为 "今天"
  • 确定按钮显示为 "确定"
  • 十年范围显示为 "2020-2029"
  • 时间列显示为 "时","分","秒"
  • index.tsx文件
import React, { useState, useEffect } from 'react';
import { DatePicker, Tooltip, Spin, ConfigProvider } from 'antd';
import dayjs, { Dayjs } from 'dayjs';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import './custom-datepicker.css';
import 'dayjs/locale/zh-cn';
import zhCN from 'antd/locale/zh_CN';
dayjs.extend(isSameOrAfter);
dayjs.extend(isSameOrBefore);
dayjs.locale('zh-cn'); // 设置dayjs为中文

interface TrafficData {
    date: string;
    personal: string;
    guild: string;
}

const App: React.FC = () => {
  const [selectedDate, setSelectedDate] = useState<Dayjs | null>(null);
  const [trafficData, setTrafficData] = useState<Record<string, TrafficData>>({});
  const [loading, setLoading] = useState(true);

  const today = dayjs().startOf('day');
  const sevenDaysLater = today.add(6, 'day');

  useEffect(() => {
    const mockApi = async () => {
      const data: Record<string, TrafficData> = {};
      Array.from({ length: 7 }).forEach((_, i) => {
        const date = today.add(i, 'day').format('YYYY-MM-DD');
        data[date] = {
          date,
          personal: `${[0, 20, 30, 40, 80, 100, 50][i]}%`,
          guild: `${Math.floor(Math.random() * 100000).toLocaleString()}`,
        };
      });

      await new Promise(resolve => setTimeout(resolve, 500));
      setTrafficData(data);
      setLoading(false);
    };

    mockApi();
  }, []);

  const disabledDate = (current: Dayjs) => current.isBefore(today, 'day') || current.isAfter(sevenDaysLater, 'day');

  if (loading) return <Spin tip="数据加载中..." />;

  return (
    <ConfigProvider locale={zhCN}> {/* 设置Ant Design为中文 */}
      <DatePicker
        value={selectedDate}
        disabledDate={disabledDate}
        onChange={setSelectedDate}
        dropdownClassName="custom-picker-dropdown"
        dateRender={current => {
          const dateStr = current.format('YYYY-MM-DD');
          const data = trafficData[dateStr];
          const isInRange = current.isSameOrAfter(today) && current.isSameOrBefore(sevenDaysLater);
          const isSelected = selectedDate?.isSame(current, 'day');

          return (
            <div className="custom-cell-wrapper">
              <div className="native-cell-content">
                {current.date()}
              </div>
              <Tooltip
                title={data ?
                  `${dayjs(dateStr).format('YYYY年M月D日')}\n可兑流量余额: ${data.personal}\n本公会可兑流量: ${data.guild}`
                  : '无可用数据'}
                overlayStyle={{
                  whiteSpace: 'pre-line',
                  pointerEvents: 'none',
                }}
                placement="bottom"
                mouseEnterDelay={0}
                mouseLeaveDelay={0.1}
                trigger={['hover']}
                getPopupContainer={trigger => trigger.parentElement!}
              >
                <div className={`custom-cell ${isInRange ? 'recent-date' : ''}`}>
                  <div className={`date-number ${isSelected ? 'selected' : ''}`}>
                    {current.date()}
                  </div>
                  {data && (
                    <div className={`availability ${data.personal === '0%' ? 'empty' : ''}`}>
                                            余{data.personal}
                    </div>
                  )}
                </div>
              </Tooltip>
            </div>
          );
        }}
      />
    </ConfigProvider>
  );
};

export default App;
  • custom-datepicker.css文件
/* custom-datepicker.css */
.custom-picker-dropdown {
    z-index: 1001;
}

.custom-cell-wrapper {
    position: relative;
    height: 100%;
    width: 100%;
}

.native-cell-content {
    visibility: hidden;
}

.custom-cell {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
    padding: 3px 0;
}

.date-number {
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    color: #000;
    transition: all 0.2s;
    border-radius: 50%;
}

.date-number.selected {
    background: #1890ff;
    color: white !important;
}

.recent-date:hover .date-number:not(.selected) {
    color: #1890ff;
}

.availability {
    font-size: 10px;
    line-height: 14px;
    color: #1890ff;
    margin-top: 2px;
}

.availability.empty {
    color: #ff4d4f !important;
}

.ant-picker-cell-inner {
    padding: 0 !important;
    height: 100% !important;
}

.ant-picker-cell:hover .ant-picker-cell-inner {
    background: transparent !important;
}

/* 添加中文面板样式调整 */
.ant-picker-date-panel {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
}

.ant-picker-header-view button {
    font-weight: 500;
}

.ant-picker-cell-inner::before {
    border-radius: 50% !important;
}

二、封装成组件

  • DateSelector.tsx文件
// DateSelector.tsx
import React from 'react';
import {DatePicker, Tooltip, Spin, ConfigProvider} from 'antd';
import dayjs, { Dayjs } from 'dayjs';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import 'dayjs/locale/zh-cn';
import './custom-datepicker.css';
import zhCN from 'antd/locale/zh_CN';

dayjs.extend(isSameOrAfter);
dayjs.extend(isSameOrBefore);

export interface TrafficData {
    personal: string;
    guild: string;
}

interface DateSelectorProps {
    value?: Dayjs | null;
    trafficData: Record<string, TrafficData>;
    onChange?: (date: Dayjs | null) => void;
    loading?: boolean;
}

const DateSelector: React.FC<DateSelectorProps> = ({
  value,
  trafficData,
  onChange,
  loading = false,
}) => {
  const today = dayjs().startOf('day');
  const sevenDaysLater = today.add(6, 'day');

  const disabledDate = (current: Dayjs) => current.isBefore(today, 'day') || current.isAfter(sevenDaysLater, 'day');

  const handleChange = (date: Dayjs | null) => {
    onChange?.(date);
  };

  if (loading) {
    return <Spin tip="数据加载中..." style={{ padding: '8px 0' }} />;
  }

  return (
    <ConfigProvider locale={zhCN}> {/* 设置Ant Design为中文 */}
      <DatePicker
        value={value}
        disabledDate={disabledDate}
        onChange={handleChange}
        dropdownClassName="custom-picker-dropdown"
        dateRender={current => {
          const dateStr = current.format('YYYY-MM-DD');
          const data = trafficData[dateStr];
          const isInRange = current.isSameOrAfter(today) && current.isSameOrBefore(sevenDaysLater);
          const isSelected = value?.isSame(current, 'day');

          return (
            <div className="custom-cell-wrapper">
              <div className="native-cell-content">{current.date()}</div>
              <Tooltip
                title={data ?
                  `${dayjs(dateStr).format('YYYY年M月D日')}\n可兑流量余额: ${data.personal}\n本公会可兑流量: ${data.guild}`
                  : '无可用数据'}
                overlayStyle={{
                  whiteSpace: 'pre-line',
                  pointerEvents: 'none',
                }}
                placement="bottom"
                mouseEnterDelay={0}
                mouseLeaveDelay={0.1}
              >
                <div className={`custom-cell ${isInRange ? 'recent-date' : ''}`}>
                  <div className={`date-number ${isSelected ? 'selected' : ''}`}>
                    {current.date()}
                  </div>
                  {data && (
                    <div className={`availability ${data.personal === '0%' ? 'empty' : ''}`}>
                                            余{data.personal}
                    </div>
                  )}
                </div>
              </Tooltip>
            </div>
          );
        }}
      />
    </ConfigProvider>
  );
};

export default DateSelector;
  • custom-datepicker.css
/* custom-datepicker.css */
.custom-picker-dropdown {
    z-index: 1001;
}

.custom-cell-wrapper {
    position: relative;
    height: 100%;
    width: 100%;
}

.native-cell-content {
    visibility: hidden;
}

.custom-cell {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
    padding: 3px 0;
}

.date-number {
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    color: #000;
    transition: all 0.2s;
    border-radius: 50%;
}

.date-number.selected {
    background: #1890ff;
    color: white !important;
}

.recent-date:hover .date-number:not(.selected) {
    color: #1890ff;
}

.availability {
    font-size: 10px;
    line-height: 14px;
    color: #1890ff;
    margin-top: 2px;
}

.availability.empty {
    color: #ff4d4f !important;
}

.ant-picker-cell-inner {
    padding: 0 !important;
    height: 100% !important;
}

.ant-picker-cell:hover .ant-picker-cell-inner {
    background: transparent !important;
}

/* 添加中文面板样式调整 */
.ant-picker-date-panel {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
}

.ant-picker-header-view button {
    font-weight: 500;
}

.ant-picker-cell-inner::before {
    border-radius: 50% !important;
}
  • index.tsx文件
// 使用示例 ParentComponent.tsx
import React, { useState, useEffect } from 'react';
import DateSelector, { TrafficData } from './DateSelector';
import dayjs from 'dayjs';

const ParentComponent: React.FC = () => {
  const [selectedDate, setSelectedDate] = useState<dayjs.Dayjs | null>(null);
  const [trafficData, setTrafficData] = useState<Record<string, TrafficData>>({});
  const [loading, setLoading] = useState(true);

  const today = dayjs().startOf('day');

  // useEffect(() => {
  //   // 模拟API调用
  //   const mockFetchData = async () => {
  //     const mockData = {
  //       [dayjs().format('YYYY-MM-DD')]: {
  //         personal: '80%',
  //         guild: '100,000',
  //       },
  //       [dayjs().add(1, 'day')
  //         .format('YYYY-MM-DD')]: {
  //         personal: '50%',
  //         guild: '75,000',
  //       },
  //     };
  //
  //     await new Promise(resolve => setTimeout(resolve, 800));
  //     setTrafficData(mockData);
  //     setLoading(false);
  //   };
  //
  //   mockFetchData();
  // }, []);

  useEffect(() => {
    const mockApi = async () => {
      const data: Record<string, TrafficData> = {};
      Array.from({ length: 7 }).forEach((_, i) => {
        const date = today.add(i, 'day').format('YYYY-MM-DD');
        data[date] = {
          personal: `${[0, 20, 30, 40, 80, 100, 50][i]}%`,
          guild: `${Math.floor(Math.random() * 100000).toLocaleString()}`,
        };
      });

      await new Promise(resolve => setTimeout(resolve, 500));
      setTrafficData(data);
      setLoading(false);
    };

    mockApi();
  }, []);

  return (
    <div style={{ padding: 24 }}>
      <h2>日期选择器示例</h2>
      <div style={{ marginBottom: 16 }}>
                当前选择:{selectedDate?.format('YYYY年M月D日') || '未选择'}
      </div>
      <DateSelector
        value={selectedDate}
        trafficData={trafficData}
        onChange={setSelectedDate}
        loading={loading}
      />
    </div>
  );
};

export default ParentComponent;

三、生效时间选择完日期后,还需填入具体时间(或提供一个时间选择器),精确到分,默认为00:00;如选择的日期为今天,则填写的时间不能早于当前时间

// index.tsx
import React, { useState, useEffect } from 'react';
import { Row, Col, TimePicker, Spin, ConfigProvider } from 'antd';
import DateSelector, { TrafficData } from './DateSelector';
import dayjs, { Dayjs } from 'dayjs';
import zhCN from 'antd/locale/zh_CN';

declare module 'dayjs' {
  interface Dayjs {
    isToday(): boolean;
  }
}

dayjs.extend((o, c) => {
  c.prototype.isToday = function () {
    return this.isSame(dayjs(), 'day');
  }
});

const DateTimePicker: React.FC = () => {
  const [selectedDate, setSelectedDate] = useState<Dayjs | null>(null);
  const [selectedTime, setSelectedTime] = useState<Dayjs>(dayjs().startOf('minute'));
  const [trafficData, setTrafficData] = useState<Record<string, TrafficData>>({});
  const [loading, setLoading] = useState(true);
  const today = dayjs().startOf('day');

  const disabledTime = (current: Dayjs | null) => {
    if (!current || !selectedDate?.isToday()) {
      return { disabledHours: () => [], disabledMinutes: () => [] };
    }

    const now = dayjs();
    return {
      disabledHours: () => {
        const currentHour = now.hour();
        return Array.from({ length: currentHour }, (_, i) => i);
      },
      disabledMinutes: (selectedHour: number) => {
        if (selectedHour < now.hour()) return [];
        return Array.from({ length: now.minute() }, (_, i) => i);
      },
    };
  };

  const handleDateChange = (date: Dayjs | null) => {
    setSelectedDate(date);
    setSelectedTime(date?.isToday() ? dayjs().startOf('minute') : dayjs().startOf('day'));
  };

  // useEffect(() => {
  //   // 模拟API请求
  //   const mockData = {
  //     [dayjs().format('YYYY-MM-DD')]: { personal: '80%', guild: '100,000' },
  //     [dayjs().add(1, 'day')
  //       .format('YYYY-MM-DD')]: { personal: '50%', guild: '75,000' },
  //   };
  //
  //   setTimeout(() => {
  //     setTrafficData(mockData);
  //     setLoading(false);
  //   }, 800);
  // }, []);

  useEffect(() => {
    const mockApi = async () => {
      const data: Record<string, TrafficData> = {};
      Array.from({ length: 7 }).forEach((_, i) => {
        const date = today.add(i, 'day').format('YYYY-MM-DD');
        data[date] = {
          personal: `${[0, 20, 30, 40, 80, 100, 50][i]}%`,
          guild: `${Math.floor(Math.random() * 100000).toLocaleString()}`,
        };
      });

      await new Promise(resolve => setTimeout(resolve, 500));
      setTrafficData(data);
      setLoading(false);
    };

    mockApi();
  }, []);

  return (
    <ConfigProvider locale={zhCN}> {/* 设置Ant Design为中文 */}
      <div style={{ padding: 24, maxWidth: 380, margin: '0 auto' }}>
        <h2 style={{ marginBottom: 24 }}>预约时间选择</h2>

        <Row gutter={24} align="middle">
          <Col span={12}>
            {/*<div style={{ marginBottom: 8 }}>选择日期</div>*/}
            <DateSelector
              value={selectedDate}
              trafficData={trafficData}
              onChange={handleDateChange}
              loading={loading}
            />
          </Col>

          <Col span={12}>
            {/*<div style={{ marginBottom: 8 }}>选择时间</div>*/}
            <TimePicker
              value={selectedTime}
              format="HH:mm"
              minuteStep={1}
              disabledTime={disabledTime}
              onChange={time => setSelectedTime(time || dayjs().startOf('minute'))}
              placeholder="请选择时间"
              disabled={!selectedDate}
              allowClear={false}
              showNow={false}
              style={{ width: '100%' }}
            />
          </Col>
        </Row>

        <div style={{ marginTop: 24, padding: 16, background: '#f5f5f5', borderRadius: 4 }}>
          已选择时间: {selectedDate ?
            `${selectedDate.format('YYYY年MM月DD日')} ${selectedTime.format('HH:mm')}`
            : '请先选择日期'}
        </div>
      </div>
    </ConfigProvider>
  );
};

export default DateTimePicker;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NVIDIA GPU 架构详解:Pascal、Volta、Turing、Ampere、Ada、Hopper、Blackwell

目录 1. Pascal&#xff08;帕斯卡&#xff09;架构&#xff08;2016&#xff09;关键技术性能特性代表产品应用场景 2. Volta&#xff08;伏特&#xff09;架构&#xff08;2017&#xff09;关键技术性能特性代表产品应用场景 3.Turing&#xff08;图灵&#xff09;架构&#…

Linux 命令行的基本命令(生信)

常见的操作系统包括 Windows、Mac OS X 和 Unix 。Linux 是类 Unix 操作系 统&#xff0c; 可安装在各种各样的电脑硬件设备&#xff0c; 从手机、平板电脑、路由器到超级计算 机。Linux 是一个领先的操作系统&#xff0c;世界上最快的十台超级计算机运行的都是 Linux 操作系统…

ECharts--中国地图(无敌详细)

前段时间需要做一个中国地图的页面&#xff0c;要求是展示各地产品的销量&#xff0c;我就在网上搜了很多ECharts的资料&#xff0c;学习了一下怎么使用。 本着互相学习&#xff0c;共同进步的原则&#xff0c;特此分享一下自己的学习经验以及使用技巧。如果有用的话可以给老弟…

QwenVL 2.5-本地安装编译布署全教程

开篇 DeepSeek开源后我国又开源了一个震撼大模型,QwenVL2.5,这是一个多模态的模形,它可以认图、识图、更能作图,还能读懂video。 Qwen2.5-VL 的主要特点如下所示: 感知更丰富的世界:Qwen2.5-VL 不仅擅长识别常见物体,如花、鸟、鱼和昆虫,还能够分析图像中的文本、图表…

【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现

项目介绍 本课程演示的是一款 基于SpringBoot电脑DIY装机教程网站的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…

React高级内容探索

flushSync确保了DOM立即更新 flushSync让你强制React同步刷新提供回调中的任何更新&#xff0c;这确保了DOM立即更新 flushSync是DOM更新之后的&#xff0c;像vue中的nextTick&#xff1a; import { useState,useRef} from "react" import { flushSync} from &quo…

基于 MetaGPT 自部署一个类似 MGX 的多智能体协作框架

MGX&#xff08;由 MetaGPT 团队开发的 mgx.dev&#xff09;是一个收费的多智能体编程平台&#xff0c;提供从需求分析到代码生成、测试和修复的全流程自动化功能。虽然 MGX 本身需要付费&#xff0c;但您可以通过免费服务和开源项目搭建一个类似的功能。以下是一个分步骤的实现…

主时钟与虚拟时钟约束

1、主时钟约束 1.1、主时钟约束语法&#xff1a; create_clock -name< clock_name > -period <period> -waveform{ <rise_time> <fall_time> } [get_ports< port_name >] 说明&#xff1a; name 之后的<clock_name> 是clk 的name&a…

CyberRT(apollo) 定时器模块简述及bug分析

timer 模块 timer的定义&#xff0c;cyberrt中timer模块用于设置定时器任务&#xff0c;字面意思&#xff0c;设置设置定时周期及出发频次&#xff08;周期 or oneshot)&#xff0c;到达指定时间时间触发callback time wheel 时钟节拍轮&#xff0c;常见的定时器设计&#x…

网络安全月度报告

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 3.1.1网络安全现状及安全挑战 网络的出现给人们的工作和生活带来了极大的便利&#xff0c;但同时也带来了极大的安全风险。在信息传输和交换时&#xff0c;需要对…

nio多线程版本

多线程多路复用 多线程NIO&#xff0c;&#xff0c;就是多个线程&#xff0c;每个线程上都有一个Selector&#xff0c;&#xff0c;&#xff0c;比如说一个系统中一个线程用来接收请求&#xff0c;&#xff0c;剩余的线程用来读写数据&#xff0c;&#xff0c;每个线程独立干自…

一周学会Flask3 Python Web开发-Flask3之表单处理WTForms安装与定义WTForms表单类

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们平时开发项目&#xff0c;都会用到表单&#xff0c;编写表单&#xff0c;提交表单&#xff0c;验证表单&#xff0c;如果…

基于NI USRP 硬件的下一代O-RAN研究测试台​

目录 基于NI SDR硬件的下一代O-RAN研究测试台​挑战&#xff1a;解决方案&#xff1a; 基于NI SDR硬件的下一代O-RAN研究测试台​ “OAIC提供了一个开放平台&#xff08;包括软件架构、库和工具集&#xff09;&#xff0c;用于对基于AI的无线接入网(RAN)控制器进行原型开发和测…

【开源-鸿蒙土拨鼠大理石系统】鸿蒙 HarmonyOS Next App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/cheinlu/HarmonyOS-groundhog-mar…

笔记本电脑本地部署ollama大模型(显存不足调用CUDA Unified Memory方法)

软硬件&#xff1a;win11,NVIDIA GeForce RTX 3050 显存4g 一.ollama模型最低要求 1. Llama 3.1 (8B) 模型 GPU: 至少需要 1 张具有 16 GB 显存的 GPU&#xff08;例如 NVIDIA Tesla V100 或 A100&#xff09;。CPU: 高性能的多核处理器&#xff08;例如 Intel Xeon 或 AMD …

【Rancher】简化Kubernetes容器管理与部署的开源平台

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Rancher 2、Rancher诞生里程 …

vscode通过ssh远程连接(linux系统)不能跳转问题

1.问题描述 unbantu中的vscode能够通过函数跳转到函数定义&#xff0c;而windows通过ssh连接unbantu的vscode却无法跳转 2.原因&#xff1a; 主要原因是这里缺少插件&#xff0c;这里是unbantu给主机的服务器&#xff0c;与ubantu本地vscode插件相互独立&#xff0c;能否跳转…

思维链 Chain-of-Thought Prompting

论文: Chain-of-Thought Prompting Elicits Reasoning in Large Language Models (Wei et al., 2022) 核心贡献: 首次提出通过显式的中间推理步骤&#xff08;即思维链&#xff09;提升大语言模型的复杂推理能力。该方法通过示例展示多步推理过程&#xff0c;引导模型生成逻辑…

计算机毕业设计SpringBoot+Vue.js体育馆管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

MySQL笔记---Ubuntu环境下从零开始的MySQL

1. 安装MySQL 1.1 自动安装&#xff08;固定版本&#xff09; 更新软件包列表&#xff1a;在终端中执行以下命令&#xff0c;以更新系统的软件包列表&#xff1a; sudo apt update安装MySQL服务器&#xff1a;运行以下命令安装MySQL服务器&#xff1a; sudo apt install mysql…