C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。

 

 


文章目录

前言

二、头文件

三、主界面

四、通讯录功能函数

1.全代码

2.增加联系人

3.删除联系人

4.查找联系人

5.修改联系人

6.展示联系人

7.清空联系人

8.退出通讯录

总结


前言

为了使用通讯录时,可以随时调整大小,所以使用动态开辟内存函数写通讯录,可增加联系人容量。

动态开辟函数,即在内存的栈区开辟空间,所以使用完毕后,需要释放内存空间


一、通讯录运行图

二、头文件

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<stdlib.h>

#define Max 10


enum function
{
    quit,//退出  默认值为0
    increase,//增加  默认值为1
    delete,//删除  默认值为2
    find,//查找   默认值为3
    revise,//修改   默认值为4
    show,//展示   默认值为5
    empty,//清空   默认值为6
    sort//排序   默认值为7
};

//创建人
typedef struct Person
{
    char name[20];//姓名
    size_t age;//年龄
    char sex[8];//性别
    char address[15];//地址
    char phone[12];//电话
}person;

//动态
//创建通讯录
typedef struct contact
{
    person *per;//指向人这个结构体类型
    size_t sz;//通讯录已有人员个数
    size_t ContactMax;//通讯录当前最大容量
}contact;

//初始化
void init_contact(contact* con);
//增容
void tune(contact* con);
//增加
void increase_contact(contact* con);
//删除
void delete_contact(contact* con);
//查找
//return -1(no) / address(yes)
int find1(const contact** con);
void find_contact(const contact* con);
//修改
void revise_contact(contact* con);
//展示
void show_contact(const contact* con);
//排序通讯录
void sort_contact(contact* con);
//销毁通讯录
void destroy_contact(contact* con);
//保存文件
void save_contact(contact* con);
//将文件信息保存到通讯录中
void load_contact(contact* con);

三、主界面

#include "contact.h"

void menu1()
{
    printf("**************************************\n");
    printf("******* Simplified address book ******\n");
    printf("*******   1> increase contact   ******\n");
    printf("*******   2> delete contact     ******\n");
    printf("*******   3> find contact       ******\n");
    printf("*******   4> revise contact     ******\n");
    printf("*******   5> Show all contacts  ******\n");
    printf("*******   6> Empty all contacts ******\n");
    printf("*******   7> Sort by name       ******\n");
    printf("*******   0> Quit Contacts      ******\n");
    printf("**************************************\n");
}

void test()
{
    //创建通讯录
    contact con;
    //初始化通讯录
    init_contact(&con);
    //将文件信息保存到通讯录中
    load_contact(&con);

    size_t choice = 0;
    do
    {
        menu1();
        printf("请输入您的选择性:");
        scanf("%u", &choice);

        switch (choice)
        {
        case increase:
            //增加
            increase_contact(&con);
            break;
        case delete:
            //删除
            delete_contact( &con );
            break;
        case find:
            //查找
            find_contact(&con);
            break;
        case revise:
            //修改
            revise_contact(&con);
            break;
        case show:
            //展示
            show_contact(&con);
            break;
        case empty:
            //清空
            init_contact(&con);
            break;
        case sort:
            //排序
            sort_contact(&con);
            break;
        case quit:
            //保存
            save_contact(&con);
            //销毁
            destroy_contact(&con);
            printf("Exiting Contacts...\n");
            break;
        default:
            printf("You entered the wrong number, please re-enter it.\n");
            break;
        }
    } while (choice);

    printf("Exited Contacts.\n");

}

int main()
{
    test();
    return 0;
}

四、通讯录功能函数

1.全代码

#include"contact.h"

void menu2()
{
    system("cls");

    printf("1> name \t 2> age\n");
    printf("3> sex \t 4> address\n");
    printf("5> phone\n");
    printf("Please select:");
}

//动态
void init_contact(contact* con)
{
    assert(con);

    // per    sz ContactMax
    con->sz = 0;

    person* p = (person*)calloc(Max, sizeof(person));
    if (p == NULL)
    {
        perror("init_contact::calloc");
        return;
    }

    con->per = p;
    con->ContactMax = Max;
}

