前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【wiki知识库】05.分类管理实现--前端Vue模块

【wiki知识库】05.分类管理实现--前端Vue模块

作者头像
哈__
发布于 2024-06-06 00:29:07
发布于 2024-06-06 00:29:07
12400
代码可运行
举报
文章被收录于专栏:哈哈熊哈哈熊
运行总次数:0
代码可运行

一、🔥今日目标

【wiki知识库】04.SpringBoot后端实现电子书的增删改查以及前端界面的展示-CSDN博客 上回带大家把电子书管理的模块做了出来,能够实现电子书的添加、修改和删除功能了,今天带着大家把分类的接口实现一下。下方我添加了一个分类管理的组件,展示我们当前的所有分类,你可以看到这个分类页面还是一个树形结构的。

除了分类管理,我们的首页也变动了一下。首页的导航栏加载的是我们已经有的分类,同时还加上了一个欢迎页面。

二、🌏前端部分的改造

2.1 新增一个tool.ts

在util包下建立一个tool.ts文件,这个文件是我们的工具文件,之前的代码可能也用到过了,我忘记给大家了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export class Tool {
    /**
     * 空校验 null或""都返回true
     */
    public static isEmpty(obj: any) {
        if ((typeof obj === 'string')) {
            return !obj || obj.replace(/\s+/g, "") === ""
        } else {
            return (!obj || JSON.stringify(obj) === "{}" || obj.length === 0);
        }
    }

    /**
     * 非空校验
     */
    public static isNotEmpty(obj: any) {
        return !this.isEmpty(obj);
    }

    /**
     * 对象复制
     * @param obj
     */
    public static copy(obj: object) {
        if (Tool.isNotEmpty(obj)) {
            return JSON.parse(JSON.stringify(obj));
        }
    }

    /**
     * 使用递归将数组转为树形结构
     * 父ID属性为parent
     */
    public static array2Tree(array: any, parentId: number) {
        if (Tool.isEmpty(array)) {
            return [];
        }

        const result = [];
        for (let i = 0; i < array.length; i++) {
            const c = array[i];
            // console.log(Number(c.parent), Number(parentId));
            if (Number(c.parent) === Number(parentId)) {
                result.push(c);

                // 递归查看当前节点对应的子节点
                const children = Tool.array2Tree(array, c.id);
                if (Tool.isNotEmpty(children)) {
                    c.children = children;
                }
            }
        }
        return result;
    }

    /**
     * 随机生成[len]长度的[radix]进制数
     * @param len
     * @param radix 默认62
     * @returns {string}
     */
    public static uuid(len: number, radix = 62) {
        const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        const uuid = [];
        radix = radix || chars.length;

        for (let i = 0; i < len; i++) {
            uuid[i] = chars[0 | Math.random() * radix];
        }

        return uuid.join('');
    }
}

2.2 新增admin-categoty.vue

在admin包下,创建admin-category.vue,这个组件用来展示我们的分类信息。这一部分我带着大家稍微过一下。


分类添加功能:

在我们点击添加或者编辑功能的时候,会把下边的代码以一个窗口的模式弹出,在这个窗口中展示了当前分类的名称,当前分类的父分类是谁以及当前分类的分类序号。在我们为一个分类进行添加或者修改的时候,我们都要涉及到这个分类到底是第一分类还是第二分类的问题,我们使用了一个level1变量来保存我们的分类结构,这个结构下边在讲。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<a-modal
    title="分类表单"
    v-model:visible="modalVisible"
    :confirm-loading="modalLoading"
    @ok="handleModalOk"
  >
    <a-form :model="category" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
      <a-form-item label="名称">
        <a-input v-model:value="category.name" />
      </a-form-item>
      <a-form-item label="父分类">
        <a-select
          v-model:value="category.parent"
          ref="select"
        >
          <a-select-option :value="0"></a-select-option>
          <a-select-option v-for="c in level1" :key="c.id" :value="c.id" :disabled="category.id === c.id">
            {{c.name}}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="顺序">
        <a-input v-model:value="category.sort" />
      </a-form-item>
    </a-form>
  </a-modal>

