vue 项目环境搭建

项目目标:

    1)熟练掌握ajax的使用 (*****)

    2)熟悉前后端数据交互(***)

    3)熟悉elementui 框架的使用(***)

    4)熟悉vue的简单使用(***)

    5)了解后端增删改查的逻辑

    6)对整个项目的前后端结构和逻辑都有一个认识。


难点:分页(后端)模糊查询(后端)


DAY01需求:

    A 搭建项目环境

        1 使用express搭建项目环境

            express smms -e


        2 进入项目根目录 一次性安装所有依赖

            cnpm i


        3 监听端口 启动服务器

            a) 打开app.js文件  

                app.listen(666, () => {

                    console.log('服务器启动成功...端口:666')

                })


            b) 启动服务器

                nodemon app



    B 前端资源文件都放入public, 集成elementui和vue.js

        1 搭建前端目录结构,准备资源文件

            images: 图片

            js: 脚本

            styles: 样式

            libs:第三方库

                elementui:

                    css: 样式文件

                    fonts: 字体文件(css需要引用它,注意路径!)

                    js:  js脚本(依赖vue.js)


                vue:  vue.min.js


                jquery: jquery.min.js


        2 新建一个测试页面 测试环境是否搭建成功

注意:主要测试elementui是否可以使用。

    C 登录页面的布局实现

        1 登录页面表单

        2 水平和垂直居中

            1) 子绝父相

            2) left right top bottom  都设置为0

            3) margin: auto


    D 表单的基本验证:

        1 data里面有两份数据

            1) 双向数据绑定 主要用来取值

                loginForm: {  

                    username: '',  // 用户名

                    password: '',  // 密码

                    confirmPassword: '' // 确认密码

                }

            2) 验证规则的数据

                  rules: {

                        // 验证用户名

                        username: [

                            {required: true, message: '请输入用户名', trigger: 'blur'}, // 非空验证

                            {min: 5, max: 12, message: '用户名长度在 5 到 12 个字符', trigger: 'blur'} // 长度验证

                        ],

                        // 验证密码

                        password: [

                            {required: true, message: '请输入密码', trigger: 'blur'}, // 非空验证

                            {min: 6, max: 12, message: '密码长度在 6 到 12 个字符', trigger: 'blur'} // 长度验证

                        ],

                        // 验证确认密码 (自定义验证规则)

                        confirmPassword: [

                            { validator: checkPass, trigger: 'blur' }  // 自定义验证函数

                        ],

                    }

说明:

在return之前 自己写的验证函数

                    let 验证函数的名字 = (rules, value, callback) => {

                        // 对value判断

                        if (value === '') {

                            // 给出提示信息 输入框边框变红色 有一个 x

                            callback(new Error('不能为空'))

                        } else if (value.length < 6 || value.length > 18) {

                             // 给出提示信息 输入框边框变红色 有一个 x

                            callback(new Error('长度必须在6 - 18 位之间'))

                        } else {

                            // 成功 输入框边框变绿色 有一个√

                            callback()

                        }

                    }


                    rules: {

要验证的字段: [

                            {required: true, message: '提示信息', trigger: '触发方式'},   // 非空验证

                            {min: 5, max: 12, message:'提示信息', trigger: '触发方式'},   // 长度验证

                            {validator: 自己写的验证函数的名字, trigger: '触发方式'}

                        ]

                    }


        2 提交表单方法

            submitForm(formName) {

                // $refs能够把用 ref属性声明的dom 都收集在一个对象里面

                this.$refs[formName].validate((valid) => {

                    // 如果valid是true 证明整个表单前端验证全部通过 允许发送给后端了

                    if (valid) {

                        // 收集用户输入的用户名和密码

                        let username = this.loginForm.username;

                        let password = this.loginForm.password;


                        // 构造ajax 把用户名和密码发送给后端(等待 后端去数据库查询存不存在)

                    } else {

                        // valid是false 证明前端验证没有通过 不允许提交表单 不允许发给后端

                        console.log('error submit')

                        return false;

                    }

                })

            }

        3 重置表单:

            resetForm(formName) {

                // 获取整个表单 调用重置方法

                this.$refs[formName].resetFields();  // this.$refs[formName] ==> this.$refs.loginForm

            }

    E 后台首页页面的实现

    D 添加账号页面的实现

    F 用户列表页面的实现


DAY02:需求

准备工作:

        1 数据库设计:

数据库名字:admin

表的名字:users