//将文件信息保存到通讯录中
void load_contact(contact* con)
{
   //打开文件
    FILE* p = fopen("contact.txt", "rb");
    if (p == NULL)
    {
        perror("load_contact::fopen");
        return;
    }

    person tmp = { 0 };
    size_t i = 0;
    while(fread(&tmp, sizeof(person), 1, p))
    {
        //考虑增容
        tune(con);
        con->per[i] = tmp;
        con->sz++;
        i++;
    }
    //关闭文件
    fclose(p);
    p = NULL;
}


void tune(contact* con)
{
    if (con->sz == con->ContactMax)
    {
        person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));
        if (p == NULL)
        {
            perror("tune::realloc");
            return;
        }

        con->per = p;
        con->ContactMax += Max;
    }
}

//动态开辟
void increase_contact(contact* con)
{
    assert(con);
    //检测当前通讯录是否需要增容
    tune(con);

    printf("name:");
    scanf("%s", &(con->per[con->sz].name));
    printf("age:");
    scanf("%u", &(con->per[con->sz].age));
    printf("sex:");
    scanf("%s", &(con->per[con->sz].sex));
    printf("address:");
    scanf("%s", &(con->per[con->sz].address));
    printf("phone:");
    scanf("%s", &(con->per[con->sz].phone));

    (con->sz)++;
}

void delete_contact(contact* con)
{
    assert(con);

    int result = find1(&con);
            
    if (result != -1)
    {
        char true[5] = { 0 };
        printf("Are you sure you want to delete %s's information?", &con->per[result].name);
        printf("yes/no:");
        scanf("%s", true);

        if (!strcmp(true, "yes"))
        {
            if ( con->sz )
            {
                memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));
            }
            else
            {
                memset(con->per[result].name, 0, sizeof(con->per[0]));
            }
            (con->sz)--;
            printf("The deletion was successful, thanks for using!\n");          
        }
        else
        {
            printf("Delete failed, please try again!\n");
        }
    }
    else
    {
        printf("Delete failed, please try again!\n");
    }
}

int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void find_contact(const contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        printf("Found, the basic information of the contact is:");
        printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",
            con->per[result].name,
            con->per[result].age,
            con->per[result].sex,
            con->per[result].address,
            con->per[result].phone);
    }
    else
    {
        printf("Didn't find it!\n");
    }

}

void revise_contact(contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        char choice1[5] = { 0 };
        printf("Are you sure you want to revise %s's information?", con->per[result].name);
        printf("yes/no:");
        scanf("%s", choice1);

        if (!strcmp(choice1, "yes"))
        {
            menu2();
            printf("Please enter the option you want to modify:");
            int choice2 = -1;
            scanf("%d", &choice2);

            char sample1[30] = { 0 };
            size_t sample2 = 0;

            printf("请输入:");
            switch ( choice2 )
            {
            case 1:
            case 3:
            case 4:
            case 5:
                scanf("%s", sample1);
                break;
            case 2:
                scanf("%d", sample2);
                break;
            }

            switch (choice2)
            {
            case 1:
                memmove(con->per[result].name, sample1, sizeof(sample1));
                break;
            case 3:
                memmove(con->per[result].sex, sample1, sizeof(sample1));
                break;
            case 4:
                memmove(con->per[result].address, sample1, sizeof(sample1));
                break;
            case 5:
                memmove(con->per[result].phone, sample1, sizeof(sample1));
                break;
            case 2:
                con->per[result].age = sample2;
                break;
            }

            printf("修改成功,感谢使用!!!\n");
        }
        else
        {
            printf("修改失败,请再次尝试!!!\n");
        }
    }
    else
    {
        printf("修改失败,请再次尝试!!!\n");
    }
}

void show_contact(const contact* con)
{
    assert(con);

    printf("\n\n================================================\n");
    printf("================================================\n\n");

    if ( con->sz )
    {
        size_t i = 0;
        for (; i < (con->sz); i++)
        {
            printf("name:%-20s\tage:%-4d\tsex:%-8s\taddress:%-15s\tphone:%-12s\n",
                con->per[i].name, con->per[i].age, con->per[i].sex,
                con->per[i].address, con->per[i].phone);
        }
        printf("\n\n");
    }
    else
    {
        printf("There is no contact information in the address book!\n");
    }
}

int cmp_char(const void* str1, const void* str2)
{
    return strcmp(((person*)str1)->name, ((person*)str2)->name);
}

void sort_contact(contact* con)
{
    qsort(con -> per[0].name, con -> sz, sizeof(con -> per[0]), cmp_char);
}

