增删改查表格(好看且有趣)

演示地址:https://codepen.io/kissbackboard/pen/oNExNKL

目前实现了增删改查、排序、趣味提示信息、回收站。

右边的猫头鹰是使用Spline3D设计工具制作,我拿官方模型库里的加工了一下

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, addial-scale=1.0">
    <title></title>
    <!-- 主要的CSS -->
    <link rel="stylesheet" href="css/main.css">
</head>

<body>
    <div id="root">
        <!-- 用于输入新增用户信息的表单 -->
        <transition name="modalBox" appear>
            <div v-show="showOperate" class="operate" @click.self="showOperate = ifOwlSpeak = false">
                <div @keyup.enter.stop="affirm">
                    <label>学号:</label>
                    <input type="number" ref="addCode" v-model="addCode" @input="OwlSpeakShow('若学号重复会无法提交哦')"><br>
                    <label>姓名:</label>
                    <input type="text" @keydown="banSpace" v-model="addName"><br>
                    <label>性别:</label>
                    <select class="addSex" v-model="addSex" @change="OwlSpeakShow('原来是一位' + addSex + '同学啊')">
                        <option value="男">男</option>
                        <option value="女">女</option>
                    </select><br>
                    <label>年龄:</label>
                    <input type="number" v-model="addAge" @input="OwlSpeakShow('按回车也可以提交哦')"><br>
                    <button @click="affirm" class="affirmBtn">确定</button>
                    <button @click="showOperate = ifOwlSpeak = false" class="cancelBtn">取消</button>
                </div>
            </div>
        </transition>
        <!-- 新增、查询、回收站功能 -->
        <button @click="add" class="addBtn" @mouseenter="OwlSpeakShow('是有新同学要来吗')" @mouseleave="OwlSpeakHide">添加学生</button>
        <input type="text" placeholder="按姓名查询" class="inquireName" @focus="inquireAlone('name')" v-model="inquireNameValue" @input="inquireName" @mouseenter="OwlSpeakShow('输入后会自动查询')" @mouseleave="OwlSpeakHide">
        <input type="number" placeholder="按学号查询" class="inquireCode" @focus="inquireAlone('code')" v-model="inquireCodeValue" @input="inquireCode" @mouseenter="OwlSpeakShow('用完整学号查询最准确了')" @mouseleave="OwlSpeakHide">
        <button class="recycleBtn" @click="showRecycle = true" @mouseenter="OwlSpeakShow('可以查看被删除的学生')" @mouseleave="OwlSpeakHide">回收站</button>
        <!-- 回收站表格 -->
        <transition name="modalBox" appear>
            <div class="recycleInfoTable" @click.self="showRecycle = false" v-show="showRecycle">
                <h1>回收站</h1>
                <table cellspacing='1' cellpadding='0' class="infoTable">
                    <thead>
                        <tr>
                            <th @click="recycleVariousSort('code')" @mouseenter="OwlSpeakShow('点击可以按学号排序')" @mouseleave="OwlSpeakHide">学号</th>
                            <th @click="recycleVariousSort('name')" @mouseenter="OwlSpeakShow('点击可以按姓名排序')" @mouseleave="OwlSpeakHide">姓名</th>
                            <th @click="recycleVariousSort('date')" @mouseenter="OwlSpeakShow('点击可以按日期排序')" @mouseleave="OwlSpeakHide">删除时间</th>
                            <th @dblclick="allEmpty" @mouseenter="OwlSpeakShow('双击清空回收站所有信息')" @mouseleave="OwlSpeakHide">操作</th>
                        </tr>
                    </thead>
                    <tbody is="transition-group" name="fade" appear>
                        <tr v-for="user in recycleInfo" v-show="user.satisfy" :key="user.id">
                            <td>{{user.code}}</td>
                            <td>{{user.name}}</td>
                            <td>{{user.date | timeformater}}</td>
                            <!--还原和彻底删除操作 -->
                            <td>
                                <button class="saveBtn" @click="reductionInfo(user)" @mouseenter="OwlSpeakShow('点击还原 ' + user.name + ' 的信息')" @mouseleave="OwlSpeakHide">还原</button>
                                <button class="deleteBtn" @click="thoroughDeleteInfo(user)" @mouseenter="OwlSpeakShow('彻底删除 ' + user.name + ' 的信息')" @mouseleave="OwlSpeakHide">彻底删除</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </transition>
        <!-- 学生信息表格 -->
        <table cellspacing='1' cellpadding='0' class="infoTable">
            <thead>
                <tr>
                    <th @click="variousSort('code')" @mouseenter="OwlSpeakShow('点击可以按学号排序')" @mouseleave="OwlSpeakHide">学号</th>
                    <th @click="variousSort('name')" @mouseenter="OwlSpeakShow('点击按姓氏首字母排序')" @mouseleave="OwlSpeakHide">姓名</th>
                    <th @click="variousSort('sex')" @mouseenter="OwlSpeakShow('点击可以按性别排序')" @mouseleave="OwlSpeakHide">性别</th>
                    <th @click="variousSort('age')" @mouseenter="OwlSpeakShow('点击可以按年龄排序')" @mouseleave="OwlSpeakHide">年龄</th>
                    <th @mouseenter="OwlSpeakShow('目前一共有 ' + info.length + ' 位学生')" @mouseleave="OwlSpeakHide">操作</th>
                </tr>
            </thead>
            <tbody is="transition-group" name="fade" appear>
                <tr v-for="user in info" v-show="user.satisfy" @keyup.enter.stop="currentCodeIfRepeat(user)" :key="user.id">
                    <td>
                        <span v-show="!user.isEdit">{{user.code}}</span><input ref="editFirst" v-show="user.isEdit" type="number" v-model="user.code" @input="OwlSpeakShow('若学号重复会无法保存哦')">
                    </td>
                    <td>
                        <span v-show="!user.isEdit">{{user.name}}</span><input v-show="user.isEdit" type="text" v-model="user.name" @keydown="banSpace">
                    </td>
                    <td>
                        <span v-show="!user.isEdit">{{user.sex}}</span>
                        <select v-show="user.isEdit" v-model="user.sex">
                            <option value="男">男</option>
                            <option value="女">女</option>
                        </select>
                    </td>
                    <td>
                        <span v-show="!user.isEdit">{{user.age}}</span><input v-show="user.isEdit" type="number" v-model="user.age">
                    </td>
                    <!-- 编辑和删除操作 -->
                    <td>
                        <button v-show="user.isEdit" @click="edit(user)" class="saveBtn" @mouseenter="OwlSpeakShow('按回车键也可以保存哦')" @mouseleave="OwlSpeakHide">保存</button>
                        <button v-show="!user.isEdit" @click="edit(user)" class="editBtn" @mouseenter="OwlSpeakShow(user.name +' 的信息有误吗')" @mouseleave="OwlSpeakHide">编辑</button>
                        <button @click="deleteInfo(user)" class="deleteBtn" @mouseenter="OwlSpeakShow('你要删除 '+ user.name +' 吗?')" @mouseleave="OwlSpeakHide">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <!-- 猫头鹰 webGL -->
        <div class="owl" @mouseenter="OwlSpeakShow('应该不会有bug了吧...')" @mouseleave="OwlSpeakHide" v-show="ifOwl">
            <div :class="[{ cover: !owlLoadIfSucceed }, { part: owlLoadIfSucceed }]" @click="ifOwl = false" @mouseenter="OwlSpeakShow('点击后将把我隐藏')" @mouseleave="OwlSpeakHide">{{owlLoadInfo}}</div>
            <p v-show="ifOwlSpeak">{{owlSpeak}}</p>
            <!-- 使用Spline3D设计工具制作 -->
            <iframe src='https://my.spline.design/copy-15a6b025c7aac1efc79c2de6c4aac93a/' frameborder='0' width='180px' height='180px' scrolling="no" @load="owlLoad"></iframe>
        </div>
    </div>
    <!-- JS部分 -->
    <script src="js/dayjs.min.js"></script>
    <script src="js/vue.js"></script>
    <!-- 默认的学生信息,方便测试各个功能(可删除) -->
    <script src="js/defaultInfo.js"></script>
    <!-- 主要的JS -->
    <script src="js/main.js"></script>