我们的分类结构可以用一张图来表示。 我给每一个分类都排上了一个编号,第一级分类的parent编号都为0,二级分类的parent编号则要相对应其父分类的编号。


level变量的封装过程:

我们的level变量是和我们全部的分类变量有关的,我们先要获取所有的分类然后对分类进行重新组合。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const handleQuery = () => {
        loading.value = true;
        // 如果不清空现有数据,则编辑保存重新加载数据后,再点编辑,则列表显示的还是编辑前的数据
        level1.value = [];
        axios.get("/category/all").then((response) => {
          loading.value = false;
          const data = response.data;
          if (data.success) {
            categorys.value = data.content;
            console.log("原始数组:", categorys.value);

            level1.value = [];
            level1.value = Tool.array2Tree(categorys.value, 0);
            console.log("树形结构:", level1);
          } else {
            message.error(data.message);
          }
        });
      };

这时候打开我们的tool.ts来看一看。你会看到一共有两个参数,第一个参数呢我们传的是一个数据数组,第二个我们传来的是0。

首先我们判断一下传过来的数组是不是空的,如果是空的直接返回,否则的话执行下方逻辑。

首先遍历我们所有的分类,检查每一个分类的父分类的编号是不是我们传过来的0,这里你应该会理解为什么这样做,因为我们要把一个数据数据重新格式化成树的形式,那我们一定要先找到这棵树的一级分类,也就是父节点编号为0的分类,找到了之后呢我们把这个分类加到result当中。然后呢我们再次调用array2Tree这个方法,同时传入两个参数,第一个参数还是之前的全部分类的数组,但是第二个参数就不是0了,是我们刚才加入到result中的分类的编号,我们这次调用这个方法的目的是为了找到一级分类的子分类:二级分类。

这样的一次递归调用就可以将数据进行树化。(不懂私信我)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 /**
     * 使用递归将数组转为树形结构
     * 父ID属性为parent
     */
    public static array2Tree(array: any, parentId: number) {
        if (Tool.isEmpty(array)) {
            return [];
        }

        const result = [];
        for (let i = 0; i < array.length; i++) {
            const c = array[i];
            // console.log(Number(c.parent), Number(parentId));
            if (Number(c.parent) === Number(parentId)) {
                result.push(c);

                // 递归查看当前节点对应的子节点
                const children = Tool.array2Tree(array, c.id);
                if (Tool.isNotEmpty(children)) {
                    c.children = children;
                }
            }
        }
        return result;
    }

