1.Vue概述
目标:MVVM模式应用特点,和Vue概念
小结:MVVM通过视图与模型的双向绑定,简化前端操作。Vue是一款前端渐进式框架,可以提高前端开发的效率。
概念:Vue 是一套用于构建用户界面的渐进式框架,自底层向上应用,Vue的核心库只关注视图层,容易入门,可以和第三方库或者已有的项目进行整合,可以做复杂的单页应用。简单的说,vue是一套前端的开发框架,vue是目前三大主流的框架之一,其他两个框架是:React、Angular。
MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中,而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间如何互相影响的:
- 只要Model发送了改变,View上自然就会表现出来。
- 当用户修改了View,Model中的数据也会跟着改变。
2.搭建示例工程
目标:使用IDEA创建示例工程并在工程中通过npm安装下载vue.js
分析:
vue是一个前端框架,其实也是一个js文件,下载vue.js文件并在页面中引入该js文件。
vue.js的下载方式:
- 可以引用在线的vue.js
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
-
可以离线下载vue.js,在项目中引用它
-
npm包资源管理器,可以下载vue.js
小结:使用npm方式安装vue模块:nvm和node安装
#初始化
npm init -y
#下载vue模块
npm install vue --save
3. 演示双向绑定与事件处理
目标:创建demo.html页面并初始化Vue实例,通过console修改Vue数据实现双向绑定效果和创建按钮实现点击即自增(演示Vue的效果)v-model代表双向绑定
分析:
- 创建页面,初始化vue
- {{}}获取显示数据
- v-model实现双向绑定
- v-on演示事件处理
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="num"><button v-on:click="num++">点击</button>
<h2>{{name}}</h2>是费琪ta爹共有{{num}}个爹
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
name:"海林",
num:1
}
});
</script>
</body>
</html>
4.Vue实例生命周期及钩子函数
目标:了解Vue实例生命周期,生命周期的钩子函数及created函数常用场景
分析:每个Vue实例在被创建时都要经过一系列的初始化过程:创建实例,装载模板,渲染模板等,Vue为每个生命周期中的每个状态都设置了钩子函数(监听函数),每当Vue实体处于不同的生命周期时,对应的函数就会被触发调用,不能用箭头函数来定义一个生命周期方法。
在创建Vue实例的时候可以指定模板Iid,数据和方法;如果要在实例化,模板渲染的过程中需要执行一些其他操作的话,那么可以使用钩子函数。
小结:钩子函数会在vue实例的各个生命周期阶段自动调用;具体有:beforeCreate,created,beforeMount,mounted,updated,beforeUpdate,destroyed,beforeDestroy。created钩子函数常用场景:用于初始化数据。钩子函数不要使用箭头函数方式编写
5.插值、v-text和v-html
目标:插值使用场景和要求,v-text和v-html的作用
小结:
插值可以使用在有需要显示vue实例数据的地方,可以在插值表达式中调用实例的数据属性和函数。
x-text和v-html的作用:可以将数据在模板中进行显示;
区别:v-html会对内容中出现的html标签进行渲染,而v-text会将内容当做普通文本输出到元素里面。
6.指令v-model的使用
目标:
分析:v-text和v-html可以看做是单向绑定,数据影响了视图渲染,但反过来就不行。v-model是双向绑定,视图(view)和模型(model)之间会互相影响。既然是双向绑定,视图一定是可以修改数据的,这样就限定了视图的元素类型,v-model的可以使用元素有:input,select,textarea,checkbox,radio,components(vue中的自定义组件),除了最后一项,都是表单的输入项。
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="checkbox" value="Java" v-model="languages">Java<br>
<input type="checkbox" value="Python" v-model="languages">Python<br>
<input type="checkbox" value="Swift" v-model="languages">Swift<br>
<h2>
选择了:{{languages.join(",")}}
</h2>
</div>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
languages:[],
}
});
</script>
</body>
</html>
注意:
- 多个checkbox对应一个model时,model的类型是一个数组,单个checkbox值是boolean类型
- radio对应的值是input的value的值
- input和textarea默认对应的model是字符串
- select单选对应字符串,多选对应数组
7.指令v-on使用
目标:了解v-on指令的语法实现按钮点击后的递增和递减
分析:在没有使用vue之前,页面标签可以通过设置onXXX设置响应事件,在vue中可以通过v-on指令,响应事件。
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button v-on:click="num++">增加</button>
<button @click="decrement1()">减少</button>
<h2>
num={{decrement()}} 和 {{num}}
</h2>
<hr>
事件冒泡测试:<br>
<div style="background-color:lightblue;width:100px;height:100px" @click="print('点击div')">
<!-- 事件修饰符.stop点击按钮时,只会执行这个按钮的默认事件,副事件被阻止 -->
<button @click.stop="print('点击了button')">点我试试</button>
</div>
<br>阻止默认事件:<br>
<!-- .prevent点击超链接时,阻止了默认事件,不访问该超链接地址,直接执行print() -->
<a href="http://www.itcast.cn"@click.prevent="print('点击了超链接')">传智播客</a>
<!-- .capture:使用事件捕获模式,.self:只有元素自身触发事件才执行(冒泡或捕获的都不执行)-->
<!-- .once:只执行一次-->
</div>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
num:1,
},
methods:{
//递减
decrement(){
return 4;
},
decrement1(){
this.num--;
},
//打印
print(str){
console.log(str);
}
}
});
</script>
</body>
</html>
事件修饰符:语法v-on:xxx.修饰符,常用的修饰符有:
- .stop:阻止事件冒泡
- .prevent:阻止默认事件发生
- .capture:使用事件捕获模式
- .self:只有元素自身触发事件执行(冒泡或捕获的都不执行)
- .once:只执行一次
8.指令v-for使用
目标:了解v-for指令语法实现对数组、对象的遍历
分析:
语法:
- 遍历数组 v-for=“item in items” item:循环的变量,items:要遍历的数组名称,先在vue的data中定义好。(item,index)可以获得对应的索引号,index:迭代当前元素的索引号,从0开始。
- 遍历对象 v-for=“value in object” v-for="(value,key) in object" v-for="(value,key,index)in object" 1个参数时,得到的是对象的值;2个参数时,第一个是值,第二个是键;3个参数时,第三个是索引,从0开始、
实现:可以在vue实例化的时候指定要遍历的数据,然后通过v-for指令在模板中遍历显示数据。一般情况下,要遍历的属性可以通过钩子函数created发送异步请求获取数据。
小结:可以使用v-for遍历数组,对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<!-- v-for写在哪一个元素哪一个元素就会被遍历显示多次 -->
<li v-for="(user,index) in users">
{{index}} {{user.name}}--{{user.age}}--{{user.gender}}
</li>
<hr>
<li v-for="value in person">
{{value}}
</li>
<hr>
<li v-for="(value,key) in person":>
{{ key}}--{{value}}
</li>
<hr>
<li v-for="(value,key,index) in person":key="index">
{{index}}--{{key}}--{{value}}
</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
users:[
{"name":"whl","age":13,"gender":"男"},
{"name":"itcast","age":4,"gender":"男"},
{"name":"kkty","age":13,"gender":"男"}
],
person:{"name":"传智播客","age":15,"gender":"男","adress":"Chinese"}
}
});
</script>
</body>
</html>
如果遍历的时候需要使用索引号,可以在循环遍历的位置,添加一个参数,该索引号从0开始。
9.指令v-if-else和v-show
目标:说出v-if和v-show的区别;通过一个按钮的点击,实现遍历数组结果的显示存在与否并在遍历过程中使用v-if对数据进行判断处理,实现文本的隐藏。
分析:
- v-if:通过一个按钮的单击,实现遍历数组结果的显示存在与否并遍历过程中v-if对数据进行判断处理
- v-show:实现文本内容的隐藏
v-if和v-show判断的区别:带有v-show的元素始终被渲染并保留在DOM中,v-show只是简单地切换元素的CSS属性display为none;v-if在不满足条件的时候元素不会存在。
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<!-- v-for写在哪一个元素哪一个元素就会被遍历显示多次 -->
<li v-for="(user,index) in users"v-if="user.gender=='女'":key="index"style="background-color: pink">
{{index}} {{user.name}}--{{user.age}}--{{user.gender}}
</li>
<li v-else style="background-color: blue">
{{index}} {{user.name}}--{{user.age}}--{{user.gender}}
</li>
</ul>
<hr>
<button @click="show=!show">点我</button>
<h2 v-if="show">
Hello VueJS.
</h2>
<hr>
<h2 v-show="show">
你好黑马
</h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
show:true,
users:[
{"name":"whl","age":13,"gender":"女"},
{"name":"itcast","age":4,"gender":"男"},
{"name":"kkty","age":13,"gender":"女"}
],
person:{"name":"传智播客","age":15,"gender":"男","adress":"Chinese"}
}
});
</script>
</body>
</html>
10.指令v-bind
目标:了解v-bind语法和作用;实现点击不同按钮切换不同的属性值;使用class属性中的特殊用法实现一个按钮切换背景色(绑定事件)
分析:
<img src=" “height=” "/>其中src和height的值如果不想写死,想获取vue实例中的数据属性值的话:可以通过使用v-bind实现。
<img v-bind:src="vue实例中的数据属性名":height="vue实例中的数据属性名"/>
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
<style type="text/css">
div{
width:100px;
height: 100px;
color: orange;
}
.red{
background-color: red;
}
.blue{
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<button @click="color='red'">红色</button>
<button @click="color='blue'">蓝色</button>
<div :class="color">点击按钮更改背景颜色</div>
<br>
<br>
<button @click="bool=!bool">点我改变下面色块的颜色</button>
<div :class="{ blue:bool ,red:!bool}" >点击按钮更改背景颜色</div>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
color:"red",
bool:true,
}
});
</script>
</body>
</html>
v-bind作用:可以对所有元素的属性设置vue实例的数据
11.计算属性的使用
目标:计算属性的应用场景,实现将一个日期时间转换为yyyy-mm-dd的格式字符串
分析:一个日期的毫秒值要显示为格式化(yyyy-MM-dd)的日期字符串的话,可以使用computed计算属性里面的方法进行处理
小结:
计算属性的应用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>
{{new Date(birthday).getFullYear()}}
{{new Date(birthday).getMonth()+1}}
{{new Date(birthday).getDate()}}
</h2>
<h2>
{{birth}}
</h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app", data:{
birthday:1429032123201
},
computed:{
birth(){
const date=new Date(this.birthday);
return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()
}
}
});
</script>
</body>
</html>
computed计算属性的应用场景:可以应用插值或者指令表达式复杂的时候。 可以将一些属性属性经过方法处理之后返回。
12. watch基本和深度监控
目标:watch的使用场景,并使用其监听简单属性值及其对象中属性值的变化
分析:在vue实例中数据属性,因为在页面中修改而产生变化。可以通过watch监控其改变前后的值。如果是修改的对象数据属性,可以开启深度监控获取获取修改后最新的对象数据。
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
<hr><br>
<input type="text" v-model="person.name"><br>
<input type="text" v-model="person.age"><br><button @click="person.age++">增加</button>
<h2>
姓名为:{{person.name}} 年龄:{{person.age}}
</h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
message:"hailin",
person:{"name":"heihei","age":"13"}
},
watch:{
message(newvalue,oldvalue){
console.log("新增:"+newvalue+";旧值:"+oldvalue)
},
person:{
//开启深度监控,监控对象中属性值的变化
deep:true,
//可以获取最小的对象属性数据
handler(obj){
console.log("name"+obj.name+"age"+obj.age)
}
}
}
});
</script>
</body>
</html>
可以监控数据属性,和深度监控监控对象属性的值
使用场景:可以监控视图中数据的变化而做出响应,可以在下拉框列表中,当如果选择了对应的下拉框选项之后,要根据最新的值去加载一些数据的话可以使用watch。
13.组件使用
目标:了解组件的使用场景,定义点击则及时的组件并使用全局注册和局部注册方式。
分析:可以将通用的或公用的页面模块抽取成vue组件,在 vue实例中引用。
- 组件其实也是一个vue实例,因此定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
- 但是组件渲染需要html模板,所以增加了template属性,值就是html模板
- 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名来使用组件
- data的定义方式比较特殊,必须是一个函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<script type="text/javascript">
//定义组件
const counter={
template:"<button @click='num++'>点击了{{num}}次</button>",
data(){
return {num:0}
}
};
//注册组件:全局注册和局部注册
//全局注册:在所有的vue实例中都可以使用组件
//参数一是组件名,参数二十具体的组件名称
// Vue.component("couter",counter);
var app = new Vue({
el:"#app",
components:{
counter:counter
}
});
</script>
</body>
</html>
组件使用场景:在项目需要重用某个模块(头部、尾部、新闻…)的时候,可以将模块抽取成组件,其他页面中注册组件并引用。(全局注册和局部注册)
- 全局注册:在任何vue实例中都可以引用(比如头部、导航菜单、底部)
- 局部注册:可以在有需要的页面引入组件(比如商场页面中的各中活动模块)
14.父组件向子组件通信
目标:父组件与子组件通信的意义,实现父组件将简单字符串和对象更新到子组件
组件通信的意义:父子组件之间数据的交换,能够及时更新组件组件内容。
- 父组件将简单字符串更新传递到子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用组件-->
<introduce :title="msg"></introduce>
</div>
<script type="text/javascript">
//定义组件
const introduce={
template:"<h2>{{title}}</h2>",
//定义接收父组件的属性
props:[
"title"
]
};
//注册组件:全局注册和局部注册
//全局注册:在所有的vue实例中都可以使用组件
//参数一是组件名,参数二十具体的组件名称
Vue.component("introduce",introduce);
var app = new Vue({
el:"#app",
// components:{
// counter:counter
// }
data:{
msg:"父组件的msg属性数据内容"
}
});
</script>
</body>
</html>
- 父组件将数组更新传递到子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用组件-->
<my-list :items="lessons"></my-list>
</div>
<script type="text/javascript">
//定义组件
const my={
template:`<ul>
<li v-for="item in items":key="item.id">{{item.id}}--{{item.name}}</li>
</ul>`,
//定义接收父组件的属性
props:{
items:{
type:Array,
//默认值
default:[]
}
}
};
//注册组件:全局注册和局部注册
//全局注册:在所有的vue实例中都可以使用组件
//参数一是组件名,参数二十具体的组件名称
// Vue.component("myList",my);
var app = new Vue({
el:"#app",
data:{
lessons:[{"id":1,"name":"Java"},
{"id":2,"name":"web"},
{"id":3,"name":"vue"}]
},
components:{
myList:my
}
});
</script>
</body>
</html>
15.子组件向父组件通信
目标: 在子组件中点击对应按钮实现父组件中属性数据的改变
小结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>{{num}}</h2>
<!-- 使用组件-->
<counter v-on:plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>
<script type="text/javascript">
//定义组件
const coun={
template:`
<div>
<button @click="incrNum">num自增</button>
<button @click="decrNum">num自减</button>
</div>
`,
props:["snum"],
methods:{
//递增
incrNum(){
//调用到父组件的方法
// 触发当前实例上的事件
return this.$emit("plus",this.snum)
},
decrNum(){
//调用到父组件的方法
return this.$emit("reduce")
}
}
};
//注册组件:全局注册和局部注册
//全局注册:在所有的vue实例中都可以使用组件
//参数一是组件名,参数二十具体的组件名称
// Vue.component("couter",counter);
var app = new Vue({
el:"#app",
components:{
counter:coun
},
data:{
num:0,
a:0
},
methods:{
numPlus(a){
this.num++;
console.log(a+1)
},
numReduce(){
this.num--;
}
}
});
</script>
</body>
</html>
16.axios概述
目标:axios的用途及了解常见用法
分析:Vuejs并没有直接处理ajax的组件,但可以使用axios或vue-resource组件实现对异步请求的操作。 vue-resource是vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。vue-resource的github地址:http://github.com/pagekit/vue-resource。Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中
小结:
axios的作用:发送异步请求获取数据,常见的方法有:get、post;在发送的时候可以指定参数(地址、请求方式和请求头部信息);返回数据结构(data/status/statusText/header/config)
17.axios方法及get、post方法使用
目标:使用axios方法获取数据并在页面中将遍历显示,切换改为get/post方法实现数据加载
小结:可以使用axios获取对应服务器数据;如果不是同一个服务的数据则可能出现跨域请求,需要在响应的服务器上配置跨域。
跨域:在前端js中如果发送异步请求的话,请求的地址与当前服务器的ip或者端口不同都是跨域请求,可以在服务器端配置 @CrossOrign(origins="*")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
<script src="node_modules/vue/dist/vue.js"></script>
<script src="js/axios.min.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(user, index) in users" :key="index">
{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
users:[],
},
created(){
/*
可以跨域请求,在对应的域加上@CrossOrign(origins="*")
* */
axios.post("data.json").then(res=>{
console.log(res),
app.users=res.data;
}).catch(err=>alert(err))
//初始化加载数据
/* axios.get("data.json").then(res=>{
console.log(res),
app.users=res.data;
}).catch(err=>alert(err))
*/
/* axios({
url:"data.json",
method:"get"//默认get
}).then(res=>{
console.log(res);
//将数据赋值到vue实例中的数据属性users
// 不能使用this,this在axios的回调函数中表示窗口,不是vue实例
app.users=res.data;
}).catch(err=>alert(err));
*/
}
});
</script>
</body>
</html>