- 说明:本文章主在介绍vue的核心特性
简介
- Vue:一种基于MVVM开发模式的,专注于视图层的前端开发框架
(1)MVVM
1)定义
-
MVVM(Model-View-ViewModel):是一种软件架构设计模式,是MVC模式的改进版,将视图(View)和模型(Model)分离,而VM作为两者通信的桥梁
-
Model:模型,后端传递的数据模型
-
View:视图,前端显示的页面
-
ViewModel:mvvm模式的核心,是model和view通信的桥梁,双向绑定,通过虚拟doc的事件监听(即不经过真正的doc,而是通过doc虚拟机,提高访问效率),实现实时更新(即model数据一改,view马上变化。不用刷新)
2)优点
- 低耦合:视图和模型可以独立修改变化,而互不影响
- 可复用:视图和模型均可被模块化,在不同页面中调用
- 独立开发:前后端分离,互不影响
- 可测试:无需等待后端开发人员提供接口,前端可以给Model提供虚拟数据,让View显示,进而运行测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pCxu2LPK-1672115002701)(null)]
(2)Vue生命周期
1)基本说明
事件,数据,方法初始化和注入。解析vue的template模板,挂载渲染到视图层。之后若数据改变,虚拟dom会实时更新视图层和模型层的该数据。最后是vue实例化销毁
2)具体说明
- vue首先初始化事件(如:一些自定义的事件会在此时初始化)和生命周期
- 然后将data数据和methods方法注入vue中
- 之后再判断是否有el元素和template模板,为vue的模板解析做准备
- 若有template模板,则将模板解析为html。没有则将el元素的外部html作为template模板解析
- 再将编译解析完成的html挂载渲染至视图层,之后当数据改变时,虚拟dom会将数据实时更新至视图层和模型层。
- 最后是销毁vue实例化对象
1. 基础语法
(1){{xxx}}
- 说明:视图层获取模型层数据的一种方式,可获取data,data(),params,计算属性中的数据,可调用methods中的方法,还可以进行简单的逻辑/算术运算操作(如:用三目运算符),结果输出于视图层
(2)条件运算
- 说明:
v-if
,v-else-if
,v-else
<div id="conditional-rendering">
// seen为模型层数据
<span v-if="num > 0">num大于0</span>
<span v-else-if="num < 0">num小于0</span>
<span v-else="num == 0">num等于0</span>
</div>
(3)循环
- 说明:
v-for
// todos为模型层数据
// 对todos循环遍历,todos中每个元素赋予todo,index为下标,0开始
<li v-for="(todo,index) in todos">
{{ todo.text }}
</li>
(4)v-bind
- 说明:单向绑定数据,简写
:
(5)v-model
- 说明:双向绑定数据
(6)v-on
- 说明:事件监听,简写
@
2. 双向绑定
- 说明:VM将视图和模型连接并双向绑定,当模型数据变化时,视图会实时变化;当视图变化时,模型也会实时变化
(1)示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
</head>
<body>
<div id="app">
文本1输入:<input type="text" v-model="message" /> <br>
文本2输入:<input type="text" v-model="message" />
</div>
<script>
var vm = new Vue({
el:"#app",
data: {
message: "123"
}
});
</script>
</body>
</html>
(2)理解
- 问题1:console修改message,input标签文本同步变化的原因?
- 回答:model层单向绑定view层input标签message(即2和3箭头),当console修改message时,则model层数据变化,那么input标签文本同步变化
- 问题2:当第一个input标签修改文本时,为什么第二个input标签文本同步修改?
- 回答:view层第一个input标签单向绑定model层message(即1箭头),且model层单向绑定view层第二个input标签message(即3箭头),当第一个input标签文本变化时,model层message同步变化,由因model层message变化,使第二个input标签文本同步变化(即数据变化: input标签1→model层→input标签2,)
3. 组件
- 组件:将视图模块化
(1)示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
</head>
<body>
// View层
<div id="app">
<shuiliumu v-for="item in items" v-bind:message="item"></shuiliumu>
</div>
<script>
//组件
Vue.component("shuiliumu",{
props: ['message'],
template: `<div>
<input type="text" v-model="message" />
{{message}}<br />
</div>`
})
var vm = new Vue({
el:"#app",
//model层
data: {
items : ['java', 'linux', '前端']
}
});
</script>
</body>
</html>
(2)理解
-
问题1:为什么console修改了items,input标签和
{{message}}
文本同步修改 -
回答: model层items修改,则通过v-for双向绑定的入参items,同步修改,那么item获取的数据也不同了。又v-bind连接组件将组件vue属性message与自定义标签中vue变量item绑定,item修改,则message同步修改,那么在组件模板中显示的message也修改了(即数据变化 model层→shuoliumu便签→input标签和
{{message}}
) -
问题2:为什么input标签文本修改,
{{message}}
同步更新 -
回答:(数据变化:input标签→shuiliumu便签items→model层items和
{{message}}
)
注意:model层items数据没变化,因为主键中数据绑定用的是单向绑定。不可用双向绑定,否则报错
4. 计算属性
-
定义:具有逻辑运算能力的属性;
-
特性:该属性存于缓存中,可被直接获取(如:函数或其他计算属性的直接获取),且当计算属性中逻辑运算的参数变化时,计算属性自动更新,无法直接改变计算属性的值
-
定义方式:与定义函数类似,单必须要有返回,作为该计算属性的值
-
优点:减少代码,节约系统开销,提高性能
-
应用场景:
- 需要不经常变化的计算结果时(如:某商品的总价计算中,显示总价totalprice在页面中)
-
注意:计算属性在methods中通过
计算属性名.value
获取值
示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript"></script>
</head>
<body>
// View层
<div id="app">
<input type="text" v-model:value="price1" /><br />
<input type="text" v-model:value="price2" /><br />
<input type="text" v-model:value="price3" />
Total: {{total}}
<!-- 不用计算属性算total方式1:view层应只关注显示,而不应该有逻辑运算。不符合mvvm模式原则 -->
<!-- Total: {{price1*1+price2*1+price3*1}} -->
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
price1: 10,
price2: 20,
price3: 30,
// 不用计算属性算total方式2:data属性只是用于描述json数据结构,其数据值有后端传来,不应有逻辑运算
// total: this.price1*1 + this.price2*1 + this.price3*1
},
methods:{
},
computed:{
//定义一个计算属性
total(){
// 当input修改时,传过来的数据为string,通过乘一转为int类型
const sum = this.price1*1 + this.price2*1 + this.price3*1;
return sum;
}
}
})
</script>
</body>
</html>
5. 插槽slot
- slot:可理解为一个组件占位符,以便组件插入
- 作为标签:表示占位符
- 作为组件属性:表示要绑定的插槽
示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
</head>
<body>
// View层
<div id="app">
<main-component>
<tittle-component slot="tittle-slot" v-bind:tittle="tittle"></tittle-component>
<name-component slot="name-slot" v-for="item in items" v-bind:name='item'></name-component>
</main-component>
</div>
<script>
// 组件
Vue.component("main-component",{
template:
`<div>
<slot name="tittle-slot"></slot>
<ul>
<slot name="name-slot"></slot>
</ul>
</div>`
})
//组件
Vue.component("tittle-component",{
props: ["tittle"],
template: `<div>{{tittle}}</div>`
})
//组件
Vue.component("name-component",{
props: ["name"],
template: `<li><input type="text" v-model:value="name" />{{name}}</li>`
})
var vm = new Vue({
el:"#app",
//model层
data: {
tittle : "歌曲",
items: ["不能说的秘密","安静","最熟悉的陌生人"]
}
});
</script>
</body>
</html>
6. 自定义事件
- 自定义事件:Vue中,指自定义一个事件类型(我们知道一般的事件类型有鼠标点下,鼠标放开, 键盘输入等),是区别与普通事件类型的事件
- 应用场景:
- 组件间相互调用函数,组件向model层调用函数
示例
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
</head>
<body>
<div id="box">
<!-- //标签内使用 v-on:自定义事件名="func($event)" $event:传递的数据 -->
<child @myevent="handleMyEvent($event)"></child>
</div>
<script type="text/javascript">
//组件
Vue.component("child",{
template:`<div>
SayHi:<button @click="handleClick('Hi')">send</button>
</div>`,
methods:{
handleClick(message){
window.alert("消息传递:"+ message);
//函数内调用自定义事件 this.$emit("自定义事件名",参数);
this.$emit("myevent",message);
}
}
})
var vm = new Vue({
el:"#box",
methods:{
handleMyEvent(data){
window.alert("我收到了:"+ data);
}
}
})
</script>
</body>
</html>