void destroy_contact(contact* con)
{
    free(con->per);
    con->per = NULL;
    con->ContactMax = 0;
    con->sz = 0;
    con = NULL;
}

void save_contact(contact* con)
{
    //写文件
    FILE* p = fopen("contact.txt", "wb");
    if (p == NULL)
    {
        perror("save_contact::fopen");
        return;
    }

    int i = 0;
    for (i = 0; i < con->sz; i++)
    {
        fwrite(con->per + i, sizeof(person), 1, p);
    }
    //关闭文件
    fclose(p);
    p = NULL;
    printf("保存成功\n");
}

2.增加联系人

使用realloc()调整通讯录大小。

联系人信息图为:

void tune(contact* con)
{
    if (con->sz == con->ContactMax)
    {
        person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));
        if (p == NULL)
        {
            perror("tune::realloc");
            return;
        }

        con->per = p;
        con->ContactMax += Max;
    }
}

//动态开辟
void increase_contact(contact* con)
{
    assert(con);
    //检测当前通讯录是否需要增容
    tune(con);

    printf("name:");
    scanf("%s", &(con->per[con->sz].name));
    printf("age:");
    scanf("%u", &(con->per[con->sz].age));
    printf("sex:");
    scanf("%s", &(con->per[con->sz].sex));
    printf("address:");
    scanf("%s", &(con->per[con->sz].address));
    printf("phone:");
    scanf("%s", &(con->per[con->sz].phone));

    (con->sz)++;
}

3.删除联系人

通过联系人的姓名来查找需要删除的联系人,找到之后确认删除该联系人。

例如:

 

int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}


void delete_contact(contact* con)
{
    assert(con);

    int result = find1(&con);
            
    if (result != -1)
    {
        char true[5] = { 0 };
        printf("Are you sure you want to delete %s's information?", &con->per[result].name);
        printf("yes/no:");
        scanf("%s", true);

        if (!strcmp(true, "yes"))
        {
            if ( con->sz )
            {
                memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));
            }
            else
            {
                memset(con->per[result].name, 0, sizeof(con->per[0]));
            }
            (con->sz)--;
            printf("The deletion was successful, thanks for using!\n");          
        }
        else
        {
            printf("Delete failed, please try again!\n");
        }
    }
    else
    {
        printf("Delete failed, please try again!\n");
    }
}

4.查找联系人

通过联系人姓名查找联系人。


int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void find_contact(const contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        printf("Found, the basic information of the contact is:");
        printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",
            con->per[result].name,
            con->per[result].age,
            con->per[result].sex,
            con->per[result].address,
            con->per[result].phone);
    }
    else
    {
        printf("Didn't find it!\n");
    }

}

5.修改联系人

先查找,再修改。

可以修改联系人的任一信息。


int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void revise_contact(contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        char choice1[5] = { 0 };
        printf("Are you sure you want to revise %s's information?", con->per[result].name);
        printf("yes/no:");
        scanf("%s", choice1);

        if (!strcmp(choice1, "yes"))
        {
            menu2();
            printf("Please enter the option you want to modify:");
            int choice2 = -1;
            scanf("%d", &choice2);

            char sample1[30] = { 0 };
            size_t sample2 = 0;

            printf("请输入:");
            switch ( choice2 )
            {
            case 1:
            case 3:
            case 4:
            case 5:
                scanf("%s", sample1);
                break;
            case 2:
                scanf("%d", sample2);
                break;
            }

            switch (choice2)
            {
            case 1:
                memmove(con->per[result].name, sample1, sizeof(sample1));
                break;
            case 3:
                memmove(con->per[result].sex, sample1, sizeof(sample1));
                break;
            case 4:
                memmove(con->per[result].address, sample1, sizeof(sample1));
                break;
            case 5:
                memmove(con->per[result].phone, sample1, sizeof(sample1));
                break;
            case 2:
                con->per[result].age = sample2;
                break;
            }

            printf("修改成功,感谢使用!!!\n");
        }
        else
        {
            printf("修改失败,请再次尝试!!!\n");
        }
    }
    else
    {
        printf("修改失败,请再次尝试!!!\n");
    }
}

6.展示联系人

展示所有联系人及其所有信息。