</body>

</html>

CSS:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    display: flex;
    justify-content: center;
}

#root {
    padding-top: 30px;
    position: relative;
}

button {
    cursor: pointer;
    user-select: none;
}

.infoTable {
    margin-top: 20px;
    background-color: rgb(255, 255, 255);
    border-radius: 5px;
    overflow: hidden;
}

.infoTable td,
.infoTable th {
    padding: 6px;
    min-width: 180px;
    max-width: 25vw;
    height: 50px;
    overflow: auto;
    text-align: center;
    background-color: #3d559d;
    color: white;
}

.infoTable th {
    height: 40px;
    background-color: #6472b8;
    cursor: pointer;
    user-select: none;
}

.infoTable tr td:last-child button {
    width: 40%;
    height: 30px;
    background-color: white;
    border: none;
    border-radius: 2px;
}

.infoTable tbody tr td .editBtn {
    color: #032ebc;
}

.infoTable tbody tr td .saveBtn {
    color: #032ebc;
    font-weight: 900;
}

.infoTable tbody tr td .deleteBtn {
    color: rgb(255, 57, 57);
}

.infoTable tbody tr:hover {
    opacity: 0.85;
}

.recycleInfoTable {
    width: 100vw;
    height: 100vh;
    position: fixed;
    z-index: 2;
    top: 0px;
    left: 0px;
    background-color: #ffffffaf;
    display: flex;
    justify-content: center;
    padding-top: 60px;
}

