[TOC]

day03 Vue&书城项目第一阶段

第一章 Vue

1. 学习目标

  • 了解什么是框架
  • 了解什么是Vue
  • 掌握Vue的基本语法
  • 了解Vue的生命周期

2. 内容讲解

2.1 什么是框架

任何编程语言在最初的时候都是没有框架的,后来随着在实际开发过程中不断总结『经验』,积累『最佳实践』,慢慢的人们发现很多『特定场景』下的『特定问题』总是可以『套用固定解决方案』。
于是有人把成熟的『固定解决方案』收集起来,整合在一起,就成了『框架』。
在使用框架的过程中,我们往往只需要告诉框架『做什么(声明)』,而不需要关心框架『怎么做(编程)』。
对于Java程序来说,我们使用框架就是导入那些封装了『固定解决方案』的jar包,然后通过『配置文件』告诉框架做什么,就能够大大简化编码,提高开发效率。我们使用过的junit其实就是一款单元测试框架。
而对于JavaScript程序来说,我们使用框架就是导入那些
封装了『固定解决方案』的『js文件』,然后在框架的基础上编码。
用洗衣服来类比框架:
典型应用场景:洗衣服
输入数据:衣服、洗衣液、水
不使用框架:手洗
使用框架:使用洗衣机,对人来说,只需要按键,具体操作是洗衣机完成的。人只是告诉洗衣机做什么,具体的操作是洗衣机完成的。
实际开发中使用框架时,我们也主要是告诉框架要做什么,具体操作是框架完成的。

2.2 Vue的简介

2.2.1 Vue的作者介绍

在为AngularJS工作之后,Vue的作者尤雨溪开Vue.js。他声称自己的思路是提取Angular中自己喜欢的部分,构建出一款相当轻量的框架。
Vue最早发布于2014年2月。作者在Hacker News、Echo JS与 Reddit的JavaScript版块发布了最早的版本。一天之内,Vue 就登上了这三个网站的首页。
Vue是Github上最受欢迎的开源项目之一。同时,在JavaScript框架/函数库中, Vue所获得的星标数已超过React,并高于Backbone.js、Angular 2、jQuery等项目。

2.2.2 Vue的官网介绍

