Vue JS
重要性
1、Vue更加简洁,Vue是渐进式的JavaScript框架
2、特点:易用、灵活、高效(虚拟DOM==》预编译的过程)
3、Vue是组件化的,一个Vue里面有很多HTML、css、JavaScript,便于管理
Vue的组件
Vue的基本语法
步骤
入门案例的步骤
1、导入Vue.js文件(在下面导入文件)
<script src="../js/vue.js"></script>
2、指定区域渲染(需要准备div,div是渲染的空间,div里面才写Vue js的代码)
<div id="app">{{msg}}</div>
3、创建Vue js的对象,指定渲染区域,动态调用
const App=new Vue({
el:"#app",
data:{
msg:"hhhh"
}
})
</script>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjqWZpoe-1627460884045)(学习_files/5.jpg)]
数据的显示
上面步骤的特点:如果页面没有渲染完成,则直接展示给用户{{msg}}
解决:
1、v-text:如果页面没有渲染完成,则不展现数据,在div中写h2 v-text=“msg”,插值表达式需要直接显示
2、注意事项:只有显示时才用,输入时不能用
3、v-html:
<div id="app">
<h2 v-text="msg"></h2>
<div v-html="h3HTml"></div>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
msg:"您好 Vue",
h3HTml:"<h3>想要h3渲染</h3>"
}
})
</script>
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPMspHZN-1627460884046)(学习_files/6.jpg)]
4、v-pre:跳过预编译:显示标签体本身,为了避免将logo之类的都转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSZnolnG-1627460884047)(学习_files/7.jpg)]
5、v-once:只渲染一次
<div v-once>{{once}}</div>
6、v-model:双向数据绑定:数据端-》页面;页面-》数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2LFPVnGh-1627460884049)(学习_files/8.jpg)]
Vue JS语法
MVVM设计思想
MVC知识回顾
0、MVC减少代码的耦合性,针对后端
1、M:Model:封装的数据
2、V:View:视图层
3、C:Controller:控制层
MVVM思想
0、针对前端,为了解耦的,模拟后端设计的一种思想
1、M:Model:封装的数据
2、V:View:视图层
3、VM:viewModel:数据视图的控制层,控制数据流转
双向数据绑定的原理
DOM
dom是JS的原生对象
整个页面都可以用document,dom=这个页面,dom是控制页面中的动态效果
虚拟DOM
页面元素发生了变化,dom 监听器就可以监听到,就将结果传给model,前端==》后端
model–》虚拟对象将结果先算好了,将结果传给DOM,页面一渲染,就出现。后端==》前端
虚拟dom:预编译的效果,Vue中模拟dom创建的,预编译的好处:先把数据算了一遍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RpDsfP2u-1627460884052)(学习_files/9.jpg)]
步骤
1、修改页面,通过DOM监听器感知用户的修改行为,通过虚拟DOM对象,更新Model中的属性
2、当数据发生改变时,由虚拟DOM根据数据绑定的规则,第一时间同时真实的DOM,至此页面发生改变
虚拟DOM像中间传话的人,预编译
事件绑定
1、事件绑定使用v-on
例如:
<div id="app">
<h3>{{num}}</h3>
<button v-on:click="num++">自增</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
num:100
}
})
</script>
2、事件绑定可以简写
v-on:可以简写为@,则上述代码变为:
<div id="app">
<h3>{{num}}</h3>
<button @click="num++">自增</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
num:100
}
})
</script>
3、事件绑定可以用函数来表示
<!-- 函数:如果没有参数()可以省略 -->
<button @click="addNum">计算</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
num:100
},
methods:{
addNum:function(){
this.num++
}
}
})
</script>
4、方法的简化
把k,v的方法简化为k(){}
简化前:
addNum:function(){
this.num++
}
简化后:
addNum(){
this.num++
}
按键触发
<div id="app">
<!--
语法:
1、v-on:keydown=“”按下触发
2、v-on:keyup=“”松开触发
3、v-on:press=“”小键盘
1、按钮实现加法操作
2、用户回车按钮触发
-->
<h3>用户的数据{{num}}</h3>
<!-- <h3>{{num2}}</h3> -->
<input type="text" v-model="num2" v-on:keyup.enter="addNum"/>
<button @click="addNum">计算</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
num:100,
num2:0
},
methods:{
addNum(){
this.num+=parseInt(this.num2)
}
}
})
</script>
练习 计算器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>按键触发</title>
</head>
<body>
<div id="app">
<!-- 准备两个文本输入框,一个num1,一个num2,准备一个按钮,计算,点击按钮时实现num1+num2,将得到的结果通过总数输出 -->
<input type="text" v-model="num1"/><br />
<input type="text" v-model="num2" v-on:keyup.enter="addNum()" /><br />
{{count}}<br />
<button @click="addNum()">计算</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
num1:0,
num2:0,
count:0
},
methods:{
addNum(){
this.count=parseInt(this.num1)+parseInt(this.num2)
}
}
})
</script>
</body>
</html>
按键修饰符
阻止冒泡 .stop
JS,元素可能需要嵌套==》事件可能嵌套
1、两个地方num++,一次加两个,双数。里面向外面冒泡
2、说明:如果事件嵌套则必然会带来事件冒泡
3、解决:组织事件冒泡 .stop属性 @click.stop=“num++”
<div id="app">
数值:{{num}}
<!-- 两个地方num++,一次加两个,双数。里面向外面冒泡
说明:如果事件嵌套则必然会带来事件冒泡
解决:组织事件冒泡 .stop属性 @click.stop="num++"
-->
<div @click="num++">
嵌套结构
<button type="button" @click.stop="num++">计算</button>
</div>
</div>
阻止默认行为 .prevent
1、点击a标签,不跳转页面,同时触发事件
2、解决:阻止a标签的默认行为
<a href="http://www.baidu.com" @click.prevent="aClick()">百度</a>
属性绑定
a标签的属性绑定
1、v-bind:href=“Vue中的属性” a v-bind:href="url"百度
2、v-bind的简化写法:a :href="url"简化写法
class类型绑定
1、div style="background-color:darkkhaki; width: 100px; height: 100px;"这样的情况用一个class来简化,如下:
<style type="text/css">
/**
* 红色、宽50、高50
*/
.red{
background-color: red;
width: 50px;
height: 50px;
}
.blue{
background-color: blue;
width: 100px;
height: 100px;
}
</style>
<div :class="red">我是类型的修饰</div>
上述方法不够灵活,需要修改代码,需求为:为class动态赋值,解决如下:
<style type="text/css">
/**
* 红色、宽50、高50
*/
.red{
background-color: red;
width: 50px;
height: 50px;
}
.blue{
background-color: blue;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="app">
<!-- class类型绑定 -->
<!-- 用一个类型来代表多个样式,简化程序的调用
需求:动态为class赋值
-->
<div :class="colorCla">我是类型的修饰</div>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
url:"http://www.baidu.com",
coloClass:"red"
}
})
</script>
属性切换
1、需求:点击文字下方的切换按钮,自动切换北京颜色
2、解决:使用flag
2.1 在Vue({})中加一个flag:true
2.2 更改绑定事件为div :class="{red:flag}"我是类型的修饰,red为style中已有的样式
疑惑:为什么用Vue({})中的colorClass不可以切换
解决:如果切换样式使用属性变量colorClass,如果切换是否显示用style样式red
2.3 在下方的button中设置flag转换,具体为:button type=“button” @click=“flag=!flag”
分支结构
1、语法:
v-if 如果为真则展示
v-else-if 必须与v-if连用
v-else 必须与v-if连用
v-show display显示,当为true时显示数据,为false时隐藏数据
<div id="app">
<h1 v-show="ok">Hello!</h1>
</div>
new Vue({
el: '#app',
data: {
ok: false
}
})
2、评级的案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>分支结构</title>
</head>
<body>
<div id="app">
<!-- /**
* 分支结构:
语法:
v-if 如果为真则展示
v-elseif 必须与v-if连用
v-else 必须与v-if连用
*/ -->
<h3>评级</h3>
输入分数:<input type="number" v-model="score" />
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=80">良好</div>
<div v-else-if="score>=70">中等</div>
<div v-else-if="score>=60">及格</div>
<div v-else>不及格</div>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
score:90
}
})
</script>
</body>
</html>
循环结构
1、什么时候用循环:多次重复执行同一个操作
2、计算机加法速度快于减法,递归耗费很多资源
3、什么数据使用循环:数组、对象、数组里面套对象(java中的集合)
需求:将数组中的数据在页面中展示
注:在js中使用of,在这里用in,展示:v-for=“pai in array”>{{pai}}
效果展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1AvqXFoU-1627460884053)(学习_files/10.jpg)]
升级:
v-for=“pai in array” v-text=“pai”>/p
需求2:获取数组的下标
语法:v-for=“(遍历的元素,遍历的下标)in array”
展示:p v-for="(item,index) in array">{{‘下标~~~’+index+‘数据值’+item}}
注意:在上述情况下,不可以加v-text属性,加上只能显示两个中的一个,不能正确显示数据
正确展示:
<p v-for="(item,index) in array">{{'下标~~~'+index+'数据值'+item}}</p>
错误展示: p v-for="(item,index) in array" v-text="(item,index)">{{'下标~~~'+index+'数据值'+item}}
遍历对象、集合:
<!-- 遍历对象 -->
<p v-for="u in user">{{u}}</p>
<p v-for="(value,key) in user">{{key}}~~{{value}}</p>
<!-- 遍历“集合” -->
<p v-for="user in userList">
{{user.id}},{{user.name}},{{user.age}}
</p>
user:{
id:100,
name:"tomcat",
age:18
},
userList:[
{
id:100,
name:"tomcat",
age:18
},
{
id:200,
name:"sql",
age:20
}
]
p标签不能嵌套p标签
表单修饰符
1、语法:
.number 只能输入数组类型
.trim 去除左右空格
.lazy 离焦事件 用户改好了触发一次,不是时时触发,当鼠标移开时才触发
<div id="app">
<h3>表单修饰符</h3>
<!-- 。number的使用 -->
数据展示{{age}}<br>
年龄:<input type="text" v-model.number="age" />
<button type="button" @click="addNum">增加</button>
<hr >
<!-- 去除左右的空格 -->
数据展示{{name.length}}<br>
年龄:<input type="text" v-model.trim="name" />
<!-- 离焦事件,不是时时触发,当鼠标移开时才触发 -->
<hr >
数据展示{{msg}}<br>
年龄:<input type="text" v-model.lazy="msg" />
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
age:18,
name:'',
msg:''
},
methods:{
addNum(){
this.age+=1
}
}
})
</script>
用户输入内容反转
1、需求:将用户的输入内容进行反转
2、解决:字符串转化为数组 拆串
将数组倒序
将数组转化字符串
<h3>数据展示{{msg.split('').reverse().join('')}}</h3>
<input v-model="msg"/>
split拆分,reverse反转,join以’‘连接
计算属性
1、当多次调用一个方法时,会多次调用方法,如图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GdFMIk3W-1627460884055)(学习_files/11.jpg)]
2、使用计算属性后,多次调用一个方法,只显示一次
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dn2nNLpG-1627460884055)(学习_files/12.jpg)]
3、原因:计算属性有缓存机制
数组的操作
push java中的入栈,在数组中是在结尾追加数据
pop java中的出栈,在数组中是在结尾删除数据
shift 删除第一个元素
unshift 在开头追加元素
splice 替换数组中的数据 参数( 起始位置,数量,替换成[可以有多个] )
sort 数组的排序
reverse 数组的反转
案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>数组的操作</title>
</head>
<body>
<h2>数组操作</h2>
<!--
push java中的入栈,在数组中是在结尾追加数据
pop java中的出栈,在数组中是在结尾删除数据
shift 删除第一个元素
unshift 在开头追加元素
splice 替换数组中的数据 参数( 起始位置,数量,替换成[可以有多个] )
sort 数组的排序
reverse 数组的反转
-->
<div id="app">
输入框:<input type="text" v-model="msg" /><br />
<span v-for="i in array">{{i}}</span><br />
<hr >
<button @click="push">push</button>
<button @click="pop">pop</button>
<button @click="shift">shift</button>
<button @click="unshift">unshift</button>
<button @click="splice">splice</button>
<button @click="sort">sort</button>
<button @click="reverse">reverse</button>
</div>
<script src="../js/vue.js"></script>
<script>
const App=new Vue({
el:"#app",
data:{
array:['a','b','c'],
msg:''
},
methods:{
push(){
this.array.push(this.msg)
},
pop(){
this.array.pop()
},
shift(){
this.array.shift()
},
unshift(){
this.array.unshift(this.msg)
},
splice(){
this.array.splice(0,1,this.msg) //替换第一个元素
//this.array.splice(this.array.length-1,1,this.msg) //替换最后一个元素
//this.array.splice(1,1) //删除第二个元素
},
sort(){
this.array.sort()
},
reverse(){
this.array.reverse()
},
}
})
</script>
</body>
<script>
[{}]
</script>
</html>
Vue生命周期
周期:
初始化:【beforeCreate(Vue对象实例化之前、刚开始),created,beforeMount(挂载el),mounted(Vue对象实例化成功,div渲染完成)】
修改:【beforeUpdate(修改前),updated(修改后)】
销毁:【beforeDestroy(销毁前),destroy(销毁后)】虚拟DOM
生命周期函数的作用:
如果需要对Vue中的数据进行额外的操作,则使用生命周期函数,目的是框架的扩展性更好