创建用户账号表:

                create table `users` (

                    id int primary key auto_increment,

                    username varchar(50),

                    password varchar(32),

                    groups varchar(50),

                    ctime TIMESTAMP  default CURRENT_TIMESTAMP

                );


        2 nodejs连接mysql数据库?

            1)下载mysql模块

                cnpm i mysql --save


            2) 引入mysql模块

                const mysql = require('mysql');


            3) 创建连接

                const connection = mysql.createConnection({

                    host     : 'localhost',  // 主机名

                    user     : 'root',   // 用户名

                    password : 'root', // 密码

                    database : 'admin'  // 数据库的名字

                })


            4) 调用连接方法

                connection.connect();


        3 nodejs操作数据库

            a) 定义sql语句

                const sqlStr = 'sql语句';


            b) 执行数据库操作

                connection.query(sqlStr, (err, data) => {

                    if (err) {

                        throw err

                    } else {

                        // 根据data的各种情况判断

                    }

                })




    A 创建git共享仓库

    B  公共导航的抽取

        iframe 标签

        <iframe name="iframe的名称" src="引入的需要在这个标签里面显示的页面url" width="宽度" height="高度">

            // src引入的页面  会在这里显示

        </iframe>


    C) 添加账号功能实现 (***)

        1 前端-填写表单,点击添加按钮 发送ajax给后端(把用户账号的数据发送给后端)

            a) 用户填写表单 通过所有的前端验证 收集表单的数据(双向绑定)

            b) 把这些数据 通过ajax的post方式,发送给后端


        2 后端-接收请求,接收数据

            a) get方式使用 req.query  post方式使用req.body


        3 后端-把数据的数据 存入数据库

            a) 构造sql语句(插入数据的sql)

                const sqlStr "sql的增删改查的语法"

            b) 执行sql语句  

                connection.query(sqlStr, (err, data) => {   })


        4 后端-根据存入数据库的结果 返回给前端一些信息

成功:res.send({"errcode":1, "msg":"添加成功"})

失败:res.send({"errcode":0, "msg":"添加失败"})


        5 前端-根据后端返回的信息 判断

成功:》》弹出添加成功》》跳转到账号列表

失败:弹出添加失败,呵呵!


    D) 用户列表功能的实现 (***)

        1 前端-在生命周期 created 里面 发送ajax 去请求所有用户列表的数据

        2 后端-接收这个请求

        3 后端-构造sql语句 去数据库查询所有数据

        4 后端-根据查询结果判断

如果有错抛出错误

否则直接把查询的所有数据响应给前端

        5 前端-接收到后端返回的所有数据,赋值给tableData, 触发页面表格渲染

            a)注意: 需要保留this的指向  ajax里面的this不指向vue实例了。


    E) 用户删除功能的实现(***)

        1 前端-点击删除按钮 触发一个函数 把 id 传入

        2 前端-在这个函数里面 发送一个删除的请求 把 id 传给后端

        3 后端-接收这个请求,接收id

        4 后端-构造sql,以id为条件 执行删除

            a)const sqlStr = 'delete from users where id=10'

        5 后端-执行sql语句(单条删除操作)  

            a)如果有错 抛出错误

            b)如果没有错 根据结果判断

                i) 如果受影响的行数 > 0, 返回给前端一些信息(删除成功的信息)

                    res.send({"errcode":1, "msg":"删除成功!"})


                ii) 否则 返回给前端一些信息(删除失败的信息)

                    res.send({"errcode":0, "msg":"删除失败!"})


        6 前端-接收后端返回的数据,判断

            a) 如果成功  》》弹 出删除成功  》》刷 新页面

            b) 如果失败  弹出删除失败


DAY03:需求

    A 修改功能的实现

准备: 先写一个修改页面

        1 把原来的这一条数据回显出来

            1) 前端-点击修改按钮 触发一个函数 传入id

            2) 前端-在这个函数里面,直接跳转到修改页面,把id传过去

            3) 前端-在修改页面的生命周期 created里面, 获取id, 里面发送ajax,把这个id发送给后端

            4) 后端-接收请求,接收id

            5) 后端-根据id构造sql,去数据库把这条数据查询出来

                a)如果有错 抛出错误

                b)否则 直接把根据id查询出来的这一条数据(也就是要修改的数据)发送给前端


            6) 前端-接收数据,一一对应的,回填在修改页面的表单里面。


        2 把修改后的新数据,保存回去(根据原来的id)

            1) 前端-点击修改按钮,触发 submitForm

            2) 前端-如果前端所有验证通过,收集用户填写的新数据 和 一个原来的id

            3) 前端-发送ajax请求,这这些新数据 和 一个原来的id 一起发送给后端

            4) 后端-接收前端发送的修改后的新数据 和 一个原来的id

            5) 后端-以id为条件 构造sql语句(修改操作)

                a) update users set 字段名1=新的值1, 字段名2=新的值2 where id = 接收到的id


            6) 后端-执行修改的sql语句,根据修改的结果 判断 返回给前端一些信息

                a)如果有错 抛出错误

                b)如果没有错 根据修改的结果数据判断

