当前位置:   article > 正文

jq项目总结

jq项目

大纲:
在这里插入图片描述

一、项目介绍

  • 后台主要是文章分类、编辑、发布、管理
  • 前台主要是文章的浏览,页面的跳转,评论的发布等
    在这里插入图片描述
    在这里插入图片描述

二、需求分析

  1. 登录功能
  • 输入正确的用户名(admin)和密码(123456)登录到管理系统首页
  1. 后台首页模块
  • 加载默认数据
  • 侧边栏切换
  • 退出登录
  1. 个人中心模块
  • 加载用户信息
  • 修改用户信息
  1. 文章分类模块
  • 增加文章分类
  • 编辑文章分类
  • 删除文章分类
  1. 文章列表模块
  • 条件查询
  • 发表,编辑、删除文章
  1. 文章编辑模块
  • 通过id传值加载文章的信息
  • 修改信息后返回上一页
  1. 文章发布模块
  • 填写信息发布或存为草稿
  • 返回上一页
  1. 评论管理模块
  • 评论的审核:拒绝、批准、删除

三、技术分析

  • bootstrap模态框弹出(传送门
  • token
  • 排他思想切换样式(slideToggle、toggleClass)
  • 服务器接口文档封装
  • iframe标签使用传送门
  • 文件预览和文件上传
  • label标签for属性自定义上传按钮
  • a标签的默认事件与注册事件
  • 模态框的复用
  • 自定义属性data-id的使用
  • select下拉菜单使用
  • pagination分页插件使用
  • 通过id页面传值
  • jedate插件的使用
  • wangEditor插件的使用
  • art-template模板引擎语法的应用
  • EChart的使用

四、布局分析

  1. 登录功能
    1.1 form中两个input输入框一个提交按钮
    1.2bootrap模态框与body同级

  2. 后台首页模块
    1.1 左侧顶部logo和管理员信息
    1.2 右侧顶部个人信息和退出功能栏
    1.3 左侧 侧边栏,右侧主体内容嵌入iframe
    在这里插入图片描述

  3. 个人中心模块
    1.1 一个form表单

  4. 文章分类模块
    1.1 一个表格

  5. 文章列表模块
    1.1 主体内容在表格
    1.2 底部分页导航

  6. 文章编辑模块
    1.1 form表单
    1.2 时间和文本域由插件组成

  7. 文章发布页面
    1.1与编辑大体相同

  8. 评论管理
    1.1 内容放在表格中

五、具体实现

1. 登录功能
1.1 设置点击事件
1.2 阻止表单默认跳转
1.3 获取输入框内容
1.4 非空判断
1.5 修改模态框文本并弹出
1.6 ajax请求数据
1.7 使用localStorage储存用户token
1.8 给模态框注册隐藏事件 手动隐藏模态
在这里插入图片描述

  • login. html
<body>
  <div class="main_wrap">
    <div class="header">
      <a href="#" class="logo"><img src="images/logo.png" alt="" /></a>
      <div class="copyright">
        CopyRight © 2019 深圳百秀信息技术股份有限公司<br />All Rights Reserved
      </div>
    </div>

    <div class="login_form_con">
      <div class="login_title"></div>
      <form class="login_form">
        <i class="iconfont icon-user"></i>
        <i class="iconfont icon-key"></i>
        <input type="text" class="input_txt" placeholder="邮箱/手机号" />
        <input type="password" class="input_pass" placeholder="密码" />
        <input type="submit" class="input_sub" value="登 录" />
      </form>
    </div>
  </div>
  <!-- 模态框 -->
  <div class="modal fade" tabindex="-1" role="dialog" id="myModal">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
              aria-hidden="true">&times;</span></button>
          <h4 class="modal-title">友情提醒</h4>
        </div>
        <div class="modal-body">
          <p>One fine body&hellip;</p>
        </div>
        <div class="modal-footer">
          <!-- <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> -->
          <button type="button" class="btn btn-primary" data-dismiss="modal">确认</button>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • login.js
// 入口函数
$(function () {
    // 1.注册点击事件
    $('.input_sub').click(function (e) {
        // 表单带有默认跳转效果,需阻止其自动跳转
        e.preventDefault();

        // 2.获得输入框内容
        let username = $('.input_txt').val();
        let password = $('.input_pass').val();
        // 3.非空判断
        if (username.length == 0 || password == 0) {
            // (1)修改模态框文本
            $('.modal-body>p').text('用户名和密码不能为空哦!');
            // (2)弹出模态框
            $('#myModal').modal();
            return;
        } else {
            // 4.ajax请求
            $.ajax({
                url: 'http://localhost:8080/api/v1/admin/user/login',
                type: 'post',
                dataType: 'json',
                data: {
                    username: username,
                    password: password
                },
                success: function (backData) {
                    console.log(backData);
                    if (backData.code == 200) {
                        // 使用localStorage储存用户token
                        localStorage.setItem('token', backData.token);
                        // (1)修改模态框
                        $('.modal-body>p').text('登录成功!');
                        // (2)弹出模态框
                        $('#myModal').modal();
                        // (3)给模态框注册隐藏事件 
                        $('#myModal').on('hidden.bs.modal', function (e) {
                            // 跳转到首页
                            window.location.href = './index.html';
                        });
                    } else {
                        // (1)修改模态框文本
                        $('.modal-body>p').text(backData.msg);
                        // (2)弹出模态框
                        $('#myModal').modal();
                    }
                }
            });
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

2. 首页模块
(1)用户信息功能(ajax加载数据)
1. 给index.html文件添加一个iframe标签
2. 给index.html页面左侧导航栏的a标签添加target属性,指向iframe标签的name属性值
作用:让这个a标签的href属性链接在右侧iframe标签中打开
3. 实现左侧导航栏点击a标签高亮效果与文章管理下拉效果
(2)退出登录功能(不需要接口只需清除token

  1. 清除token localStorage.removeItem('token');
  2. 加载的登录页window.location.href = './loging.html';
  • index.html
<body>
    <div class="sider">
        <a href="#" class="logo"><img src="images/logo02.png" alt="logo"></a>
        <div class="user_info">
            <img src="images/2.jpg" alt="person">
            <span>欢迎&nbsp;&nbsp;李宗盛</span>
            <b>管理员</b>
        </div>
        <!-- 左侧导航栏 -->
        <div class="menu">
            <div class="level01 active"><a href="main_count.html" target="main_frame"><i
                        class="iconfont icon-yidiandiantubiao04"></i><span>首页</span></a></div>
            <div class="level01"><a href="#"><i class="iconfont icon-icon-article"></i><span>文章管理</span><b
                        class="iconfont icon-arrowdownl"></b></a></div>
            <ul class="level02">
                <li><a href="./article_list.html" target="main_frame"><i class="iconfont icon-previewright"></i><span>文章列表</span></a></li>
                <li><a href="./article_release.html" target="main_frame"><i class="iconfont icon-previewright"></i><span>发表文章</span></a></li>
                <li><a href="./article_category.html" target="main_frame"><i class="iconfont icon-previewright"></i><span>文章类别管理</span></a>
                </li>
            </ul>

            <div class="level01"><a href="./comment_list.html" target="main_frame"><i
                        class="iconfont icon-comment"></i><span>评论管理</span></a></div>
            <div class="level01" id="user"><a href="./user.html" target="main_frame"><i
                        class="iconfont icon-user"></i><span>个人中心</span></a></div>
        </div>
        <!-- 顶部栏 -->
        <div class="header_bar">
            <div class="user_center_link">
                <a href="./user.html" target="main_frame">个人中心</a>
                <img src="images/2.jpg" alt="person">
                <a href="javascript:void(0)" class="logout"><i class="iconfont icon-tuichu"></i> 退出</a>
            </div>
        </div>
        <!-- 右侧主体内容 -->
        <div class="main" id="main_body">
            <!-- 右侧添加iframe,默认src指向首页图表页面main_count.html -->
            <iframe src="main_count.html" frameborder="0" width="100%" height="100%" name="main_frame"></iframe>
        </div>
    </div>
    </body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

index.js

// 入口函数
$(function () {

    $.ajax({
        url: 'http://localhost:8080/api/v1/admin/user/info',
        type: 'get',
        dataType: 'json',
        success: function (backData) {
            console.log(backData);
            // 渲染数据
            $('.user_info>img').attr('src', backData.data.userPic);
            $('.user_info>span').text(backData.data.nickname);
            $('.user_center_link>img').attr('src', backData.data.userPic);
        }
    });


    /*   点击左侧导航栏效果 */
    $('.level01').click(function () {
        // console.log('djl');
        $(this).addClass('active').siblings().removeClass('active');
        if ($(this).index() == 1) {
            // (2)二级菜单下滑
            $('.level02').slideToggle();
            $(this).find('b').toggleClass('rotate0');
            $('level02>li:eq(0) a')[0].click();

        } else {
            // 取消所有的二级菜单高亮状态
            $('.level02>li').removeClass('active');
        }

    });
    // 二级菜单点击事件
    $('.level02>li').click(function () {
        // 排他思想修改样式
        $(this).addClass('active').siblings().removeClass('active')
    })

    // 退出登录
    $('.logout').click(function () {
        localStorage.removeItem('token');
        window.location.href = './loging.html';
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

3. 个人中心模块

  • 加载数据库中的数据
  • 图片模块文件预览和文件上传
    在这里插入图片描述
    1.细节优化:给index.html页面的右侧顶部个人中心按钮设置target属性指向iframe的name,并且注册行内事件:主动触发左侧个人中心按钮的点击事件
  • href="./user.html" + target=“main_frame”:在iframe中打开个人中心页面
  • οnclick="$(’#user’).trigger(‘click’)" :主动触发左侧导航栏个人中心的点击事件,来修改a标签高亮效果
<div class="user_center_link">
	<a href="./user.html" onclick="$('#user').trigger('click')" target="main_frame">个人中心</a>
	<img src="images/2.jpg" alt="person">
	<a href="javascript:void(0)" class="logout"><i class="iconfont icon-tuichu"></i> 退出</a>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5

2.页面一加载,ajax请求个人详细信息,渲染页面

  • 细节:渲染页面的表单元素类名与服务器返回的对象属性名一致,就可以写一个for-in循环优化代码
//1.页面一加载:ajax请求个人详情信息,渲染页面
    $.ajax({
        url: BigNew.user_detail,
        type: 'get',
        dataType: 'json',
        success: function (backData) {
            console.log(backData);
            //渲染页面
            // $('input.username').val(backData.data.username);
            // $('input.nickname').val(backData.data.nickname);
            // $('input.email').val(backData.data.email);
            // $('input.password').val(backData.data.password);
            //遍历对象优化代码
            for (var key in backData.data) {
                $('input.' + key).val(backData.data[key]);
            }
            $('img.user_pic').attr('src', backData.data.userPic);
        }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  1. .文件预览功能
  • 固定的四个步骤
//2.文件预览
    //1.给file表单元素注册onchange事件
    $('#exampleInputFile').change(function () {
        //1.2 获取用户选择的图片
        let file = this.files[0];
        //1.3 将文件转为src路径
        let url = URL.createObjectURL(file);
        //1.4 将url路径赋值给img标签的src
        $('.user_pic').attr('src', url);
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 编辑个人信息
  • 使用formData上传带文件的参数
  • 注意点:当前页面所在的窗口window对象是user.html,如果想要获取父窗口,则需要使用window.parent,这种用法一般用于获取iframe标签的父窗口。
    https://www.runoob.com/jsref/prop-win-parent.html
//3.编辑个人信息(fromdata上传文件)
    $('#form').on('submit', function (e) {
        //禁用表单默认提交事件
        e.preventDefault();
        $.ajax({
            url: BigNew.user_edit,
            type: 'post',
            dataType: 'json',
            data: new FormData(this),
            contentType: false,
            processData: false,
            success: function (backData) {
                console.log(backData);
                if (backData.code == 200) {
                    alert('修改成功');
                    /* 
                    window:            当前页面窗口 user.html
                    window.parent:     当前页面父窗口 index.html
                    */
                    window.parent.location.reload();
                }
            }
        });
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • user.js
// 入口函数
$(function () {
    // 页面一加载ajax加载用户信息
    $.ajax({
        url: BigNew.user_detail,
        type: 'get',
        dataType: 'json',
        success: function (backData) {
            console.log(backData);
            //渲染数据
            $('.user_pic').attr('src', backData.data.userPic);
            // 遍历对象快速赋值
            for (let key in backData.data) {
                $('.' + key).val(backData.data[key]);
            }

        }
    });

    // 文件预览
    // 1.给表单注册一个onchange事件
    $('#exampleInputFile').change(function () {
        //2.获取选中的文件
        let file = this.files[0];
        // 3.根据文件生成url    
        let url = URL.createObjectURL(file);
        // 4.img标签src属性显示url
        $('.user_pic').attr('src', url);

    });

    // 文件上传
    $('.btn-edit').click(function (e) {
        // 1.阻止表单默认跳转
        e.preventDefault();
        // 2.使用formfdata生成参数
        let fd = new FormData($('form')[0]);

        // 3.ajax 请求数据
        $.ajax({
            url: BigNew.user_edit,
            type: 'post',
            dataType: 'json',
            data: fd,
            processData: false,
            contentType:false,
            success: function (backData) {
                console.log(backData);
                if (backData.code == 200) {
                    // 1.修改模态框文本
                    $('.modal-body>p').text('修改成功')
                    // 2.弹出模态框
                    $('#myModal').modal();
                    // 3.给模态框注册隐藏事件
                    $('#myModal').on('hidden.bs.modal', function (e) {
                        // 刷新首页
                        window.parent.location.reload();
                    });
                } else {
                    //1.修改模态框文本
                    $('.modal-body>p').text(backData.msg);
                    //2.弹出模态框
                    $('#myModal').modal();
                }
            }
        });

    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

4. 文章分类模块
PS:模态框事件触发源:点击的是谁,谁就是弹出的模态框原生’DOM对象’(e.relatedTarget
在这里插入图片描述

  1. ajax加载数据
  • 模板
    • 给编辑和删除按钮 创建一个自定义属性data-id将每个分类的id存在其中
  <script id="cat_list" type="text/html">
        {{each data v}}
        <tr>
            <td> {{v.name}} </td>
            <td>{{v.slug}} </td>
            <td class="text-center">
                <a data-id=" {{v.id}} " href="javascript:void(0);" data-toggle="modal" class=" btn btn-info btn-xs"
                    data-target="#myModal">编辑</a>
                <a data-id=" {{v.id}} " href="javascript:void(0);" class="btn btn-danger btn-xs btn-delete">删除</a>
            </td>
        </tr>
        {{/each}}
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. 模态框复用 : 点击新增和编辑弹出是同一个模态框
    • 编辑时将data-id 的id给模态框的编辑按钮.通过ajax请求id参数匹配获取信息

 //给模态框注册点击事件:获取e.relatedTarget弹出事件源
            // 1.给模态框注册弹出事件
            $('#myModal').on('show.bs.modal', function (e) {
                // 模态框事件触发源:点击的是谁弹出的模态框(原生DOM对象)
                console.log(e.relatedTarget);
                if ($(e.relatedTarget).text() == '新增分类') {
                    // 新增业务逻辑
                    // (1)修改模态框确认按钮为新增
                    $('.btn-confirm').text('新增');
                } else {
                    // 编辑业务逻辑
                    // (2)修改模态框框确定按钮为编辑
                    $('.btn-confirm').text('编辑');
                    // 传值:显示当前编辑的文章分类信息
                    // e.relatedTarget : 当前点击的编辑按钮
                    $('#recipient-name').val($(e.relatedTarget).parent().prev().prev().text());
                    $('#message-text').val($(e.relatedTarget).parent().prev().text());

                    // (3)传值:将当前点击的编辑按钮的data-id传递给模态框的编辑按钮
                    $('.btn-confirm').attr('data-id', $(e.relatedTarget).attr('data-id'));
                }
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
//给模态框注册点击事件:获取e.relatedTarget弹出事件源
            // 1.给模态框注册弹出事件
            $('#myModal').on('show.bs.modal', function (e) {
                // 模态框事件触发源:点击的是谁弹出的模态框(原生DOM对象)
                console.log(e.relatedTarget);
                if ($(e.relatedTarget).text() == '新增分类') {
                    // 新增业务逻辑
                    // (1)修改模态框确认按钮为新增
                    $('.btn-confirm').text('新增');
                } else {
                    // 编辑业务逻辑
                    // (2)修改模态框框确定按钮为编辑
                    $('.btn-confirm').text('编辑');
                    // 传值:显示当前编辑的文章分类信息
                    // e.relatedTarget : 当前点击的编辑按钮
                    $('#recipient-name').val($(e.relatedTarget).parent().prev().prev().text());
                    $('#message-text').val($(e.relatedTarget).parent().prev().text());

                    // (3)传值:将当前点击的编辑按钮的data-id传递给模态框的编辑按钮
                    $('.btn-confirm').attr('data-id', $(e.relatedTarget).attr('data-id'));
                }
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  1. 模态框的确认按钮,点击新增显示新新增,点击编辑显示编辑,点击进入编辑状态
    // 3.新增分类
            $('.btn-confirm').click(function () {
                if ($(this).text() == '新增') {
                    // 新增分类
                    $.ajax({
                        url: BigNew.category_add,
                        type: 'post',
                        dataType: 'json',
                        data: {
                            name: $('#recipient-name').val(),
                            slug: $('#message-text').val()
                        },
                        success: function (backData) {
                            console.log(backData);
                            if (backData.code == 201) {
                                alert('新增成功');
                                // 刷新页面
                                window.location.reload();
                            }

                        }
                    });
                } else { //编辑
                    /* 4.编辑分类 */
                    $.ajax({
                        url: BigNew.category_edit,
                        type: 'post',
                        dataType: 'json',
                        data: {
                            id: $(this).attr('data-id'),
                            name: $('#recipient-name').val(),
                            slug: $('#message-text').val()
                        },
                        success: function (backData) {
                            console.log(backData);
                            if (backData.code == 200) {
                                alert('修改成功');
                                // 刷新当前页面
                                window.location.reload();
                            }

                        }
                    });
                }
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  1. 模态框点击取消表单清空,模态框消失
  • 表单有一个reset()方法可以重置表单
 // 2.模态框取消按钮
            $('.btn-cancel').click(function () {
                // 清空列表
                $('.modal-body>form')[0].reset();
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 点击删除,删除这个分类(删除按钮是动态加载的需注册委托事件)
    // 4.删除分类
            // 注意点:删除按钮是ajax动态添加的,需要注册委托事件
            $('body').on('click', '.btn-delete', function () {
                // (1)获取当前点击的按钮的data-id
                let id = $(this).attr('data-id');
                // console.log(id);
                // (2)ajax发送请求
                $.ajax({
                    url: BigNew.category_delete,
                    type: 'post',
                    dataType: 'json',
                    data: {
                        id: id
                    },
                    success: function (backData) {
                        console.log(backData);
                        if (backData.code == 204) {
                            alert('删除成功');
                            // 刷新页面
                            window.location.reload();
                        }
                    }
                });
            });
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

5. 文章列表模块
在这里插入图片描述

  • 1.筛选功能,select下拉框有一个所有分类,但是接口文档不支持这个参数
    • 需求: 页面展示:分类名称 接口参数:分类id
    • 解决方案:利用select优先获取value值的特点
/*2.筛选功能
* 细节:表单中的按钮会有一个默认提交事件,需要阻止默认行为
2.1 按钮注册点击事件
2.2 ajax发送请求(这个请求会多次调用,封装到函数中)
2.3 数据响应之后使用模板引擎渲染页面
2.4 页面一加载就请求所有的数据
*/
//2.1 按钮点击事件
$('#btnSearch').click(function (e) {
    //阻止表单默认行为
    e.preventDefault();
    //2.2 ajax请求
    $.ajax({
        url: BigNew.article_query,
        type: 'get',
        dataType: 'json',
        data: {
            page: currentPage,
            perpage: 10,//每页返回10条数据
            type: $('#selCategory').val(),
            state: $('#selStatus').val(),
        },
        success: function (backData) {
            console.log(backData);
            //2.3 模板引擎渲染页面
            $('.table>tbody').html(template('article_list', backData));
        }
    });
});
//2.4 页面一加载请求数据
$('#btnSearch').trigger('click');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 文章分类模板
<!-- 文章分类模板 -->
	<script id="cat_list" type="text/html">
		<option value="">所有分类</option>
		{{each data v}}
		<option value=" {{v.id}} ">{{v.name}}</option>
		{{/each}}
	</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. 文章列表模板
  • 细节注意点
    • 点击编辑按钮:需要跳转编辑文章页面,可以使用window.location.href传参
    • 点击删除按钮:该接口需要传递文章的id,可以给删除添加添加自定义行内属性data-id存储文章id
<!-- 文章列表模板 -->
<script type="text/html" id="article_list">
    {{ each data.data v }}
    <tr>
        <td>{{ v.title }}</td>
        <td>{{ v.author }}</td>
        <td>{{ v.category }}</td>
        <td class="text-center">{{ v.date }}</td>
        <td class="text-center">{{ v.state }}</td>
        <td class="text-center">
            <a href="article_edit.html?id={{ v.id }}" data-id="{{ v.id }}" class="btn btn-default btn-xs">编辑</a>
            <a href="javascript:void(0);" data-id="{{ v.id }}" class="btn btn-danger btn-xs delete">删除</a>
        </td>
    </tr>
    {{ /each }}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 2.分页插件
    • a.如果用户点击筛选功能,则总页数发生变化。该插件需要重新加载
    • b.性能优化:只有当用户点击的页数和当前页数不一致的时候才会发送ajax请求数据
    • 筛选按钮点击事件:ajax响应之后加载插件
/*2.筛选功能
* 细节:表单中的按钮会有一个默认提交事件,需要阻止默认行为
2.1 按钮注册点击事件
2.2 ajax发送请求(这个请求会多次调用,封装到函数中)
2.3 数据响应之后使用模板引擎渲染页面
2.4 页面一加载就请求所有的数据
*/
//2.1 筛选按钮注册点击事件
$('#btnSearch').click(function (e) {
    e.preventDefault();//表单元素阻止默认行为
    //2.2 ajax发送请求
    $.ajax({
        url: BigNew.article_query,
        type: 'get',
        dataType: 'json',
        data: {
            type: $('#selCategory').val(),
            state: $('#selStatus').val(),
            page: 1,
            perpage: 10
        },
        success: function (backData) {
            console.log(backData);
            //2.3 模板引擎渲染页面
            $('.table>tbody').html(template('art_list', backData));
            //pagination插件使用
            //(1)先销毁旧插件
            $('#pagination').twbsPagination('destroy');
            //(2)重新加载插件
            $('#pagination').twbsPagination({
                totalPages: backData.data.totalPage,
                visiblePages: 6,
                startPage: 1,
                first: '首页',
                prev: '上一页',
                next: '下一页',
                last: '尾页',
                onPageClick: function (event, page) {
                    //初次加载默认会执行一次点击事件
                    console.log('点击页' + page);
                    //页码处理函数
                    getArticleList(page);
                }
            });
        }
    });
});

//2.4 页面加载默认触发筛选按钮点击事件
$('#btnSearch').trigger('click');

/**
* @description:根据页码查询文章列表
* @param {type} currentPage:当前页
* @return: 
*/
function getArticleList(currentPage) {
    $.ajax({
        url: BigNew.article_query,
        type: 'get',
        dataType: 'json',
        data: {
            type: $('#selCategory').val(),
            state: $('#selStatus').val(),
            page: currentPage,
            perpage: 10
        },
        success: function (backData) {
            console.log(backData);
            $('.table>tbody').html(template('art_list', backData));
        }
    });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

6. 文章编辑模块
(1)获取从article_list传过来的id加载文章类别
(2)注意:加载文章详细信息(ajax加载速度不一样,需先加载完分类栏目再加载详细信息,否则加载类别时有时与内容不一致)
在这里插入图片描述

/* 1.获取从文章列表页传过来的id */
	let id = window.location.href.split('=')[1];
	console.log(id);

	/* 2.先加载所有的文章分类列表 */
	$.ajax({
		url: BigNew.category_list,
		type: 'get',
		dataType: 'json',
		success: function (backData) {
			console.log(backData);
			//模板引擎渲染页面
			$('.category').html(template('cat_list', backData));

			// 先等文章分类加载完,再加载文章详情
			getArticleDetail();
		},
	});

	/* 3.ajax请求文章详细信息 */
	// 封装成一个函数
	function getArticleDetail() {
		$.ajax({
			url: BigNew.article_search,
			type: 'get',
			dataType: 'json',
			data: {
				id: id,
			},
			success: function (backData) {
				console.log(backData);
				// 渲染文章详细信息
				$('.title').val(backData.data.title);
				$('.article_cover').attr('src', backData.data.cover);
				$('.category').val(backData.data.categoryId);
				$('#testico').val(backData.data.date);
				// 富文本编辑器设置需要用到自己的语法
				editor.txt.html(backData.data.content);
			},
		});
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

(3)文件预览

	/* 4.文件预览 */
	//1.给file表单元素注册onchange事件
	$('#inputCover').change(function () {
		//1.2 获取用户选择的图片
		let file = this.files[0];
		//1.3 将文件转为src路径
		let url = URL.createObjectURL(file);
		//1.4 将url路径赋值给img标签的src
		$('.article_cover').attr('src', url);
	});

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(4)文件提交:已发布和草稿
注意点:点击修改和存为草稿都可以修改文章,只是state参数不同
解决方案:
1.封装一个函数
2.同时注册+判断

  • 注意点:
    a.formdata默认只能获取有name属性的表单值
    b.如果formdata获取参数<接口文档参数 则可以使用append手动追加
    c.append()如果追加了重复参数,fd不会覆盖,而是全部发个服务器
	$('.btn-edit,.btn-draft').on('click', function (e) {
		//(1)禁用表单默认提交事件
		e.preventDefault();
		//(2)创建FormData对象:参数是表单dom对象
		let fd = new FormData($('form')[0]);
		/* 
            注意点:
            a.formdata默认只能获取有name属性的表单值
            b.如果formdata获取参数<接口文档参数 则可以使用append手动追加
            c.append()如果追加了重复参数,fd不会覆盖,而是全部发个服务器
        */
		fd.append('id', id);
		fd.append('data', $('#testico').val());
		fd.append('content', editor.txt.html());
		fd.append('state', $(this).text() == '修改' ? '已发布' : '草稿');
		$.ajax({
			url: BigNew.article_edit,
			type: 'post',
			dataType: 'json',
			data: fd,
			contentType: false,
			processData: false,
			success: function (backData) {
				console.log(backData);
				if (backData.code == 200) {
                    alert('编辑成功');
                    // 回退上一级页面:文章列表
                    // window.location.href='./article_list.html'
                    window.history.back();
				}
			},
		});
	});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

7. 文章发布模块

  • 文章类别加载
  • 文件预览
  • 文件上传
    在这里插入图片描述
//入口函数
$(function () {
	/* 1.加载文章类别 */
	$.ajax({
		url: BigNew.category_list,
		type: 'get',
		dataType: 'json',
		success: function (backData) {
			console.log(backData);
			// 渲染到页面
			$('select.category').html(template('cat_list', backData));
		},
	});

	/* 2.文件预览 */
	//1.给file表单元素注册onchange事件
	$('#inputCover').change(function () {
		//1.2 获取用户选择的图片
		let file = this.files[0];
		//1.3 将文件转为src路径
		let url = URL.createObjectURL(file);
		//1.4 将url路径赋值给img标签的src
		$('article_cover').attr('src', url);
	});

	/* 3.文件上传*/
	$('.btn-release,.btn-draft').on('click', function (e) {
		//禁用表单默认提交事件
		e.preventDefault();
		//创建FormData对象:参数是表单dom对象
		let fd = new FormData($('#form')[0]);
		fd.append('content', editor.txt.html());
		fd.append('state', $(this).text().trim() == '发布' ? '已发布' : '');
		$.ajax({
			url: '',
			type: 'post',
			dataType: 'json',
			data: fd,
			contentType: false,
			processData: false,
			success: function (backData) {
				console.log(backData);
				if (backData.code == 200) {
					alert('修改成功');
					$('level02>li:eq(0)', window.parent.document)
						.addClass('active')
						.siblings()
                        .removeClass('active');
                        // 回退上一页
                        window.history.back();
				}
			},
		});
	});
});

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

8. 评论管理

  • ajax请求数据与分页插件实现列表分页加载

  • 通过if语句判断点击的什么按钮,发送不同的ajax请求
    在这里插入图片描述

  • comment.js

<script>
		// 页面一加载
		$.ajax({
			url: BigNew.comment_list,
			type: 'get',
			dataType: 'json',
			data: {
				page: 1,
				perpage: 10,
			},
			success: function (backData) {
				console.log(backData);
				$('table>tbody').html(template('com_list', backData));
				// 加载分页
				//(1)先销毁上一次的分页数据
				$('#pagination').twbsPagination('destroy');
				//(2)加载分页插件
				$('#pagination').twbsPagination({
					totalPages: backData.data.totalPage, //总页数
					startPage: 1, //起始页
					visiblePages: 6, //可见页
					first: '首页',
					prev: '上一页',
					next: '下一页',
					last: '尾页',
					onPageClick: function (event, page) {
						$('#page-content').text('Page' + page);
						console.log('点击页:' + page);
						getCommentList(page);
					},
				});
			},
		});
		// 封装函数请求对应页码评论列表
		function getCommentList(currentPage) {
			$.ajax({
				url: BigNew.comment_list,
				type: 'get',
				dataType: 'json',
				data: {
					page: currentPage,
					perpage: 10,
				},
				success: function (backData) {
					console.log(backData);
					// 模板引擎渲染页面
					$('table>tbody').html(template('com_list', backData));
				},
			});
		}
		/* 3.通过、拒绝、删除:
            请求方法和参数一致,只是路径不同
            表格tr是ajax动态新增的,需要注测委托事件
        */

		$('table>tbody').on(
			'click',
			'.btn-pass,.btn-reject,.btn-delete',
			function () {
				console.log('jinru ');
				//    1.根据按钮来生成对应的url路径
				let url = '';
				switch ($(this).text()) {
					case '批准':
						url = BigNew.comment_pass;
						break;
					case '拒绝':
						url = BigNew.comment_reject;
						break;
					default:
						url = BigNew.comment_delete;
						break;
				}
				console.log(url);
				// 2.发送请求
				$.ajax({
					url: url,
					type: 'post',
					dataType: 'json',
					data: { id: $(this).attr('data-id') },
					success: function (backData) {
						console.log(backData);
						if (backData.code == 200) {
							alert(backData.msg);
							// 刷新页面
							window.location.reload();
						}
					},
				});
			}
		);
	</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 模板
<!-- 模板 -->
	<script id="com_list" type="text/html">
		{{ each data.data v }}
		<tr>
			<td>{{ v.author }}</td>
			<td>{{ v.content }}</td>
			<td>{{ v.title }}</td>
			<td>{{ v.date }} {{ v.time }}</td>
			<td>{{ v.state }}</td>
			<td class="text-center">
				{{ if v.state == '待审核' }}
				<a
					href="javascript:void(0);;"
					data-id="{{ v.id }}"
					class="btn btn-info btn-xs btn-pass"
					>批准</a
				>
				{{ else if v.state == '已通过'}}
				<a
					href="javascript:void(0);;"
					data-id="{{ v.id }}"
					class="btn btn-warning btn-xs btn-reject"
					>拒绝</a
				>
				{{ /if }}
				<a
					href="javascript:void(0);;"
					data-id="{{ v.id }}"
					class="btn btn-danger btn-xs btn-delete"
					>删除</a
				>
			</td>
		</tr>
		{{ /each }}
	</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

六、总结

技术点、注意总结分析

(1)token

没有token时:
在这里插入图片描述

  • token工作流程:
    在这里插入图片描述
    在这里插入图片描述
    • 方法一:原生ajax实现token
			 /* 方法一:原生ajax实现token */
            // (1).实例化ajax对象
            let xhr = new XMLHttpRequest();
            // (2).设置请求方法和地址
            // get请求的数据直接添加在url后面 格式是url?key = value
            xhr.open('get', 'http://localhost:8080/api/v1/admin/user/info');

            // 在请求头中发送token
            xhr.setRequestHeader('Authorization',localStorage.getItem('token'));

            // (3).发送请求
            xhr.send();
            // (4)注册回调函数
            xhr.onload = function(){
                console.log(xhr.responseText);
            }
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 方法二: jq的ajax全局配置:只需配置一次,就会对所有的ajax生效 将其放在jq源码后面 (传送门)
	$.ajaxSetup({
                beforeSend:function(xhr){
                    // (1)发送ajax之前会执行的方法
                    xhr.setRequestHeader('Authorization',localStorage.getItem('token'));
                    localStorage.getItem('token');
                },
                /* (2)ajax失败之后会执行这个函数 */
                erro:function(xhr,status,error){
                    console.log(xhr,status,error);
                    if(xhr.status==403){//未登录
                        alert('请先登录');
                        window.location.href ='./login.html';
                    }else if(xhr.status==404){//路径错误
                        //跳转404页面
                        window.location.href='./404.html';
                    }else{//其他错误,弹窗提示信息
                        alert('‘400:'+error);
                    }
                }
 
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 状态说明
状态码含义说明
200OK请求成功
201CREATED创建成功
204DELETED删除成功
400BAD REQUEST请求的地址不存在或者包含不支持的参数
401UNAUTHORIZED未授权
403FORBIDDEN被禁止访问
404NOT FOUND请求的资源不存在
422Unprocesable entity[POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误
500INTERNAL SERVER ERROR内部错误

(2)服务器接口文档封装(http.js)

  • 1.目前存在的问题
    • a.所有的接口文档都是在各自的页面写死
    • b.服务器基地址与接口地址写在一起,不便于维护
  • 2.解决方案
    • a.将项目所有的接口地址写在一个文件中(http.js)
      • 这样以后接口发生修改就不用修改每一个页面,直接修改这个文件即可
    • b.将http.js文件中的基地址与接口地址分开写
      • 因为服务器的基地址有可能会变。一般企业会有一个测试环境与正式发布环境的基地址
  • http.js文件
    • 什么样的js文件需要使用沙箱模式:这个js文件需要在很多个页面导入
    • 什么样的js文件不需要使用沙箱模式:这个js文件不需要很多个地方导入。例如一个网页的前端三层中的js文件
/* 沙箱模式 */
(function(w){
    let baseURL = 'http://localhost:8080/api/v1'
    let BigNew = {
        baseURL:baseURL,//基地址
        user_login:      baseURL + '/admin/user/login',//用户登录
        user_info:       baseURL + '/admin/user/info',//用户信息
        user_detail:     baseURL + '/admin/user/detail',//用户详情
        user_edit:       baseURL + '/admin/user/edit',//用户编辑
        category_list:   baseURL + '/admin/category/list',//文章类别查询
        category_add:    baseURL + '/admin/category/add',//文章类别新增
        category_search: baseURL + '/admin/category/search',//文章类别搜索
        category_edit:   baseURL + '/admin/category/edit',//文章类别编辑
        category_delete: baseURL + '/admin/category/delete',//文章类别删除
        article_query:   baseURL + '/admin/article/query',//文章搜索
        article_publish: baseURL + '/admin/article/publish',//文章发布
        article_search:  baseURL + '/admin/article/search',//文章信息查询
        article_edit:    baseURL + '/admin/article/edit',//文章编辑
        article_delete:  baseURL + '/admin/article/delete',//文章删除
        comment_list:    baseURL + '/admin/comment/search',//文章评论列表
        comment_pass:    baseURL + '/admin/comment/pass',//文章评论通过
        comment_reject:  baseURL + '/admin/comment/reject',//文章评论不通过
        comment_delete:  baseURL + '/admin/comment/delete',//文章评论删除
    };

    //暴露接口
    w.BigNew = BigNew;
})(window);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

(3)iframe标签使用

  • iframe嵌套多网页核心原理: a标签的target属性 (打开方式)
    • 默认值_self : 在当前页面打开
    • _blank : 在新页面打开
    • framename : iframe标签的name属性值,在指定的iframe标签中打开
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        iframe {
            /* iframe默认是行内块,转块级auto就会生效 */
            display: block;
            margin: 50px auto;
            width: 800px;
            height: 600px;
        }
    </style>
</head>

<body>

    <!-- 
        iframe嵌套多网页核心原理: a标签的target属性 (打开方式)
            默认值_self : 在当前页面打开
            _blank : 在新页面打开
            framename : iframe标签的name属性值,在指定的iframe标签中打开
     -->
    <a href="./index1.html" target="myframe">页面1</a>
    <a href="./index2.html" target="myframe">页面2</a>
    <a href="./index3.html" target="myframe">页面3</a>
    <iframe src="./index1.html" frameborder="0" name="myframe"></iframe>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这里插入图片描述

a标签的默认事件与注册事件

  1. a标签有一个默认跳转事件
  2. a标签也可以注册点击事件 (两个事件: 默认事件 + 注册事件)
  3. a标签js原生的onclick与click方法区别
    onclick() : 只能触发注册事件
    click()方法 : 同时触发默认事件 + 注册事件
    onclick() : 只能触发注册事件 -> 等同于jq的$().click()
  document.querySelector('a').onclick = function () {// jq : $('a').click(function(){})
            this.style.border = '10px solid red';
        };
  • 1
  • 2
  • 3

label标签for属性自定义上传按钮

1.给label标签的for属性赋值,值是input标签的id,
那这样的话点击label就相当于点击了input
2.隐藏这个input,然后在label标签里面添加img标签即可
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!-- 技术点:自定义上传按钮样式
        1.给label标签的for属性赋值,值是input标签的id,
    那这样的话点击label就相当于点击了input
        2.隐藏这个input,然后在label标签里面添加img标签即可
     -->
     <input style="display: none" id="aaa" type="file" value="上传文件">
     <br>
    <label for="aaa">
        <img src="./uploads_icon.jpg" style="height: 50px" alt="">
    </label>
    
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

select下拉菜单使用

select标签特点

  • 1.默认只会获取select中option标签的值,不会获取select自己的value值
  • 2.如果option有value属性,则select会优先获取option的value值
  • 3.如果option没有value属性,则select会获取option的text值
  • 开发中:
    (1)服务器需要的参数id : 放在value属性值中 (下拉菜单的value属性优先获取)
    (2)用户展示的数据 : 放在innerText
	<select name="" id="sel" value="666">
        <option>爱生活</option>
        <option>爱美食</option>
        <option>爱运动</option>
        <option>爱学习</option>
    </select>

    <script>
        console.log( document.querySelector('#sel').value );//爱生活
        
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

pagination分页插件使用

总结链接

jedate插件的使用

总结链接

wangEditor插件的使用

总结链接

Echart的使用

链接

  1. 导包
<!-- 1.引入 ECharts 文件 -->
<script src="echarts.js"></script>
  • 1
  • 2
  1. HTML结构
<!-- 2.为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
  • 1
  • 2
  1. 初始化
// 3.1 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));

// 3.2 指定图表的配置项和数据
//所有的图表使用步骤都是固定的,不同的图表仅仅只是配置项和数据不同而已
var option = {
    title: {
        text: 'ECharts 入门示例'
    },
    tooltip: {},
    legend: {
        data: ['销量']
    },
    xAxis: {
        data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
    },
    yAxis: {},
    series: [{
        name: '销量',
        type: 'bar',
        data: [5, 20, 36, 10, 10, 20]
    }]
};

// 3.3使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

所有的图表使用步骤都是固定的,不同的图表仅仅只是配置项(option)和数据不同而已

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/813092
推荐阅读
相关标签
  

闽ICP备14008679号