void show_contact(const contact* con)
{
    assert(con);

    printf("\n\n================================================\n");
    printf("================================================\n\n");

    if ( con->sz )
    {
        size_t i = 0;
        for (; i < (con->sz); i++)
        {
            printf("name:%-20s\tage:%-4d\tsex:%-8s\taddress:%-15s\tphone:%-12s\n",
                con->per[i].name, con->per[i].age, con->per[i].sex,
                con->per[i].address, con->per[i].phone);
        }
        printf("\n\n");
    }
    else
    {
        printf("There is no contact information in the address book!\n");
    }
}

7.清空联系人

又名初始化通讯录。

重新向内存申请一片空间,存储联系人信息。

void init_contact(contact* con)
{
    assert(con);

    // per    sz ContactMax
    con->sz = 0;

    person* p = (person*)calloc(Max, sizeof(person));
    if (p == NULL)
    {
        perror("init_contact::calloc");
        return;
    }

    con->per = p;
    con->ContactMax = Max;
}

8.退出通讯录

通过free()释放内存栈区的空间,避免内存泄露。

void destroy_contact(contact* con)
{
    free(con->per);
    con->per = NULL;
    con->ContactMax = 0;
    con->sz = 0;
    con = NULL;
}

总结

在使用完内存函数之后,一定一定要记得释放空间哦~

上述代码展示就是整个动态通讯录的全部啦,如果你有兴趣想要了解,可以通过C_Ccpp/C_study/contact at main · Yjun6/C_Ccpp (github.com)找到它们。

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

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

相关文章

Opencv项目实战:22 物体颜色识别并框选

目录 0、项目介绍 1、效果展示 2、项目搭建 3、项目代码展示与部分讲解 Color_trackbar.py bgr_detector.py test.py 4、项目资源 5、项目总结 0、项目介绍 本次项目要完成的是对物体颜色的识别并框选&#xff0c;有如下功能&#xff1a; &#xff08;1&#xff09;…

线程池的使用:如何写出高效的多线程程序?

目录1.线程池的使用2.编写高效的多线程程序Java提供了Executor框架来支持线程池的实现&#xff0c;通过Executor框架&#xff0c;可以快速地创建和管理线程池&#xff0c;从而更加方便地编写多线程程序。 1.线程池的使用 在使用线程池时&#xff0c;需要注意以下几点&#xff…

GDAL python教程基础篇(7)OGR空间计算

1.空间计算 地理数据处理&#xff08;geoprocessing&#xff09;计算函数&#xff1a; 多边形&#xff08;Polygon&#xff09;&#xff1a; 1、交&#xff1a;poly3.Intersection(poly2) 2、并&#xff1a;poly3.Union(poly2) 3、差&#xff1a;poly3.Difference(poly2) 4、补…

python打包成apk界面设计,python打包成安装文件

大家好&#xff0c;给大家分享一下如何将python程序打包成apk文件&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 1、如何用python制作十分秒加减的apk 如何用python制作十分秒加减的apk&#xff1f;用法:. apk包放入apk文件目录,然后输入…

Linux基础命令大全(下)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…

走进哈希心房

目录 哈希的概念 哈希函数 哈希冲突和解决方法 闭散列 插入 查找 删除 开散列 插入 查找 删除 哈希表&#xff08;开散列&#xff09;整体代码 位图 位图模拟实现思路分析&#xff1a; 位图应用 布隆过滤器 本文介绍unordered系列的关联式容器&#xff0c;unor…

安卓手机也可以使用新必应NewBing

没有魔法安卓手机也可以使用新必应NewBing 目前知道的是安卓手机 安卓手机先安装一个猴狐浏览器 打开手机自带浏览器&#xff0c;搜索关键词&#xff1a;猴狐浏览器&#xff0c;找到官网 也可以直接复制这个网址 狐猴浏览器 lemurbrowser CoolAPK 我的手机是荣耀安卓手机…

【正点原子FPGA连载】 第三十三章基于lwip的tftp server实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

第三十三章基于lwip的tftp server实验 文件传输是网络环境中的一项基本应用&#xff0c;其作用是将一台电子设备中的文件传输到另一台可能相距很远的电子设备中。TFTP作为TCP/IP协议族中的一个用来在客户机与服务器之间进行文件传输的协议&#xff0c;常用于无盘工作站、路由器…

「ML 实践篇」分类系统:图片数字识别