如果成功:返回成功的数据对象给前端

如果失败:返回失败的数据对象给前端

            7) 前端-接收后端返回的信息 判断

                a)成功: 》》弹 出对应的提示信息 》》跳 转到用户列表页面

                b)失败: 弹出对应的提示信息


    B 批量删除的实现

        1 前端-给取消选中绑定事件 在事件里面实现取消选择

        2 前端-给整个table绑定选中就会改变的selection-change事件类型,

触发一个函数handleSelectionChange,自定把选中的数据传入函数里面

        3 前端-在这个函数里面,接收到这个值,把他赋值给一个属性(vue实例)

             this.multipleSelection = val;

        4 前端-给批量删除上绑定事件,在事件里面,获取 this.multipleSelection(里面保存了被勾选的数据)

        5 前端-遍历数据  this.multipleSelection 把里面的id 获取出来,放入一个数组 (被选中的数据的id)

        6 前端-构造ajax 把这些被选中的id们(数组)发送给后端

        7 后端-接收请求 接收这个包含id们 的数组

        8 后端-构造sql语句(in 子句),执行sql语句删除

            1) 如果有错 抛出错误

            2)否则 根据删除的结果数据 data 判断

                a) 如果 成功(受影响行数 > 0) 返回成功的数据对象给前端

                b) 否则 返回失败的数据对象给前端

        9 前端-接收后端响应回来的数据  判断

            1)如果成功 》》弹 出对应的提示信息   》》刷 新页面

            2)如果失败 弹出对应的提示信息

    C 登录功能实现

        1 检查用户身份(用户名和密码是否正确,是否在数据库里面存在)

            1)前端-前端验证通过,发送ajax请求给后端,把用户名和密码发送给后端

            2)后端-接收请求,接收用户名和密码

            3)后端-以用户名和密码 且 的关系,构造sql语句 执行sql语句查询数据库,判断

                a)如果有错 抛出错误

                b)否则 看数据是否存在 判断

如果存在返回成功(存在)的数据对象

否则返回失败(不存在)的数据对象

            4)前端-根据后端响应的数据,判断

                a)如果存在 》》弹 登录成功 》》跳 转到后台系统首页

                b)如果不存在 弹 出请检查用户名或密码


        2 检查用户是否已经登录(cookie)

            cookie: 储存在用户本地终端(浏览器)上的数据

说明:就是由服务器端(后端)创建存储在浏览器(客户端、前端)上的一种追踪用户的技术。


                nodejs操作cookie

增:设置:res.cookie(key, value);  // res.cookie('username', 'admin')

删:清除cookie: res.clearCookie(key) // res.clearCookie('username')

改:修改cookie: res.cookie(key, newValue) // res.cookie('username', 'guest');

查:获取cookie: req.cookies.key  // req.cookies.username;

具体步骤:

                1)后端-如果登录成功 设置cookie (在登录成功的路由里面设置)


                2)前端-每一个页面 都发送一个请求 (为了检测cookie是否存在)

                    <script src="/users/checkIsLogin"></script>


                3)后端-接收这个请求 获取cookie(从浏览器),检测是否存在

如果存在不作出任何操作(需要返回一些信息)

如果不存在返回弹窗请登录以后再操作跳转到登录页面




        3 退出登录功能

            1) 前端-点击退出系统,通过a标签发送一个get方式的请求

            2) 后端-接收请求,清除cookie, 弹出对应提示, 跳转到登录页面

DAY04需求:

    A 修改密码功能实现

        1 验证旧密码

            1)前端-写一个修改密码页面,实现前端的表单验证

            2)前端-自定义旧密码的验证规则(旧密码正不正确 前端是不知道的 需要发送ajax去验证)

            3)前端-在自定义的函数里面 直接发送ajax 把输入的旧密码的值 发送给后端

            4)后端-接收旧密码,从cookies获取当前登录用户的id。

            5)后端-根据id为条件,把当前用户数据查询出来,用查询出来的密码 和 接收到的旧密码比较

                a)如果有错 抛出错误

                b) 否则 判断