Vue (读音 /vjuː/,类似于view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
官网地址:https://cn.vuejs.org/

2.3 准备Vue.js环境

  1. Vue框架的js文件获取
  1. 创建空vue.js文件,将官网提供的vue.js文件的内容复制粘贴到本地vue.js文件中

2.4 Vue的入门案例

  1. 创建工程,导入vue.js文件放入工程的js文件夹中
  2. 创建demo01.html(引入vuejs,定义div,创建vue实例)

<!DOCTYPE html>








{{message}}






2.5 声明式渲染

2.5.1 概念

2.5.1.1 声明式

『声明式』是相对于『编程式』而言的。

  • 声明式:告诉框架做什么,具体操作由框架完成
  • 编程式:自己编写代码完成具体操作

2.5.1.2 渲染

day03_VUE&书城第一阶段 - 图1

上图含义解释:

  • 蓝色方框:HTML标签
  • 红色圆形:动态、尚未确定的数据
  • 蓝色圆形:经过程序运算以后,计算得到的具体的,可以直接在页面上显示的数据、
  • 渲染:程序计算动态数据得到具体数据的过程

2.5.2 案例讲解

HTML代码

{{message}}

vue代码
// 1.创建一个JSON对象,作为new Vue时要使用的参数
var argumentJson = {

// el用于指定Vue对象要关联的HTML元素。el就是element的缩写<br />    // 通过id属性值指定HTML元素时,语法格式是:#id<br />    "el":"#app",

// data属性设置了Vue对象中保存的数据<br />    "data":{<br />        "message":"Hello Vue!"<br />    }<br />};

// 2.创建Vue对象,传入上面准备好的参数
var app = new Vue(argumentJson);
day03_VUE&书城第一阶段 - 图2
images

2.5.3 查看声明式渲染的响应式效果

day03_VUE&书城第一阶段 - 图3

通过验证Vue对象的『响应式』效果,我们看到Vue对象和页面上的HTML标签确实是始终保持着关联的关系,同时看到Vue在背后确实是做了大量的工作。

2.6 绑定元素属性

2.6.1 基本语法

v-bind:HTML标签的原始属性名

2.6.2 案例代码

HTML代码




<!-- 同样的表达式,在标签体内通过{{}}告诉Vue这里需要渲染; --><br />    <!-- 在HTML标签的属性中,通过v-bind:属性名="表达式"的方式告诉Vue这里要渲染 --><br />    <p>{{vueValue}}</p><br /></div><br />**Vue代码**<br />// 创建Vue对象,挂载#app这个div标签<br />var app = new Vue({<br />    "el":"#app",<br />    "data":{<br />        "vueValue":"太阳当空照"<br />    }<br />});<br />**扩展:**<br />v-bind:属性名="属性值"可以简写成 :属性名="属性值"<br />

2.7 双向数据绑定

2.7.1 提出问题

day03_VUE&书城第一阶段 - 图4
images
而使用了双向绑定后,就可以实现:页面上数据被修改后,Vue对象中的数据属性也跟着被修改。

2.7.2 案例代码

HTML代码




<p>{{vueValue}}</p><br /></div><br />**Vue代码**<br />// 创建Vue对象,挂载#app这个div标签<br />var app = new Vue({<br />    "el":"#app",<br />    "data":{<br />        "vueValue":"太阳当空照"<br />    }<br />});<br />**页面效果**<br />p标签内的数据能够和文本框中的数据实现同步修改:<br />![](https://cdn.nlark.com/yuque/0/2021/png/25621085/1639802873021-bda8ce1d-f174-4075-853a-0ee36e8c7e16.png#)

2.7.3 动态绑定样式表




我爱你刘亦菲





扩展:

  1. v-model:value=”值” 可以简写成 v-model=”值”
  2. trim修饰符

实际开发中,要考虑到用户在输入数据时,有可能会包含前后空格。而这些前后的空格对我们程序运行来说都是干扰因素,要去掉。在v-model后面加上.trim修饰符即可实现。

Vue会帮助我们在文本框失去焦点时自动去除前后空格。

2.8 条件渲染

根据Vue对象中,数据属性的值来判断是否对HTML页面内容进行渲染。

2.8.1 v-if

HTML代码


if


day03_VUE&书城第一阶段 - 图5
day03_VUE&书城第一阶段 - 图6

Vue代码
var app = new Vue({
“el”:”#app”,
“data”:{
“flag”:true
}
});

2.8.2 v-if和v-else

HTML代码


if/else


day03_VUE&书城第一阶段 - 图7
day03_VUE&书城第一阶段 - 图8

Vue代码
var app02 = new Vue({
“el”:”#app02”,
“data”:{
“flag”:true
}
});

2.8.3 v-show

HTML代码


v-show


day03_VUE&书城第一阶段 - 图9

Vue代码
var app03 = new Vue({
“el”:”#app03”,
“data”:{
“flag”:true
}
});

2.9 列表渲染

2.9.1 迭代一个简单的数组

HTML代码






  • {{fruit}}



Vue代码
var app01 = new Vue({
“el”:”#app01”,
“data”:{
“fruitList”: [
“apple”,
“banana”,
“orange”,
“grape”,
“dragonfruit”
]
}
});

2.9.2 迭代一个对象数组

HTML代码















编号 姓名 年龄 专业
{{employee.empId}} {{employee.empName}} {{employee.empAge}} {{employee.empSubject}}


Vue代码
var app = new Vue({
“el”:”#app”,
“data”:{
“employeeList”:[
{
“empId”:11,
“empName”:”tom”,
“empAge”:111,
“empSubject”:”java”
},
{
“empId”:22,
“empName”:”jerry”,
“empAge”:222,
“empSubject”:”php”
},
{
“empId”:33,
“empName”:”bob”,
“empAge”:333,
“empSubject”:”python”
}
]
}
});

2.10 事件驱动

2.10.1 案例一: 字符串顺序反转

HTML代码


{{message}}

<!-- v-on:事件类型="事件响应函数的函数名" --><br />    <button v-on:click="reverseMessage">Click me,reverse message</button><br /></div><br />**Vue代码**<br />var app = new Vue({<br />    "el":"#app",<br />    "data":{<br />        "message":"Hello Vue!"                <br />    },<br />    "methods":{<br />        "reverseMessage":function(){<br />            this.message = this.message.split("").reverse().join("");<br />        }<br />    }<br />});<br />

2.10.2 案例二:获取鼠标移动时的坐标信息

HTML代码



{{position}}



Vue代码
var app = new Vue({
“el”:”#app”,
“data”:{
“position”:”暂时没有获取到鼠标的位置信息”
},
“methods”:{
“recordPosition”:function(event){
this.position = event.clientX + “ “ + event.clientY;
}
}
});
扩展:
v-on:事件名=”函数”可以简写成@事件名=”函数”

2.10.3 取消控件的默认行为

2.10.3.1 控件默认行为
  • 点超链接会跳转页面
  • 点表单提交按钮会提交表单

本来控件的默认行为是天经地义就该如此的,但是如果我们希望点击之后根据我们判断的结果再看是否要跳转,此时默认行为无脑跳转的做法就不符合我们的预期了。

2.10.3.2 取消方式

调用事件对象preventDefault()方法。
超链接举例
HTML代码:
超链接
JavaScript代码:
document.getElementById(“anchor”).onclick = function() {
console.log(“我点击了一个超链接”);
//event.preventDefault();
}
表单提交按钮举例
HTML代码:




JavaScript代码:
document.getElementById(“submitBtn”).onclick = function() {
console.log(“我点击了一个表单提交按钮”);
event.preventDefault();
}

2.10.4 阻止事件冒泡

day03_VUE&书城第一阶段 - 图10
images
图中的两个div,他们的HTML标签是:




点击里面的div同时也等于点击了外层的div,此时如果两个div上都绑定了单击响应函数那么就都会被触发:
document.getElementById(“outterDiv”).onclick = function() {
console.log(“外层div的事件触发了”);
}

document.getElementById(“innerDiv”).onclick = function() {
console.log(“内层div的事件触发了”);
}
所以事件冒泡就是一个事件会不断向父元素传递,直到window对象。
如果这不是我们想要的效果那么可以使用事件对象的stopPropagation()函数阻止。
document.getElementById(“innerDiv”).onclick = function() {
console.log(“内层div的事件触发了”);

event.stopPropagation();<br />}<br />

2.10.5 Vue事件修饰符

对于事件修饰符,Vue官网的描述是:
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

2.10.5.1 取消控件的默认行为

控件的默认行为指的是:

  • 点击超链接跳转页面
  • 点击表单提交按钮提交表单

实现这个需求使用的Vue事件修饰符是:.prevent
超链接




2.10.5.2 取消事件冒泡

实现这个需求使用的Vue事件修饰符是:.stop



2.11 侦听属性

2.11.1 提出需求

尊姓:{{firstName}}


大名:{{lastName}}


尊姓:

大名:

全名:{{fullName}}



在上面代码的基础上,我们希望firstName或lastName属性发生变化时,修改fullName属性。此时需要对firstName或lastName属性进行『侦听』。
具体来说,所谓『侦听』就是对message属性进行监控,当firstName或lastName属性的值发生变化时,调用我们准备好的函数。
##### 2.11.2 Vue代码 在watch属性中声明对firstName和lastName属性进行『侦听』的函数:
var app = new Vue({
“el”:”#app”,
“data”:{
“firstName”:”jim”,
“lastName”:”green”,
“fullName”:”jim green”
},
“watch”:{
“firstName”:function(inputValue){
this.fullName = inputValue + “ “ + this.lastName;
},
“lastName”:function(inputValue){
this.fullName = this.firstName + “ “ + inputValue;
}
}
});
#### 2.12 案例练习 ##### 2.12.1 功能效果演示 day03_VUE&书城第一阶段 - 图11 ##### 2.12.2 任务拆解 - 第一步:显示表格 - 第二步:显示四个文本框 - 第三步:创建一个p标签用来显示用户在文本框中实时输入的内容 - 第四步:点击添加记录按钮实现记录的添加 ##### 2.12.3 第一步:显示表格 HTML标签
















编号 姓名 年龄 专业 操作
{{user.empId}} {{user.empName}} {{user.empAge}} {{user.empSubject}}


Vue代码
var vue = new Vue({
“el”:”#app”,
“data”:{
“userList”:[
{
“empId”:11,
“empName”:”张三”,
“empAge”:20,
“empSubject”:”Java”
},{
“empId”:22,
“empName”:”李四”,
“empAge”:21,
“empSubject”:”PHP”
},{
“empId”:33,
“empName”:”王五”,
“empAge”:22,
“empSubject”:”C++”
}
]
}
});

##### 2.12.4 第二步:显示四个文本框 HTML标签
















编号 姓名 年龄 专业 操作
{{user.empId}} {{user.empName}} {{user.empAge}} {{user.empSubject}}

编号

姓名

年龄

专业




Vue代码

测试是否正确的方式是:在控制台尝试修改Vue对象的数据属性值:
day03_VUE&书城第一阶段 - 图12 ##### 2.12.5 第四步:点击添加记录按钮 往表格中添加数据其实就是将表单上输入的数据this.user加入到数组this.userList中
添加完之后清空表单数据,其实就是设置this.user = {}
HTML标签
















编号 姓名 年龄 专业 操作
{{user.empId}} {{user.empName}} {{user.empAge}} {{user.empSubject}}

编号

姓名

年龄

专业




Vue代码

##### 2.12.6 第五步: 点击每行的删除按钮删除该行数据 删除该行数据其实就是根据下标从数组this.userList中移除元素
HTML代码
















编号 姓名 年龄 专业 操作
{{user.empId}} {{user.empName}} {{user.empAge}} {{user.empSubject}}

编号

姓名

年龄

专业




Vue代码
#### 2.13 Vue的生命周期 ##### 2.13.1 概念 在我们各种语言的编程领域中,『生命周期』都是一个非常常见的概念。一个对象从创建、初始化、工作再到释放、清理和销毁,会经历很多环节的演变。比如我们在JavaSE阶段学习过线程的生命周期,今天学习Vue对象的生命周期,将来还要学习Servlet、Filter等Web组件的生命周期。
##### 2.13.2 Vue对象的生命周期 day03_VUE&书城第一阶段 - 图13
images
##### 2.13.3 生命周期钩子函数 Vue允许我们在特定的生命周期环节中通过钩子函数来加入我们的代码。

{{message}}




new Vue({
“el”:”#app”,
“data”:{
“message”:”hello”
},
“methods”:{
“changeValue”:function(){
this.message = “new hello”;
}
}, // 1.实例创建之前
“beforeCreate”:function(){
console.log(“beforeCreate:”+this.message);
}, // 2.实例创建完成
“created”:function(){
console.log(“created:”+this.message);
}, // 3.数据挂载前
“beforeMount”:function(){
console.log(“beforeMount:”+document.getElementById(“content”).innerText);
}, // 4.数据已经挂载
“mounted”:function(){
console.log(“mounted:”+document.getElementById(“content”).innerText);
}, // 5.数据更新前
“beforeUpdate”:function(){
console.log(“beforeUpdate:”+document.getElementById(“content”).innerText);
}, // 6.数据更新之后
“updated”:function(){
console.log(“updated:”+document.getElementById(“content”).innerText);
}
});
## 第二章 书城项目第一阶段 ### 1. 学习目标 - 实现登录表单校验 - 实现注册表单校验 ### 2. 内容讲解 #### 2.1 准备工作 创建目录后,把一整套现成的前端页面复制到新建的目录下,然后把vue.js文件复制到script目录下。
#### 2.2 登录页面的表单验证 ##### 2.2.1 规则设定 - 用户名非空 - 密码非空 ##### 2.2.2 在login.html页面中加入Vue的环境
##### 2.2.3 案例思路 day03_VUE&书城第一阶段 - 图14 ##### 2.2.4 代码实现 HTML代码

<div class="login_banner"><br />        <div id="l_content"><br />            <span class="login_word">欢迎登录</span><br />        </div>

    <div id="content"><br />            <div class="login_form"><br />                <div class="login_box"><br />                    <div class="tit"><br />                        <h1>尚硅谷会员</h1><br />                    </div><br />                    <div class="msg_cont"><br />                        <b></b><br />                        <span class="errorMsg" style="color: red">{{errorMessage}}</span><br />                    </div><br />                    <div class="form"><br />                        <form action="login_success.html"><br />                            <label>用户名称:</label><br />                            <input<br />                                   class="itxt"<br />                                   type="text"<br />                                   placeholder="请输入用户名"<br />                                   autocomplete="off"<br />                                   tabindex="1"<br />                                   name="username"<br />                                   id="username"<br />                                   v-model="username"<br />                                   /><br />                            <br /><br />                            <br /><br />                            <label>用户密码:</label><br />                            <input<br />                                   class="itxt"<br />                                   type="password"<br />                                   placeholder="请输入密码"<br />                                   autocomplete="off"<br />                                   tabindex="1"<br />                                   name="password"<br />                                   id="password"<br />                                   v-model="password"<br />                                   /><br />                            <br /><br />                            <br /><br />                            <input type="submit" value="登录" id="sub_btn" @click="loginCheck"/><br />                        </form><br />                        <div class="tit"><br />                            <a href="regist.html">立即注册</a><br />                        </div><br />                    </div><br />                </div><br />            </div><br />        </div><br />    </div><br />    <div id="bottom"><br />        <span><br />            尚硅谷书城.Copyright &copy;2015<br />        </span><br />    </div><br /></div><br />**Vue代码**<br />var vue = new Vue({<br />    "el":"#app",<br />    "data":{<br />        "username":"",<br />        "password":"",<br />        "errorMessage":""<br />    },<br />    "methods":{<br />        loginCheck(){<br />            //判断用户名和密码是否为空<br />            if (this.username != "") {<br />                if (this.password == ""){<br />                    //就要阻止表单提交<br />                    event.preventDefault()<br />                    //加入提示功能<br />                    this.errorMessage = "密码不能为空"<br />                }<br />            }else {<br />                //就要阻止表单提交<br />                event.preventDefault()<br />                //加入提示功能<br />                this.errorMessage = "用户名不能为空"<br />            }<br />        }<br />    }<br />});<br />

2.3 注册页面的表单验证

2.3.1 在注册页面(register.html)中引入vue



HTML代码


<div class="login_banner"><br />        <div class="register_form"><br />            <h1>注册尚硅谷会员</h1><br />            <form action="regist_success.html"><br />                <div class="form-item"><br />                    <div><br />                        <label>用户名称:</label><br />                        <input type="text" placeholder="请输入用户名" v-model="username" @blur="checkUsername"/><br />                    </div><br />                    <span style="color: red">{{usernameErrorMessage}}</span><br />                </div><br />                <div class="form-item"><br />                    <div><br />                        <label>用户密码:</label><br />                        <input type="password" placeholder="请输入密码" v-model="password"/><br />                    </div><br />                    <span style="color: red">{{passwordErrorMessage}}</span><br />                </div><br />                <div class="form-item"><br />                    <div><br />                        <label>确认密码:</label><br />                        <input type="password" placeholder="请输入确认密码" v-model="passwordConfirm"/><br />                    </div><br />                    <span style="color: red">{{confirmErrorMessage}}</span><br />                </div><br />                <div class="form-item"><br />                    <div><br />                        <label>用户邮箱:</label><br />                        <input type="text" placeholder="请输入邮箱" v-model="email"/><br />                    </div><br />                    <span style="color: red">{{emailErrorMessage}}</span><br />                </div><br />                <div class="form-item"><br />                    <div><br />                        <label>验证码:</label><br />                        <div class="verify"><br />                            <input type="text" placeholder="" v-model="code"/><br />                            <img src="../../static/img/code.bmp" alt="" /><br />                        </div><br />                    </div><br />                    <!--<span>请输入正确的验证码</span>--><br />                </div><br />                <button class="btn" @click="registerCheck">注册</button><br />            </form><br />        </div><br />    </div><br />    <div id="bottom"><br />        <span><br />            尚硅谷书城.Copyright &copy;2015<br />        </span><br />    </div><br /></div><br />**Vue代码**<br /><script><br />    var vue = new Vue({<br />        "el":"#app",<br />        "data":{<br />            "username":"",//用户名<br />            "password":"",//密码<br />            "passwordConfirm":"",//确认密码<br />            "email":"",//邮箱<br />            "code":"",//验证码<br />            "usernameErrorMessage":"",<br />            "passwordErrorMessage":"",<br />            "confirmErrorMessage":"",<br />            "emailErrorMessage":""<br />        },<br />        "methods":{<br />            checkUsername(){<br />                //校验用户名是否符合规则<br />                //1. 编写一个正则表达式去描述这个规则<br />                var usernameRegExp = /^[A-Za-z0-9_]{6,12}$/;<br />                //2. 使用正则表达式校验用户名输入框里面的内容:this.username<br />                if (!usernameRegExp.test(this.username)) {<br />                    //校验不通过<br />                    this.usernameErrorMessage = "用户名必须是5-8位的数字、字母或者下划线"<br />                }else {<br />                    //符合规则了,就重新设置提示信息为空<br />                    this.usernameErrorMessage = ""<br />                }<br />            },<br />            registerCheck(){<br />                //注册校验的方法<br />                //1. 校验用户名<br />                //1.1 编写一个正则表达式去描述这个规则<br />                var usernameRegExp = /^\w{6,12}$/;<br />                //1.2 校验用户名是否符合规则<br />                if (!usernameRegExp.test(this.username)) {<br />                    //用户名不符合规则,那么就阻止默认事件<br />                    event.preventDefault()

                this.usernameErrorMessage = "用户名必须是5-8位的数字、字母或者下划线"<br />                    return<br />                }<br />                //2. 校验密码<br />                //2.1 编写一个正则表达式去描述密码校验的规则<br />                var passwordRegExp = /^[A-Za-z0-9_]{6,10}$/;<br />                //2.2 使用正则表达式校验密码<br />                if (!passwordRegExp.test(this.password)) {<br />                    //密码不符合规则,那么就阻止默认事件<br />                    event.preventDefault()

                this.passwordErrorMessage = "密码必须是6-10位的数字、字母或者下划线"<br />                    return<br />                }else {<br />                    this.passwordErrorMessage = ""<br />                }<br />                //3. 校验确认密码<br />                //3.1 就是对比确认密码输入框的内容和密码输入框的内容是否一样<br />                if (this.password != this.passwordConfirm) {<br />                    event.preventDefault()<br />                    this.confirmErrorMessage = "两次输入的密码必须一致"<br />                    return<br />                }else {<br />                    this.confirmErrorMessage = ""<br />                }<br />                //4. 校验邮箱格式<br />                var emailRegExp = /^[a-zA-Z0-9_\.-]+@([a-zA-Z0-9-]+[\.]{1})+[a-zA-Z]+$/;<br />                if(!emailRegExp.test(this.email)){<br />                    event.preventDefault()

                this.emailErrorMessage = "邮箱格式不正确"<br />                    return<br />                }else {<br />                    this.emailErrorMessage = ""<br />                }<br />            }<br />        }<br />        /*"watch":{<br />        //对用户名添加监听<br />        "username":function (inputValue) {<br />          //校验用户名是否符合规则<br />          //1. 编写一个正则表达式去描述这个规则<br />          var usernameRegExp = /^[A-Za-z0-9_]{5,8}$/;<br />          //2. 使用正则表达式校验用户名输入框里面的内容:inputValue<br />          if (!usernameRegExp.test(inputValue)) {<br />            //校验不通过<br />            this.usernameErrorMessage = "用户名必须是5-8位的数字、字母或者下划线"<br />          }else {<br />            //符合规则了,就重新设置提示信息为空<br />            this.usernameErrorMessage = ""<br />          }<br />        }<br />      }*/<br />    });<br /></script>