目的&#xff1a;使用 MNIST 数据集&#xff0c;建立数字图像识别模型&#xff0c;识别任意图像中的数字&#xff1b; 文章目录1. 数据准备&#xff08;MNIST&#xff09;2. 二元分类器&#xff08;SGD&#xff09;3. 性能测试1. 交叉验证2. 混淆矩阵3. 查准率与查全率4. P-R 曲…

2023年腾讯云服务器配置价格表(轻量服务器、CVM云服务器、GPU云服务器)

目前腾讯云服务器分为轻量应用服务器、云服务器云服务器云服务器CVM和GPU云服务器&#xff0c;首先介绍一下这三种服务。 1、腾讯云云服务器&#xff08;Cloud Virtual Machine&#xff0c;CVM&#xff09;提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源&#xff…

【经验总结】10年的嵌入式开发老手,到底是如何快速学习和使用RT-Thread的?(文末赠书5本)

【经验总结】一位近10年的嵌入式开发老手&#xff0c;到底是如何快速学习和使用RT-Thread的&#xff1f; RT-Thread绝对可以称得上国内优秀且排名靠前的操作系统&#xff0c;在嵌入式IoT领域一直享有盛名。近些年&#xff0c;物联网产业的大热&#xff0c;更是直接将RT-Thread这…

python绘制图像中心坐标二维分布曲线

数据和代码如下所示&#xff1a; import pandas as pd import numpy as np import matplotlib.pyplot as plt import xlrd from scipy.stats import multivariate_normal from mpl_toolkits.mplot3d import Axes3D np.set_printoptions(suppressTrue)# 根据均值、标准差,求指定…

SuperMap iMobile for Android 地图开发(一)

第一步&#xff1a;创建 Android Studio 项目 第一步&#xff1a;创建 Android Studio 项目 Android Studio 有两种创建项目的方法。 第一种是在 Android Studio起始页选择“Start a new Android Studio Project”。 第二种是在 Android Studio 主页选择“File”–>“New P…

数仓建模—主题域和主题

主题域和主题 前面在这个专题的第一篇,也就是数仓建模—数仓初识中我们就提到了一个概念—主题,这个概念其实在数仓的定义中也有提到 数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。 今天我们主要来探究一下,数仓的主题到底是…

Multi-Camera Color Correction via Hybrid Histogram Matching直方图映射

文章目录Multi-Camera Color Correction via Hybrid Histogram Matching1. 计算直方图&#xff0c; 累计直方图&#xff0c; 直方图均衡化2. 直方图规定化&#xff0c;直方图映射。3. 实验环节3.1 输入图像3.2 均衡化效果3.3 映射效果4. 针对3实验环节的伪影 做处理和优化&…

ChatGPT研究分析:GPT-4做了什么

前脚刚研究了一轮GPT3.5&#xff0c;OpenAI很快就升级了GPT-4&#xff0c;整体表现有进一步提升。追赶一下潮流&#xff0c;研究研究GPT-4干了啥。本文内容全部源于对OpenAI公开的技术报告的解读&#xff0c;通篇以PR效果为主&#xff0c;实际内容不多。主要强调的工作&#xf…

九种跨域方式实现原理(完整版)

前言 前后端数据交互经常会碰到请求跨域&#xff0c;什么是跨域&#xff0c;以及有哪几种跨域方式&#xff0c;这是本文要探讨的内容。 一、什么是跨域&#xff1f; 1.什么是同源策略及其限制内容&#xff1f; 同源策略是一种约定&#xff0c;它是浏览器最核心也最基本的安…

如何发布自己的npm包

一、什么是npm npm是随同nodejs一起安装的javascript包管理工具&#xff0c;能解决nodejs代码部署上的很多问题&#xff0c;常见的使用场景有以下几种&#xff1a; ①.允许用户从npm服务器下载别人编写的第三方包到本地使用。 ②.允许用户从npm服务器下载并安装别人编写的命令…

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCMQ2传感参模块1.2、STM32F103C8T6MQ2传感参模块五、基础知识学习与相关…

Vue3之插槽(Slot)

何为插槽 我们都知道在父子组件间可以通过v-bind,v-model搭配props 的方式传递值&#xff0c;但是我们传递的值都是以一些数字&#xff0c;字符串为主&#xff0c;但是假如我们要传递一个div或者其他的dom元素甚至是组件&#xff0c;那v-bind和v-model搭配props的方式就行不通…
最新文章