如果成功:返回成功的数据对象给前端

如果失败:返回失败的数据对象给前端

            6)前端-根据后端响应结果判断

如果错误

使用callback(new Error('错误信息'))

如果正确

                    callback()

        2 保存新密码(执行修改)

            1) 前端-点击保存按钮 发送ajax 把新密码发送给后端

            2)后端-接收新密码 从cookie获取 id

            3)后端-以id为条件 构造sql语句(修改密码)

            4)后端-执行sql语句,根据结果判断

如果成功:

清除cookie

返回成功的数据对象给前端

            5)前端-根据后端响应的数据,判断

如果成功:》》填充修改密码成功》》跳转到登录页面


    B 分页功能实现

分页思路分析:(后端分页)

后端分页需要什么条件呢?

                1) 每页显示多少条 pageSize ? 从前端传过来,用户选择了以后就传过来

                2)当前在第几页呢 currentPage ? 从前端传过来  用户点了哪个页码 就传给后端

                3)后端查询所有数据 计算数据的总条数 发送给前端

                4) 把当前用户想要的 对应页面的 数据 查询出来 发送给前端

                    sql查询条件:

                    n = (currentPage - 1)*pageSize

                    select * from users limit(n, pageSize)


结论:(*****)

前端需要给后台发送什么?

                    a) 页面尺寸pageSize

                    b) 当前页面 currentPage


后端需要给前端返回什么?

                    a)数据总条数据 (前端需要用来计算页码有多少)

                    b)对应页面的数据(点击第1页 就只返回第 1 页的数据 )



工作中:(常见分页)

前端:只需要给后端发送当前页码

后端:自己构造sql 把对应当前页码的数据返回。


分页步骤:

            1 前端-使用分页组件 在对应的位置写上(账号列表页面)

            2 前端-获取需要发送给后端的参数: pageSize(页面尺寸)  currentPage(当前页)

            3 前端-改造页面里面请求数据的函数 getAllUsers

需要把前端的参数传入这个函数一起发送给后端(改成按照分页请求数据 而不是一次请求所有数据)


            4 后端-接收请请求,接收参数 pageSize 和 currentPage

            5 后端-构造sql 查询全局数据,计算出数据总条数

                    const sqlStr = 'select * from users';

                    connection.query(sqlStr, (err, data) => {

                        if (err) {

                            throw err

                        } else {

                           // 计算数据总条数

                           let  totalcount = data.length;

                        }

                    })

            6 后端-构造sql 排序然后 按照分页的条件查询 查询出对应页码的数据

                let n = (currentPage - 1)*pageSize

                sqlStr += ` order by ctime desc limit ${n}, ${pageSize}`

                connection.query(sqlStr, (err, data) => {

                    if (err) {

                        throw err

                    } else {

                        // 按照分页查询的数据的结果(前端传过来哪一页就是对应页码的数据)

                        let pageData = data;

                        // 把数据总条数 和 对应页码的数据 一起发送给前端

                        res.send({"totalcount": totalcount, "pageData": pageData})

                    }

                })


            7 前端-接收数据(数据是一个对象: {"totalcount":数据总条数, "pageData":对应当前页码的数据})

把数据赋值给data里面 对应的字段


DAY05需求:

    A 分页功能完善

    B 登录显示当前登录用户功能完善

    C 商品列表模块商品添加实现

    D 商品管理模块实现

    E 高级查询

        1 前端-点击查询按钮,触发一个函数, 在这个函数里面,

收集查询的两个参数(分类名称 和 关键字(商品名称 或 条形码)) 发送给后端


        2 前端-发送ajax 把 分类名称 和 关键字 发送给后端


        3 后端-接收请求,接收参数(分类名称 和 关键字)


        4 后端-根据参数 构造sql语句 按照条件查询 ? 怎么写sql? (****)


        5 后端-执行sql,把查询的结果返回给前端

        6 前端接收返回结果 赋值给 tableData, 渲染表格

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,893评论 2 89
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,389评论 25 707
  • 2018年4月29日 盘点一下自己本周收获: 1. 享受早起 一日之计在于晨,一晨之计在于起。现在每天都能比闹钟响...
    向丽泡妈阅读 46评论 0 0
  • 东边日出西边雨, 花枝离架水越渠, 心安似雪轻飞落, 任他几遇不复预。
    JonWang_js阅读 158评论 0 0