哈喽.我是慕筱佳,通过前几篇文章的学习,我们学习了一些系统指令,事件还有生命周期,接下来笔者将会带领你们走进更深的vue世界.
1.MVVM设计模式
vue是一个渐进式框架,其遵循MVVM设计模式,提到MVVM或许很多人会很陌生,这也是目前前端三大主流框架比较流行的设计模式,接下来让我们看看这个设计模式到底是什么?MVVM其实就是Model-View-ViewModel的缩写,它本质上市MVC的改进版,将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。主要的目的就是分离视图和模型.
<div id="app">
<h1>{{msg}}</h1>
</div>
<script>
new Vue({
el:"#app",
data:{
msg:"慕筱佳"
}
})
</script>
2.MVVM的优点
1.低耦合
视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2.可重用性
你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
3.独立开发
开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
4.可测试
界面素来是比较难于测试的,测试可以针对ViewModel来写。
3.watch侦听器
对于watch监听器而言,其实本质是一个特殊的函数,主要是用来监视data中的某个数据的变化,从而做除一些逻辑的处理.并且不需要手动调用,监听器分为普通监听和深度监听.
1.watch侦听器的函数名必须和被监视的数据名保持一致
2.不能滥用watch侦听器, 因为会有性能开销
普通监听器:
new Vue({
el: "#app",
data: {
msg: 'hello'
},
//监听器
watch: {
msg(newValue, oldValue) {
console.log(newValue, oldValue);
}
}
})
深度监听器:
watch: {
//比如要监听user数据
user:{
// oldVal:系统自动注入,更新之前的值
// newVal: 系统自动注入, 更新之后的值
handler(newVal,oldVal) {
console.log(newVal,oldVal);
},
//watch监听对象的时候,需要加deep:true,只有这样才能深入底层去实时监听,
//没有加的话,对象是监听不到变化的,添加immediate时会在侦听开始之后被立即调用
deep:true,
immediate: true
}
}
4.computed计算属性
在 computed 中,可以定义一些 属性,这些属性,叫做 【计算属性】, 计算属性的本质,就是 一个方法,只不过我们在使用 这些计算属性的时候,是把它们的名称直接当作属性来使用的;并不会把 计算属性当作方法去调用.
在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。所以计算属性中的方法必须要有返回值.而且存在缓存.对于性能开销比较友好.
<div id="app">
<input type="text" v-model="firstname"><br />
<input type="text" v-model="lastname">
<h2>{{fullname}}</h2>
</div>
new Vue({
el: "#app",
data: {
firstname: "",
lastname: ''
},
//计算属性
computed: {
fullname() {
//必须要有返回值
return this.firstname + this.lastname;
}
}
})
computed相比methods来说,最大的优点就是计算属性存在缓存机制
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。 所以出于对性能的考虑,计算属性是比较好的.
注意 : 1.计算属性调用的时候是当做数据调用 2. 计算属性方法名, 不能和data中的数据同名
5.过滤器filter
过滤器实际是一种特殊的方法,主要用来对将要输出的数据进行预处理,定义的过滤器必须要有返回值,并且过滤器的第一个形参永远是待处理的数据(由系统自动注入),
vue中的过滤器分为两种:全局过滤器和局部过滤器.
过滤器只能在插值表达式和v-bind指令中使用,调用的时候通过管道符 | 来调用.
全局过滤器
在任何地方都可以使用
<body>
<div id="app">
<h1>{{msg}}</h1>
调用全局过滤器
<h1>{{msg | change}}</h1>
</div>
<script>
//定义全局过滤器
Vue.filter("change", data => {
//必须返回索要处理的数据
return data.toUpperCase();
})
new Vue({
el: "#app",
data: {
msg: "hello world"
}
})
</script>
</body>
局部过滤器
定义在vue实例中的过滤器为局部过滤器, 不能在vue实例对象的外面使用.
<div id="app">
<h1>{{time | dateFmt}}</h1>
<h1>{{msg | reverse}}</h1>
<h1>{{str | uppPer}}</h1>
</div>
new Vue({
el: "#app",
data: {
},
filters: {
dateFmt(time, divider = "/") {
const date = new Date(time);
const y = date.getFullYear(); //年
const m = date.getMonth() + 1; //月
const d = date.getDate(); //日
const h = date.getHours(); //时
const mm = date.getMinutes(); //分
const ss = date.getSeconds(); //秒
return `${y}${divider}${m}${divider}${d} ${h}:${mm}:${ss}`;
},
//处理字符串反转的过滤器
reverse(str) {
return str.split("").reverse().join("");
},
//转换为大写
uppPer(data) {
return data.toUpperCase();
}
}
1、 当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
2、 一个表达式可以使用多个过滤器。过滤器之间需要用管道符“|”隔开。其执行顺序从左往右
6.组件components
组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。根据项目需求,抽象出一些组件,每个组件里包含了展现、功能和样式。每个页面,根据自己所需,使用不同的组件来拼接页面。这种开发模式使前端页面易于扩展,且灵活性高,而且组件之间也实现了解耦。
在vue中,一个组件本质是一个拥有预定义选项的一个 Vue 实例
<myheader></myheader>
<navbar></navbar>
上面的自定义标签其实就是vue中的组件.组件以一个自定义标签的形式存在,起到占位符的功能。通过Vue.js的声明式渲染后,占位符将会被替换为实际的内容.
vue组件分为全局组件和局部组件
6-1.组件命名规范
1.构建组件对象
// 组件对象
const myheader = {
template: `
<div>{{title}}</div>
`,
data() {
//在组件内部的data必须是一个函数
return {
title: "头部"
}
}
}
2.注册组件时,如果全局注册,则为全局组件,如果局部注册,则为局部组件
//注册全局组件
Vue.component("myheader", myheader);
new Vue({
el: "#app",
//注册局部组件
//局部组件只能在vue实例中使用
components: {
myheader
}
})
3.使用组件
<div id="app">
<myheader></myheader>
</div>
6-3.组件嵌套
<body>
<div id="app">
<button @click="get">按钮</button>
<navbar></navbar>
</div>
<script>
new Vue({
el: "#app",
data: {
title: "我是头部"
},
components: {
"navbar": {
template: `<div>
<h1>{{navTitle}}</h1>
<child-bar></child-bar>
</div>`,
data() {
return {
navTitle: "我是导航"
}
},
components: {
"childBar": {
template: `
<div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
`,
data() {
return {
list: ["首页", "音乐", "影视"]
}
},
methods: {
//这里是组件childBar的方法
}
}
}
},
},
methods: {
get() {
console.log("get...");
}
}
})
</script>
</body>
在组件嵌套中,要特别注意几点:
- 组件中的data必须为一个函数
- 组件中的私有数据必须要经过通信才能使用,不然通过this是无法拿到私有组件中的数据的.
6-4.论data必须为函数【面试题】
组件是可复用的vue
实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data
数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data
数据就应该被复制一次,之后,当某一处复用的地方组件内data
数据被改变时,其他复用地方组件的data
数据不受影响.6-5.动态组件
vue提供内置的组件对象,为了更好的动态展示组件.
is: 指定需要展示的组件名称, 一般需要使用v-bind动态绑定<component is="组件名称"></component>
6-6.缓存组件keep-alive
在vue2.0中提供了keep-alive组件,目的是为了对组件进行缓存,提高性能.只需要用keep-alive将目标组件包裹起来即可.
在keep-alive组件中,提供了特殊的生命周期钩子函数,只有在被缓存的组件中才存在.<!-- 缓存组件 -->
<keep-alive>
<!-- 动态组件 -->
<component :is="page"></component>
</keep-alive>
但是这种方法有bug,后续笔者会对以上bug做出解决方案.如果你的项目只有一种状态需要被缓存时,可以考虑使用这种方法.activated(){
console.log('Home组件被激活');
},
deactivated(){
console.log('Home组件被失活');
}