全部代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <a-layout>
    <a-layout-content
      :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
    >
      <p>
        <a-form layout="inline" :model="param">
          <a-form-item>
            <a-input v-model:value="param.name" placeholder="名称">
            </a-input>
          </a-form-item>
          <a-form-item>
            <a-button type="primary" @click="handleQuery()">
              查询
            </a-button>
          </a-form-item>
          <a-form-item>
            <a-button type="primary" @click="add()">
              新增
            </a-button>
          </a-form-item>
        </a-form>
      </p>
      <p>
        <a-alert
                class="tip"
                message="小提示:这里的分类会显示到首页的侧边菜单"
                type="info"
                closable
        />
      </p>
      <a-table
        v-if="level1.length > 0"
        :columns="columns"
        :row-key="record => record.id"
        :data-source="level1"
        :loading="loading"
        :pagination="false"
        :defaultExpandAllRows="true"
      >
        <template #cover="{ text: cover }">
          <img v-if="cover" :src="cover" alt="avatar" />
        </template>
        <template v-slot:action="{ text, record }">
          <a-space size="small">
            <a-button type="primary" @click="edit(record)">
              编辑
            </a-button>
            <a-popconfirm
              title="删除后不可恢复,确认删除?"
              ok-text="是"
              cancel-text="否"
              @confirm="handleDelete(record.id)"
            >
              <a-button type="danger">
                删除
              </a-button>
            </a-popconfirm>
          </a-space>
        </template>
      </a-table>
    </a-layout-content>
  </a-layout>

  <a-modal
    title="分类表单"
    v-model:visible="modalVisible"
    :confirm-loading="modalLoading"
    @ok="handleModalOk"
  >
    <a-form :model="category" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
      <a-form-item label="名称">
        <a-input v-model:value="category.name" />
      </a-form-item>
      <a-form-item label="父分类">
        <a-select
          v-model:value="category.parent"
          ref="select"
        >
          <a-select-option :value="0"></a-select-option>
          <a-select-option v-for="c in level1" :key="c.id" :value="c.id" :disabled="category.id === c.id">
            {{c.name}}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="顺序">
        <a-input v-model:value="category.sort" />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts">
  import { defineComponent, onMounted, ref } from 'vue';
  import axios from 'axios';
  import { message } from 'ant-design-vue';
  import {Tool} from "@/util/tool";

  export default defineComponent({
    name: 'AdminCategory',
    setup() {
      const param = ref();
      param.value = {};
      const categorys = ref();
      const loading = ref(false);

      const columns = [
        {
          title: '名称',
          dataIndex: 'name'
        },
        // {
        //   title: '父分类',
        //   key: 'parent',
        //   dataIndex: 'parent'
        // },
        {
          title: '顺序',
          dataIndex: 'sort'
        },
        {
          title: 'Action',
          key: 'action',
          slots: { customRender: 'action' }
        }
      ];

      /**
       * 一级分类树,children属性就是二级分类
       * [{
       *   id: "",
       *   name: "",
       *   children: [{
       *     id: "",
       *     name: "",
       *   }]
       * }]
       */
      const level1 = ref(); // 一级分类树,children属性就是二级分类
      level1.value = [];

      /**
       * 数据查询
       **/
      const handleQuery = () => {
        loading.value = true;
        // 如果不清空现有数据,则编辑保存重新加载数据后,再点编辑,则列表显示的还是编辑前的数据
        level1.value = [];
        axios.get("/category/all").then((response) => {
          loading.value = false;
          const data = response.data;
          if (data.success) {
            categorys.value = data.content;
            console.log("原始数组:", categorys.value);

            level1.value = [];
            level1.value = Tool.array2Tree(categorys.value, 0);
            console.log("树形结构:", level1);
          } else {
            message.error(data.message);
          }
        });
      };

      // -------- 表单 ---------
      const category = ref({});
      const modalVisible = ref(false);
      const modalLoading = ref(false);
      const handleModalOk = () => {
        modalLoading.value = true;
        axios.post("/category/save", category.value).then((response) => {
          modalLoading.value = false;
          const data = response.data; // data = commonResp
          if (data.success) {
            modalVisible.value = false;

            // 重新加载列表
            handleQuery();
          } else {
            message.error(data.message);
          }
        });
      };

      /**
       * 编辑
       */
      const edit = (record: any) => {
        modalVisible.value = true;
        category.value = Tool.copy(record);
      };

      /**
       * 新增
       */
      const add = () => {
        modalVisible.value = true;
        category.value = {};
      };

      const handleDelete = (id: number) => {
        axios.delete("/category/delete/" + id).then((response) => {
          const data = response.data; // data = commonResp
          if (data.success) {
            // 重新加载列表
            handleQuery();
          } else {
            message.error(data.message);
          }
        });
      };

      onMounted(() => {
        handleQuery();
      });

      return {
        param,
        // categorys,
        level1,
        columns,
        loading,
        handleQuery,

        edit,
        add,

        category,
        modalVisible,
        modalLoading,
        handleModalOk,

        handleDelete
      }
    }
  });
</script>

<style scoped>
  img {
    width: 50px;
    height: 50px;
  }
</style>

2.3 添加新的路由规则

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  {
    path: '/admin/category',
    name: 'AdminCateGory',
    component: AdminCategory
  },

2.4 添加the-welcome.vue

在component文件夹下边 添加the-welcome.vue页面。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <span>欢迎</span>

</template>

<script lang="ts">
    name: 'the-welcome'
</script>
<style scoped>

</style>

2.5 修改HomeView.vue

