1 MVC和MVVM
1.1 MVC
概述:后端分层开发思想
- M(Model)模型:需要给view传递的所有数据。
- V(View)视图:负责将model中的数据进行展示
- C(Controller)控制器:负责接收页面http请求,进行业务逻辑调用或处理,返回正确的模型、视图或内容
1.2 MVVM
概述:前端视图层分层开发思想
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app"></div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
},
methods:{
}
})
</script>
</body>
</html>
2 指令
2.1 文本
- { { }}
- v-text
- v-html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<!--
第一个:插值表达式 {
{}}
a:有闪烁问题(v-cloak:解决插值表达式的闪烁问题 )
b:不会覆盖元素中原本的内容
c:不会解析标签
-->
<h3 v-cloak>{
{msg}}</h3>
<!--
第二个:v-text
a:会覆盖元素中原本的内容
b:不会解析标签
-->
<h3 v-text="msg"></h3>
<!--
第三个:v-html
a:会覆盖元素中原本的内容
b:会解析标签
-->
<h3 v-html="msg"></h3>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
msg:'Vue'
},
methods:{
}
})
</script>
</body>
</html>
2.2 绑定属性和事件
- v-bind
- v-on
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
<style>
.color {
color: lightgreen;
}
.style {
font-style: italic;
}
.size {
font-size: 50px;
}
</style>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<!--绑定属性:v-bind
第一种:绑定普通属性
第二种:绑定样式:行内样式和内联样式
-->
<!--1.普通属性-->
<input type="button" value="标题" v-bind:title="myTitle">
<input type="button" value="标题" :title="myTitle">
<!--2.行内样式-->
<!--数组-->
<h1 :class="['color','style']">cxk</h1>
<!--数组中使用三元表达式-->
<h1 :class="['color','style',flag?'size':'']">cxk</h1>
<!--数组中使用对象-->
<h1 :class="['red','blue',{
'size':flag}]">cxk</h1>
<!--直接使用对象-->
<h1 :class="{color:true, style:true, size:true}">cxk</h1>
<h1 :class="style1">cxk</h1><!--引用data中的数据-->
<!--3.内联样式-->
<!--直接写样式-->
<h1 :style="{
'color':'red'}">cxk</h1>
<!--在vm实例中写样式后引用-->
<h1 :style="style2">cxk</h1>
<!--使用数组去引用多个样式-->
<h1 :style="[style2,style3]">cxk</h1>
<!--绑定事件:v-on-->
<!--事件修饰符:
.stop:阻止冒泡
.prevent:阻止默认行为
.capture:捕获机制触发
.self:自身触发事件,只阻止自己身上冒泡行为
.once:只触发一次-->
<input type="button" value="提交" v-on:click="submit">
<input type="button" value="提交" @click="submit">
<div>
<input type="button" value="提交" @click.self="submit">
</div>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
title:'kun',
flag:true,
style1:{
color:true, style:true, size:true},
style2:{
'color':'red'},
style3:{
'font-style':'italic'}
},
methods:{
submit:function(){
alert('kun');
//1.在vm实例中想要获取data上的数据,通过'this.属性名'访问
//2.在vm实例中想要使用方法,通过'this.方法名'访问
//3.箭头函数不改变this的指向
console.log(this.title);
}
}
})
</script>
</body>
</html>
2.3 双向数据绑定
- v-model
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<p>{
{msg}}</p>
<input type="text" v-model="msg">
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'cxk'
},
methods:{
}
})
</script>
</body>
</html>
2.4 循环判断
- v-for
- v-if
- v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<!--判断-->
<h3 v-if="flag">v-if</h3>
<h3 v-show="flag">v-show</h3>
<!--循环-->
<!--(1)遍历数组-->
<p>遍历数组</p>
<p v-for="(item, i) in list" :key="item.id">{
{item}}---{
{i}}</p>
<!--(2)遍历对象数组-->
<p>遍历对象数组</p>
<p v-for="(item, i) in list2" :key="item.id">
{
{item.id}}---{
{item.age}}---{
{item.sex}}---{
{i}}
</p>
<!--(3)遍历对象-->
<p>遍历对象</p>
<p v-for="(val, key,i) in list3" :key="item.id">
{
{val}}---{
{key}}---{
{i}}
</p>
<!--(4)迭代数字:从1开始-->
<p>迭代数字:从1开始</p>
<p v-for="count in 8">{
{count}}</p>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
flag:true,
list:[1,2,3,4,5,6],
list2:[
{
id:'1', age:12, sex:'男'},
{
id:'2', age:14, sex:'女'},
{
id:'3', age:17, sex:'男'}
],
list3:{
id:'4',
age:16,
sex:'男'
}
},
methods:{
}
})
</script>
</body>
</html>
2.5 自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<h3 v-fontsize="50">Vue</h3>
<h3 v-color="red">Vue</h3>
</div>
<script>
//1.全局自定义指令
//注意:定义时不需要加v-,调用时需要加v-
//参数一:指令名称
//参数二:是对象
Vue.directive('color',{
//以下三个函数的第一个参数永远是:el
//指令绑定到此元素上时,会立即执行函数bind,只执行一次,还没有插入到DOM中
bind:function(el,binding){
el.style.color=binding.value;
},
//元素插入到DOM中时,会立即执行函数inserted,只执行一次
inserted:function (el) {
//focus的使用必须是元素插入DOM中才可以起作用
},
//当VNode更新时,会立即执行updated函数,可以触发多次
updated:function (el) {
}
});
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
directives:{
'color':{
bind:function(el,binding){
el.style.color=binding.value;
}
},
//一般使用最多的是bind和update,以下的使用同时使用这两个函数
'fontsize':function (el,binding) {
el.style.fontSize=parseInt(binding.value)+'px';
}
}
});
</script>
</body>
</html>
3 过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<p>{
{msg | format('疯狂')}}</p>
</div>
<script>
//过滤器调用顺序:就近原则,优先调用私有过滤器
//1.全局过滤器
//参数一:是过滤器管道符前面传递来的数据,
//也可以传递多个参数
Vue.filter('format',function (msg,arg) {
//replace的参数一:可以写字符串和正则
return msg.replace(/可爱/g,arg);
});
var vm = new Vue({
el:'#app',
data:{
msg:'曾经,你也是一个可爱的少女,甜到很多人,可爱的你,可爱的你'
},
methods:{
},
//2.私有过滤器
filters:{
format:function (msg,arg) {
return msg.replace(/可爱/g,'漂亮');
}
}
});
</script>
</body>
</html>
4 生命周期函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<div id="app">
<h3 id="h3">{
{msg}}</h3>
<input type="button" value="Modify" @click="msg='Vue'">
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'Hello Vue'
},
methods:{
show:function () {
console.log('执行');
}
},
//创建阶段
beforeCreate(){
//1.实例被完全创建出来后,会执行这个函数
//注意:这个生命周期函数执行时,data和methods都没有被初始化
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
created(){
//2.这个生命周期函数执行时,data和methods都被初始化了
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
beforeMount(){
//3.模板已经在内存中编译好了,但是尚未把模板渲染(挂载)到页面上去,还是旧数据
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
mounted(){
//4.内存中的模板已经真实的挂载在页面中,页面已经被渲染好了,实例已经被完全创建好了
//如果要通过某些插件操作dom节点,最早在mounted中执行
//此时组件已经脱离了创建阶段,进入运行阶段
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
//运行阶段
beforeUpdate(){
//5.界面还没有被更新,数据已经被更新了
//根据data数据的改变,选择性的执行0到多次
//页面中显示的数据还是旧的,data中的数据是最新的,
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
updated(){
//6.页面和data数据已经保持同步,都是最新的
console.log(document.getElementById('h3').innerHTML);
console.log(this.msg);
},
//销毁阶段
beforeDestroy(){
//7.Vue实例已经从运行阶段到销毁阶段
//实例身上所有的大图和methods、过滤器、指令等都处于可用状态,还没有真正执行销毁过程
},
destroyed(){
//8.实例身上所有的大图和methods、过滤器、指令等都处于不可用状态
}
});
</script>
</body>
</html>
5 动画
5.1 v-…动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
<style>
/*自定义样式:
默认使用: .v-...
transition加了name属性使用: .name值-...
如:本案例中将.v-enter等改为——>.h3-enter
*/
/*1.某个元素动画*/
.h3-enter,
.h3-leave-to {
opacity: 0;
transform: translateX(200px);
}
.h3-enter-active,
.h3-leave-active {
transition: all 0.8s ease;
}
/*2.列表动画*/
.add-enter,
.add-leave-to {
opacity: 0;
transform: translateY(150px);
}
.add-enter-active,
.add-leave-active {
transition: all 0.8s ease;
}
.add-move {
transition: all 0.6s ease;
}
.add-leave-active {
position: absolute;
}
</style>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<!--1.某个元素动画-->
<input type="button" value="切换" @click="flag=!flag">
<!--使用transition包裹要实现动画的元素
name属性用于区分不同组之间的动画-->
<transition name="h3">
<h3 v-if="flag">kun</h3>
</transition>
<!--2.列表动画-->
<ul>
<!--列表过渡:v-for渲染出来,不能使用transition,需要使用transitionGroup
appear:页面入场动画效果
tag:渲染为指定元素,如果不指定,渲染为span标签
mode:动画切换模式-->
<transition-group name="add" appear tag="ul" mode="out-in">
<li v-for="(item, i) in list" :key="item.id" >
{
{item.id}}----{
{item.name}}
</li>
</transition-group>
</ul>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
flag:true,
list:[
{
id:1, name: '小明'},
{
id:2, name: '小坤'},
{
id:3, name: '小月'},
{
id:4, name: '小花'},
]
},
methods:{
}
})
</script>
</body>
</html>
5.2 animate动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
<script src="./lib/animate.css"></script>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<input type="button" value="切换" @click="flag=!flag">
<transition
enter-active-class="bounceIn"
leave-active-class="bounceOut"
:duration="{ enter: 200, leave: 400}">
<h3 v-if="flag" class="animated">kun</h3>
</transition>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
flag:true
},
methods:{
}
})
</script>
</body>
</html>
5.3 钩子函数动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入vue包-->
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<!--2.视图:v(view)-->
<div id="app">
<input type="button" value="加入购物车" @click="flag=!flag">
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter">
<div class="ball" v-show="flag"></div>
</transition>
</div>
<script>
//3.创建实例:vm
var vm = new Vue({
//el:指定要控制的区域
el:'#app',
//4.数据:m
data:{
flag:true
},
methods:{
beforeEnter(el){
//动画入场之前,动画尚未开始,设置起始样式
el.style.transform = 'translate(0,0)';
},
enter(el,done){
//动画开始之后的样式,动画执行完成字后的结束状态
el.offsetWidth;
el.style.transform = 'translate(150px,250px)';
el.style.transition = 'all 1s ease ';
//动画完成立即消失,实质就是afterEnter函数的引用
done();
},
afterEnter(el){
//控制小球的显示与隐藏;直接跳过后半场动画,flag直接变为false,下一次依然是false变为true
this.flag=!this.flag;
},
}
})
</script>
</body>
</html>