.recycleInfoTable table {
    height: 1px;
}

.recycleInfoTable td:nth-child(3),
.recycleInfoTable th:nth-child(3) {
    padding: 6px;
    width: 360px;
    height: 30px;
}

.recycleInfoTable h1 {
    position: absolute;
    top: 10px;
    color: rgb(255, 57, 57);
}

.operate {
    display: grid;
    place-content: center;
    width: 100vw;
    height: 100vh;
    background-color: #3d559d41;
    position: fixed;
    z-index: 9;
    top: 0px;
    left: 0px;
}

.operate div {
    width: 500px;
    height: 280px;
    background-color: #ffffff;
    text-align: center;
    padding-top: 20px;
    box-shadow: 1px 6px 15px 1px rgba(0, 0, 0, 0.4);
    border-radius: 5px;
}

.operate div input,
.addSex {
    width: 50%;
    height: 30px;
    margin-top: 15px;
    padding-left: 5px;
}

.operate div input:focus {
    outline-color: #3d6bff;
}

.operate div button {
    margin-top: 20px;
    margin-left: 30px;
    margin-right: 30px;
    width: 22%;
    height: 15%;
    background-color: #6776ff;
    border: none;
    color: white;
    font-size: 16px;
    border-radius: 3px;
}

.operate div label {
    font-weight: 900;
    letter-spacing: 5px;
}

/* 学生信息表格中的表单 */
.infoTable tbody tr td input,
.infoTable tbody tr td select {
    text-align: center;
    width: 150px;
    height: 33px;
    font-size: 15px;
}

.infoTable tbody tr td input:focus {
    outline-color: #2e5eff;
}

.addBtn {
    width: 120px;
    height: 40px;
    background-color: #4d5ffd;
    border: none;
    color: white;
    font-size: 16px;
    border-radius: 3px;
    /* word-spacing: 1px; */
}

.recycleBtn {
    width: 120px;
    height: 40px;
    background-color: #fd4b37;
    border: none;
    color: white;
    font-size: 16px;
    border-radius: 3px;
    position: fixed;
    right: 10px;
    bottom: 10px;
}

/* 用于查询的表单 */
.inquireCode,
.inquireName {
    width: 150px;
    height: 37px;
    position: absolute;
    z-index: 99;
    right: 0px;
    top: 30px;
    text-align: center;
    border: 1px solid #5b84ff;
    border-radius: 2px;
}

.inquireCode:focus,
.inquireName:focus {
    outline-color: #5b84ff;
}

.inquireName {
    right: 160px;
}