这里做出了一些修改,一个是the-welcome组件的展示,还有一个就是页面侧边栏的展示,我们之前展示的是页面默认的,现在我们要展示数据库当中的分类结构。里边我们有一些代码还用不到,但是我没有注释掉。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <a-layout>
    <a-layout-sider width="200" style="background: #fff">
      <a-menu
        mode="inline"
        :style="{ height: '100%', borderRight: 0 }"
        @click="handleClick"
        :openKeys="openKeys"
      >
        <a-menu-item key="welcome">
          <MailOutlined />
          <span>欢迎</span>
        </a-menu-item>
        <a-sub-menu v-for="item in level1" :key="item.id" :disabled="true">
          <template v-slot:title>
            <span><user-outlined />{{item.name}}</span>
          </template>
          <a-menu-item v-for="child in item.children" :key="child.id">
            <MailOutlined /><span>{{child.name}}</span>
          </a-menu-item>
        </a-sub-menu>
        <a-menu-item key="tip" :disabled="true">
          <span>以上菜单在分类管理配置</span>
        </a-menu-item>
      </a-menu>
    </a-layout-sider>
    <a-layout-content
    :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
  >
      <div class="welcome" v-show="isShowWelcome">
        <the-welcome></the-welcome>
      </div>
      <a-list v-show="!isShowWelcome" item-layout="vertical" size="large" :grid="{ gutter: 20, column: 3 }" :data-source="ebooks">
        <template #renderItem="{ item }">
          <a-list-item key="item.name">
            <template #actions>
              <span>
                <component v-bind:is="'FileOutlined'" style="margin-right: 8px" />
                {{ item.docCount }}
              </span>
              <span>
                <component v-bind:is="'UserOutlined'" style="margin-right: 8px" />
                {{ item.viewCount }}
              </span>
              <span>
                <component v-bind:is="'LikeOutlined'" style="margin-right: 8px" />
                {{ item.voteCount }}
              </span>
            </template>
            <a-list-item-meta :description="item.description">
              <template #title>
                <router-link :to="'/doc?ebookId=' + item.id">
                  {{ item.name }}
                </router-link>
              </template>
              <template #avatar><a-avatar :src="item.cover"/></template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
  </a-layout-content>
  </a-layout>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref, reactive, toRef } from 'vue';
import axios from 'axios';
import { message } from 'ant-design-vue';
import {Tool} from "@/util/tool";
import TheWelcome from '@/components/the-welcome.vue';


export default defineComponent({
  name: 'Home',
  components: {
    TheWelcome
  },
  setup() {
    const ebooks = ref();
    // const ebooks1 = reactive({books: []});

    const openKeys =  ref();

    const level1 =  ref();
    let categorys: any;
    /**
     * 查询所有分类
     **/
    const handleQueryCategory = () => {
      axios.get("/category/all").then((response) => {
        const data = response.data;
        if (data.success) {
          categorys = data.content;
          console.log("原始数组:", categorys);

          // 加载完分类后,将侧边栏全部展开
          openKeys.value = [];
          for (let i = 0; i < categorys.length; i++) {
            openKeys.value.push(categorys[i].id)
          }

          level1.value = [];
          level1.value = Tool.array2Tree(categorys, 0);
          console.log("树形结构:", level1.value);
        } else {
          message.error(data.message);
        }
      });
    };

    const isShowWelcome = ref(true);
    let categoryId2 = 0;

    const handleQueryEbook = () => {
      axios.get("/ebook/list", {
        params: {
          page: 1,
          size: 1000,
          categoryId2: categoryId2
        }
      }).then((response) => {
        const data = response.data;
        ebooks.value = data.content.list;
        // ebooks1.books = data.content;
      });
    };

    const handleClick = (value: any) => {
      // console.log("menu click", value)
      if (value.key === 'welcome') {
        isShowWelcome.value = true;
      } else {
        categoryId2 = value.key;
        isShowWelcome.value = false;
        handleQueryEbook();
      }
      // isShowWelcome.value = value.key === 'welcome';
    };

    onMounted(() => {
      handleQueryCategory();
      // handleQueryEbook();
    });

    return {
      ebooks,
      // ebooks2: toRef(ebooks1, "books"),
      // listData,
      pagination: {
        onChange: (page: any) => {
          console.log(page);
        },
        pageSize: 3,
      },

      handleClick,
      level1,

      isShowWelcome,

      openKeys
    }
  }
});
</script>

<style scoped>
  .ant-avatar {
    width: 50px;
    height: 50px;
    line-height: 50px;
    border-radius: 8%;
    margin: 5px 0;
  }