.owl {
    position: fixed;
    z-index: 99;
    top: 100px;
    right: 0px;
    color: #4364c7;
    /* background-color: #032ebc; */
}

.owl .cover {
    width: 100%;
    height: 100%;
    background-color: transparent;
    position: absolute;
    right: 30px;
    bottom: -30px;
    font-size: 22px;
    font-weight: 900;
    -webkit-text-stroke: .3px rgb(255, 255, 255);
}

.owl .part {
    width: 33px;
    height: 33px;
    background-color: white;
    border-radius: 100%;
    position: absolute;
    right: 15px;
    bottom: 19px;
    cursor: pointer;
    font-size: 6px;
    text-align: center;
    line-height: 33px;
    transition: all .1s;
}

.owl .part:hover {
    background-color: #1f46c5;
    color: white;
}

.owl p {
    width: auto;
    height: auto;
    text-align: center;
    position: absolute;
    z-index: 2;
    bottom: 190px;
    left: -45px;
    user-select: none;
    background-color: #476cff;
    color: white;
    padding: 10px;
    border-radius: 5px;
}

.owl p::before {
    content: '';
    width: 30px;
    height: 30px;
    background-color: #476cff;
    position: absolute;
    z-index: -1;
    bottom: -25px;
    right: 55px;
    clip-path: polygon(0 0, 50% 50%, 100% 0);
}

.fade-enter-active {
    animation: fadeAnimate 0.3s ease-in-out;
}

.fade-leave-active {
    animation: fadeAnimate 0.3s ease-in-out reverse;
}

@keyframes fadeAnimate {
    from {
        opacity: 0;
        transform: translateY(-50%);
    }

    to {
        transform: translateY(0%);
        opacity: 1;
    }
}

.modalBox-enter-active {
    animation: modalBox 0.3s ease-in-out;
}

.modalBox-leave-active {
    animation: modalBox 0.3s ease-in-out reverse;
}

@keyframes modalBox {
    0% {
        transform: translateY(-100px) scale(2);
        opacity: 0;
    }

    100% {
        transform: translateY(0px) scale(1);
        opacity: 1;
    }
}

JS:

// 实例化Vue
const vm = new Vue({
    el: '#root',
    data: {
        info: JSON.parse(localStorage.getItem("persistence_user_info")) || [],
        recycleInfo: JSON.parse(localStorage.getItem("recycle_user_info")) || [],
        showOperate: false,
        addCode: '',
        addName: '',
        addSex: '',
        addAge: '',
        inquireCodeValue: '',
        inquireNameValue: '',
        ifOwl: true,
        ifOwlSpeak: true,
        owlSpeak: '可以持久化存储信息哦',
        owlLoadIfSucceed: false,
        owlLoadInfo: 'canvas加载中...',
        ascOrDesc: 'asc',
        // 猫头鹰随机说的句子
        owlRandomSpeak: [
            '可以持久化存储信息哦',
            'JavaScript是最好的语言',
            '没有对象? new一个',
            '本人面向百度、CSDN编程',
            '我以后在给代码加注释',
            '见鬼了,昨天还好好的',
            '启动! Ctrl+C大法',
            '它在我电脑上能运行',
        ],
        showRecycle: false
    },
    methods: {
        add() {
            // 使所有用于增加操作的表单值为空
            this.addCode = this.addName = this.addSex = this.addAge = '';
            this.showOperate = true;
            // 下一次DOM更新结束后执行指定的回调函数
            this.$nextTick(function () {
                this.$refs.addCode.focus();
            });
        },
        affirm() {
            let code = this.addCode;
            let name = this.addName;
            let sex = this.addSex;
            let age = this.addAge;
            // 判断所有用于输入新增用户信息的表单 值是否为空
            if (code == '' || name == '' || sex == '' || age == '') return alert('信息不完整');
            // 判断是否有学号重复
            for (let i = 0; i < this.info.length; i++) {
                if (this.info[i].code == this.addCode) return alert('学号重复!');
            }
            // 新建一个学生对象
            let obj = {
                id: Math.random(),
                code,
                name,
                sex,
                age,
                satisfy: true,
                isEdit: false
            }
            // 把这个学生对象添加到info
            this.info.push(obj);
            this.showOperate = false;
            this.OwlSpeakShow('欢迎新同学:' + name);
        },
        deleteInfo(user) {
            // 添加到回收站
            let obj = {
                id: user.id,
                code: user.code,
                name: user.name,
                sex: user.sex,
                age: user.age,
                satisfy: user.satisfy,
                isEdit: user.isEdit,
                date: +new Date(),
            };
            this.recycleInfo.unshift(obj);
            // 删除一个学生对象
            this.info = this.info.filter(item => item.id != user.id);
            this.OwlSpeakShow(user.name + ' 的信息删除成功');
        },
        edit(user) {
            // 判断是否为编辑状态
            if (user.isEdit) {
                // 非编辑状态
                // 判断当前行的学号是否与其他学号重复
                this.currentCodeIfRepeat(user);
            } else {
                // 编辑状态
                user.isEdit = true;
                // 下一次DOM更新结束后执行指定的回调函数
                this.$nextTick(function () {
                    // 点击编辑后使第一个文本框赋值
                    this.$refs.editFirst.forEach(item => {
                        if (item.value == user.code) return item.focus();
                    });
                });
            }
        },
        // 按学号查询
        inquireCode() {
            let meetsNum = 0;
            let inquireInfo;
            // 判断是查询回收站的表格还是学生信息的表格
            this.showRecycle ? inquireInfo = this.recycleInfo : inquireInfo = this.info;
            inquireInfo.forEach(element => {
                element.code.toString().indexOf(this.inquireCodeValue) != -1 ? element.satisfy = true : element.satisfy = false;
                element.satisfy && meetsNum++;
            });
            this.inquireCodeValue ? this.OwlSpeakShow('有 ' + meetsNum + ' 位同学符合查询条件') : this.OwlSpeakShow('输入后会自动查询');
        },
        // 按姓名查询
        inquireName() {
            this.banSpace();
            let meetsNum = 0;
            let inquireInfo;
            // 判断是查询回收站的表格还是学生信息的表格
            this.showRecycle ? inquireInfo = this.recycleInfo : inquireInfo = this.info;
            inquireInfo.forEach(element => {
                element.name.indexOf(this.inquireNameValue) != -1 ? element.satisfy = true : element.satisfy = false;
                element.satisfy && meetsNum++;
            });
            this.inquireNameValue ? this.OwlSpeakShow('有 ' + meetsNum + ' 位同学符合查询条件') : this.OwlSpeakShow('输入后会自动查询');
        },
        inquireAlone(mark) {
            if (mark == 'code') {
                this.inquireCode();
                this.inquireNameValue = '';
            } else if (mark == 'name') {
                this.inquireName();
                this.inquireCodeValue = '';
            }
        },
        // 禁止输入空格
        banSpace() {
            window.event.target.value = window.event.target.value.replace(/\s+/g, ''); //适用于keyup事件
            if (window.event.keyCode == 32 || window.event.code == 'Space' || window.event.key == ' ') return window.event.returnValue = false; //适用于keydown事件
        },
        // 判断所有学号是否重复,并把重复学号所在的行设为编辑状态
        allCodeIfRepeat() {
            let flag = false;
            for (let i = 0; i < this.info.length; i++) {
                let frequency = 0;
                let element = this.info[i];
                for (let j = 0; j < this.info.length; j++) {
                    let elements = this.info[j];
                    if (element.code == elements.code) {
                        frequency++;
                        if (frequency > 1) {
                            element.isEdit = true;
                            flag = true;
                        }
                    }
                }
            }
            flag && alert('学号重复!');
            return flag;
        },
        // 判断当前行的学号是否与其他学号重复
        currentCodeIfRepeat(user) {
            let frequency = 0;
            for (let i = 0; i < this.info.length; i++) {
                if (this.info[i].code == user.code) {
                    frequency++;
                    if (frequency > 1) {
                        alert('学号重复!');
                        return true;
                    }
                }
            }
            user.isEdit = false;
            return false;
        },
        OwlSpeakShow(speak) {
            this.ifOwlSpeak = true;
            this.owlSpeak = speak;
        },
        OwlSpeakHide() {
            this.ifOwlSpeak = false;
        },
        // 学生信息表格排序
        variousSort(mark) {
            // 根据学号排序
            if (mark == 'code') {
                this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.code - b.code) : this.info.sort((a, b) => b.code - a.code);
            }
            // 根据姓名排序
            else if (mark == 'name') {
                this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.name.localeCompare(b.name)) : this.info.sort((a, b) => b.name.localeCompare(a.name));
            }
            // 根据性别排序
            else if (mark == 'sex') {
                this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.sex.localeCompare(b.sex)) : this.info.sort((a, b) => b.sex.localeCompare(a.sex));
            }
            // 根据年龄排序
            else if (mark == 'age') {
                this.ascOrDesc == 'asc' ? this.info.sort((a, b) => a.age - b.age) : this.info.sort((a, b) => b.age - a.age);
            }
            this.ascOrDesc == 'asc' ? this.ascOrDesc = 'desc' : this.ascOrDesc = 'asc';
        },
        // 回收站表格排序
        recycleVariousSort(mark) {
            if (mark == 'code') {
                this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.code - b.code) : this.recycleInfo.sort((a, b) => b.code - a.code);
            }
            // 根据姓名排序
            else if (mark == 'name') {
                this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.name.localeCompare(b.name)) : this.recycleInfo.sort((a, b) => b.name.localeCompare(a.name));
            }
            // 根据日期排序
            else if (mark == 'date') {
                this.ascOrDesc == 'asc' ? this.recycleInfo.sort((a, b) => a.date - b.date) : this.recycleInfo.sort((a, b) => b.date - a.date);
            }
            this.ascOrDesc == 'asc' ? this.ascOrDesc = 'desc' : this.ascOrDesc = 'asc';
        },
        // 对于iframe加载成功的处理
        owlLoad() {
            this.owlLoadIfSucceed = true;
            this.owlLoadInfo = '隐藏';
        },
        // 在回收站彻底删除
        thoroughDeleteInfo(user) {
            // 彻底删除一个学生对象
            this.recycleInfo = this.recycleInfo.filter(item => item.id != user.id);
        },
        // 在回收站还原一个学生
        reductionInfo(user) {
            let repeat = false;
            for (let i = 0; i < this.info.length; i++) {
                if (this.info[i].code == user.code) {
                    alert('学号重复!');
                    repeat = true;
                    this.info[i].isEdit = repeat;
                    user.isEdit = repeat;
                } 
            }
            // 添加到学生信息表
            let obj = {
                id: user.id,
                code: user.code,
                name: user.name,
                sex: user.sex,
                age: user.age,
                satisfy: user.satisfy,
                isEdit: repeat
            };
            this.info.unshift(obj);
            this.thoroughDeleteInfo(user);
        },
        allEmpty() {
            this.recycleInfo = [];
        }
    },
    filters: {
        timeformater(value, str = 'YYYY年MM月DD日 HH:mm:ss') {
            return dayjs(value).format(str);
        },
    },
    watch: {
        // 深度监视info
        info: {
            deep: true,
            handler(value) {
                localStorage.setItem("persistence_user_info", JSON.stringify(value));
            },
        },
        // 深度监视recycleInfo
        recycleInfo: {
            deep: true,
            handler(value) {
                localStorage.setItem("recycle_user_info", JSON.stringify(value));
            },
        },
    },
    created() {
        // 恢复各个属性的默认值(防止刷新网页后还处于编辑、查询等状态)
        this.info.forEach(element => {
            element.isEdit = false;
            element.satisfy = true;
        });
        // 对于(在编辑状态并且有学号重复的情况下刷新网页)的措施
        // 判断所有学号是否重复,并把重复学号所在的行设为编辑状态
        this.allCodeIfRepeat();
        // 让猫头鹰随机说话
        setInterval(() => {
            !this.ifOwlSpeak && this.OwlSpeakShow(this.owlRandomSpeak[Math.floor(Math.random() * this.owlRandomSpeak.length)]);
        }, 6000);
    }
});

记得引入vue哦

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值