</style>

三、❗注意

在之前写的admin-ebook.vue当中还有一些代码是注释掉的,因为之前没有写分类模块,现在我们需要使用分类的功能了,我们还需要解除一些注释。大家可以看看哪些地方有关category的被注释掉了,大家可以打开,后端接口下一篇文章就会带大家写出来。

这里需要修改一些onMounted()函数中的代码,修改成下边的部分。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 onMounted(() => {
      handleQueryCategory();
      // handleQueryEbook();
    });

此外,这个网站的标题头部的信息可能我之前没加上去,就是这个。

在the-header.vue中修改一下自己的代码。

在下边的style中加上样式。然后就可以展示出来了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<style>
  .logo {
    width: 120px;
    height: 31px;
    /*background: rgba(255, 255, 255, 0.2);*/
    /*margin: 16px 28px 16px 0;*/
    float: left;
    color: white;
    font-size: 18px;
  }
</style>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
LCD1602液晶使用介绍–(完整版)
所谓的1602是指显示的时候,有2行内容每行有16个字符。其实这类字符型产品都可以这样解读比如:lcd12864就是有128行64列。目前市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理大多相同。因此基于HD44780写的液晶控制程序可以很方便适用于市面上大多数字符型液晶产品。
全栈程序员站长
2022/09/13
1.4K0
LCD1602液晶使用介绍–(完整版)
4.11 51单片机-LCD1602显示屏
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号的点阵型液晶模块。
DS小龙哥
2022/01/10
7300
4.11 51单片机-LCD1602显示屏
C51单片机LCD1602驱动程序
LCD1602字符型液晶(每行显示16个字符,一共可以显示两行)——一种专门用来显示字母、数字、符号的点阵型液晶模块。它由若干个5×7或者5×10的点阵字符组成,每个点阵字符位都可以用来显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,所以它不能很好的显示图片。
全栈程序员站长
2022/09/13
8460
C51单片机LCD1602驱动程序
【常用传感器】LCD1602液晶工作原理详解及例程代码[通俗易懂]
LCD ( Liquid Crystal Display 的简称)液晶显示器。能够同时显示16×2,32个字符,是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
全栈程序员站长
2022/07/28
5.1K0
【常用传感器】LCD1602液晶工作原理详解及例程代码[通俗易懂]
lcd开机流程图_LCD1602程序代码及显示流程图.doc[通俗易懂]
前些天弄了最小系统板后就想着学习1602的显示程序,可惜坛子里的或网上的,都没有简单的1602显示程序,无柰在网上下载了一段经过反复修改测试,终于有了下面一段代码:
全栈程序员站长
2022/09/13
7730
lcd1602使用手册_lcd1602的rs,rw和e三个引脚的功能
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
全栈程序员站长
2022/08/02
7.9K0
lcd1602使用手册_lcd1602的rs,rw和e三个引脚的功能
1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程
delay_n40us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
全栈程序员站长
2022/09/13
1.2K0
1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程
和12岁小同志搞创客开发:如何驱动LCD1602液晶显示屏?
项目专栏:https://blog.csdn.net/m0_38106923/category_11097422.html
不脱发的程序猿
2021/10/25
6080
和12岁小同志搞创客开发:如何驱动LCD1602液晶显示屏?
lcd开机流程图_LCD1602程序代码及显示流程图
前些天弄了最小系统板后就想着学习1602的显示程序,可惜坛子里的或网上的,都没有简单的1602显示程序,无柰在网上下载了一段经过反复修改测试,终于有了下面一段代码:
全栈程序员站长
2022/09/13
1.3K0
lcd开机流程图_LCD1602程序代码及显示流程图
LCD1602为什么不能一次点亮?
LCD 1602 是一种点阵式的字符型液晶屏,它能够同时显示16 x 02即32个字符。LCD 1602 液晶显示屏的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,即可以显示出图形。1602是指显示的内容为16 x 2,即同时可以显示两行,每行16个字符,但只能显示字符和数字。LCD 1602是通过 HD44780 液晶控制芯片控制的。控制驱动主电路及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。不同厂家生产的LCD1602芯片可能有所不同,但使用方法基本都是一样的。
单片机技术宅
2022/11/22
7430
LCD1602为什么不能一次点亮?
LCD1602
LCD1602是我们常用的一种显示屏,一直想写一些关于元器件的介绍和使用。今天就来从LCD1602开始。
跋扈洋
2021/02/02
1.1K0
LCD1602
Arduino 和LCD1602液晶屏 I2C接口实验「建议收藏」
为什么使用I2C接口?因为省IO口啊,只需要4条线,可以看看之前发的实验,接线多复杂呀,对吧。
全栈程序员站长
2022/07/29
3K0
Arduino 和LCD1602液晶屏 I2C接口实验「建议收藏」
Arduino与LCD1602(I2C)搭配使用攻略
我使用的是Arduino(UNO)开发板和LCD1602带拓展板I2C。具体连线比较简单。 GND ------ 地线 VCC ------ 电源5V SDA ------ I2C 数据线 SCL ------ I2C 时钟线
zstar
2022/06/14
1.3K0
Arduino与LCD1602(I2C)搭配使用攻略
lcd1602模块的基本组成_1602液晶显示模块P0口
LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。下图即是该模块:
全栈程序员站长
2022/11/09
9590
lcd1602模块的基本组成_1602液晶显示模块P0口
51单片机LCD1602程序详解[通俗易懂]
LCD1602 工业字符型液晶。1602是指LCD显示的内容为16X2,即可以显示两行,每行16个字符.
全栈程序员站长
2022/09/13
2K0
1602A的基本描述[通俗易懂]
LCD1602的主控芯片是HD44780或者其它兼容芯片。 与此相仿的是LCD12864液晶显示器,它是一种图形点阵显示器,能显示的内容比LCD1602要丰富得多,除了普通字符外,还可以显示点阵图案,带有汉字库的还可以显示汉字,它的并行驱动方式与LCD1602相差无几,所以,在这里花点时间是值得的。
全栈程序员站长
2022/11/09
5610
1602A的基本描述[通俗易懂]
51单片机+DS1302设计一个电子钟(LCD1602显示时间)
电子钟是一种能够准确显示时间的设备,广泛应用于家庭、办公场所和公共场所,为人们提供了方便和准确的时间信息。本项目设计一个基于51单片机的电子钟,使用DS1302作为RTC时钟芯片,LCD1602作为显示屏,并通过串口方式连接上位机进行时间设置和闹钟设置。
DS小龙哥
2023/11/15
1.9K1
51单片机+DS1302设计一个电子钟(LCD1602显示时间)
(十四)51单片机——LCD1602实现滚动效果
目录 学习目标 成果展示  硬件知识 LCD1602介绍  引脚定义 内部结构 DDRAM 字模库 时序结构 指令集 操作流程 代码  总结  ---- 学习目标         今天我们要学习的是LCD1602液晶显示屏。首先,我们会编写显示各种数据的函数,比如显示字符串、十进制数、二进制数等等,之后我们会让LCD1602显示屏动起来,形成我们日常看到的广告牌的样子。 成果展示  https://live.csdn.net/v/embed/229030 LCD1602 硬件知识 LCD1602介绍 
小点点
2022/12/12
2.6K0
(十四)51单片机——LCD1602实现滚动效果
lcd1602c语言程序分析,LCD1602 C程序
LCD基本显示程序 四条数据线输入:DB4—RB0,DB5—RB1,DB6—RB2,DB7—RB3 寄存器选择RS接RB4,为”L”指令寄存器,为”H”数据寄存器 读写使能控制线E,接RE2,每当E线向LCD模块发送一个正脉冲,LCD模块与 单片机 之间将进行一次数据交换; //**********定义与声明******************* #include
全栈程序员站长
2022/09/13
6290
STM32驱动LCD1602程序(调试已成功)「建议收藏」
IO接线: RS PA8 RW PB6 E PB7 LCD1602_IO PB8-PB15 所有的口都配置成开漏输出,并且所有的口都通过10k电阻上拉至5V,部分电路图如下:
全栈程序员站长
2022/09/13
3K0
STM32驱动LCD1602程序(调试已成功)「建议收藏」
推荐阅读
相关推荐
LCD1602液晶使用介绍–(完整版)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档