哈喽你们好,先后端分离系列文章又开始了,今天周一,仍是感谢你们花时间来观看我写的博客,周末呢,没有写文章,可是也没有闲着,主要是研究了下遗留问题,看过以前文章的应该知道,以前的在AOP使用Redis缓存的文章里,遗留了一个问题,周末苦思冥想仍是不得其法,想了一个馊主意,可是确定不是最终解决方案,感兴趣的能够看看,地址《框架之十一 || AOP自定义筛选,Redis入门 11.1》,而后呢,剩下的时间,就是简单搭建了下我在之后的Vue实战中用到的一个小项目,我会手把手在一户的文章中讲到,可是还在搭建中,预计下周能够接触到,由于Vue是从新开始的,因此在基础这一起说的比较多,主要也是但愿都能好好学习下,也是但愿能检查下去,看博客园粉丝破百的时候,能不能有啥小福利啥的哈哈哈html
言归正传,上文我们说到了vue基础的第二章 指令和计算属性,由于时间的问题,上次没有说到Class 与 Style 绑定,那今天我们就简单说说这个绑定样式问题,而后重点说一下 Vue的生命周期,我感受这个仍是比较重要的,由于任何一个Web程序,生命周期都是重中之重,老生常谈的一个话题,今天我们也说说。而后若是有时间,能够简单说下Vue的两大核心之组件(另外一个你们应该也还记得,就是数据驱动,双向数据绑定,就是不用操做DOM的那个,嗯~),好啦,开始今天的讲解吧!vue
以前我们都已经了解到了,Vue是经过Data来控制DOM的,这样能够减小太多的JS操做,从而达到页面的无缝快速渲染的做用,这是一个很好的想法,咱们能够想一下,页面内,除了各类标签的DOM须要操做修改之外,还有哪些因素呢,不过,你应该已经想到了,就是样式!页面的三大元素:HTML+CSS+JS。咱们也可使用相同的办法,经过操做Data来控制样式!对,Vue的设计者们也考虑到了这个问题,因此就出来了动态绑定class和style。操做元素的 class 列表和内联样式是数据绑定的一个常见需求。由于它们都是属性,因此咱们能够用
v-bind
处理它们:只须要经过表达式计算出字符串结果便可。不过,字符串拼接麻烦且易错。所以,在将v-bind
用于class
和style
时,Vue.js 作了专门的加强。表达式结果的类型除了字符串以外,还能够是对象或数组。git
还记得当时咱们给 a 标签是如何添加 src 的?对,就是 v-bind ,它就是用来统一操做页面内各类属性的,因此咱们要修改 class 和 style 也得使用到 v-bind ,这里咱们统一使用他们的缩写 ( :),github
在咱们的博客首页 DEMO 中,咱们都是经过这样的方法定义一个 class编程
<li v-for='item in listSearch' class="post-list-item">
如今咱们须要实现一个删除效果,那就须要给文章列表 list ,动态的增长一个 deleted 的 class ,后端
<!--注意,不能在已经存在的静态类post-list-item上操做--> <li v-for='item in listSearch' class="post-list-item" :class="{ deleted: item.deleted}"> // 注意:若是用三目运算,不要加括 :class="o.cardShow === true ?'class1':'class2'"
var vm = new Vue({ el: '#app',//容器 data: { author: "老张的哲学", task: { name: '',//内容为空 id: 100, date: " Just Now ", finished: false, deleted: false }, list: [ //假数据 { name: " Vue前篇:ES6初体验 & 模块化编程", id: 9585766, date: "2018年9月5日", finished: false, deleted: true },//咱们在这里定义一个删除的true { name: "Vue前篇:JS对象&字面量&this", id: 9580807, date: "2018年9月4日", finished: false, deleted: false }, { name: " VUE 计划书 & 个人先后端开发简史", id: 9577805, date: "2018年9月3日", finished: false, deleted: false }, { name: " DTOs 对象映射使用,项目部署Windows+Linux完整版", id: 3800, date: "2018年9月1日", finished: false, deleted: false }, { name: " 三种跨域方式比较,DTOs(数据传输对象)初探", id: 4200, date: "2018年8月31日", finished: false, deleted: false }, { name: "VUE 计划书 & 个人先后端开发简史", id: 3200, date: "2018年9月2日", finished: false, deleted: false }, { name: "VUE 实战预告", id: 3200, date: "2018年9月12日", finished: false, deleted: false } ], }, } }); <!-- 样式 --> <style> .deleted { color: red; text-decoration: line-through; } </style>
从代码中咱们可看到 :class="{ deleted: item.deleted}",这是一个经过对象定义样式,第一个 deleted ,就是咱们的样式 class ,第二个就是对应咱们的 数据属性。deleted 这个 class 存在与否将取决于数据属性 list 中的 item.deleted 是否为 true,若是为 false,那么这个 class 就不会显示,这就达到了一个动态的效果,固然,你也能够在对象中传入更多属性来动态切换多个 class。跨域
咱们能够看一看结果:数组
咱们能够把一个数组传给 v-bind:class
,以应用一个 class 列表:缓存
<h2 :class="[hrClass,testClass]"> <span>Contact</span> </h2> data: { hrClass: 'hr', testClass:'test', }
运行出来的结果就是酱紫的:网络
所以能够看得出来,数组中的值是咱们的 Data 属性值,经过渲染,加载出咱们对应的真是 class 值,这个在动态多个绑定的时候,仍是颇有用的。
v-bind:style
的对象语法十分直观——看着很是像 CSS,但实际上是一个 JavaScript 对象。CSS 属性名能够用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> data: { activeColor: 'red', fontSize: 30 }
可是这种写法并非很好,由于会定义不少数据属性,因此咱们通常是这么使用的,绑定一个样式对象:
<div v-bind:style="styleObject"></div> data: { styleObject: { color: 'red', fontSize: '13px' } }
这样看起来,像不像咱们把 <style> 中的样式定义,转到了 Data 里,可是好处就是能够控制变化,这个具体的使用仍是看具体的安排,目前我主要是使用的原来的写法,静态的写到 <style> 里,可是须要样式变化的地方,写到 Data 里,仍是很爽快的~
在编程的世界其实和现实世界是同样的,一切皆是对象,都是有生命的,只不过没有感情而已,就比大到一个机器人,它有生命周期(设计,生产,销毁,死亡),也有本身的神经网络,可是若是要是有本身的感情支配的话,啧啧,那就是妥妥的一我的呀 [哭笑],小到一个项目的启动,一个页面的加载,都是由生命周期,Vue把整个生命周期划分为建立、挂载、更新、销毁等阶段,每一个阶段都会给一些“钩子”让咱们来作一些咱们想实现的动做(这个钩子叫法很贴切,很形象的表现了每到一个阶段会钩住,并执行相应的操做,而不会跳跃过去)。学习实例的生命周期,能帮助咱们理解vue实例的运做机制,更好地合理利用各个钩子来完成咱们的业务代码,不一样的时期处理不一样的逻辑,好比 loading 的加载。
其实,在 vue 的整个生命周期内,总共分为8个阶段建立前/后,载入前/后,更新前/后,销毁前/后。
建立前/后: 在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,$el尚未。
载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但仍是挂载以前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,可是dom结构依然存在
咱们分别来看看这几个阶段:
此阶段为实例初始化以后,此时的数据观察和事件配置都没好准备好。咱们试着console一下实例的数据data和挂载元素el,代码以下:
let app = new Vue({ el:"#app", data:{ author: "老张的哲学", }, beforeCreate: function () { console.group('beforeCreate 建立前状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //undefined console.log("%c%s", "color:red", "data : " + this.$data); //undefined console.log("%c%s", "color:red", "author: " + this.author);//undefined
},
});
beforeCreate以后紧接着的钩子就是建立完毕created,咱们一样打印一下数据data
和挂载元素el
,看会获得什么?
created: function () { console.group('created 建立完毕状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //undefined console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
上一个阶段咱们知道DOM还没生成,属性el
还为 undefined,那么,此阶段为即将挂载,页面渲染成功,el 已经赋值
beforeMount: function () { console.group('beforeMount 挂载前状态===============》'); console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
mounted也就是挂载完毕阶段,到了这个阶段,数据就会被成功渲染出来
mounted: function () { console.group('mounted 挂载结束状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
这个时候,你把鼠标放到右侧的 <div> 上,左侧页面就是被选中状态,说明这个就是咱们渲染出来的页面,这就是已经挂载成功了。
这个时候,页面渲染的四个阶段已经完成了,咱们看看流程:(刚开始的时候beforeCreate阶段,数据和页面都没有渲染,可是页面的静态数据已经被加载出来,而后一步一步,先vue实例,而后挂载,到最后页面渲染完成)
当修改vue实例的data时,vue就会自动帮咱们更新渲染视图,在这个过程当中,vue提供了beforeUpdate的钩子给咱们,在检测到咱们要修改数据的时候,更新渲染视图以前就会触发钩子beforeUpdate。
beforeUpdate: function () { console.group('beforeUpdate 更新前状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); debugger;//打断点 },
注意:这里要说下,打断点就是为了能准确看到这个钩子起的做用,不受其余钩子的影响。
由图看来,咱们的 Data 数据已经更新了,可是页面里尚未更新,那何时更新呢,请往下看。
updated: function () { console.group('updated 更新完成状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); },
调用实例的destroy( )
方法能够销毁当前的组件,在销毁前,会触发beforeDestroy钩子。
beforeDestroy: function () { console.group('beforeDestroy 销毁前状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); },
成功销毁以后,会触发 destroyed 钩子,此时该实例与其余实例的关联已经被清除,它与视图之间也被解绑,控制 Data 已经不能控制页面,也没法双向绑定。
destroyed: function () { console.group('destroyed 销毁完成状态===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author) },
这个时候咱们能够看到,vue 实例被销毁后,再修改 Data 页面也已经不能修改页面 DOM 了。
这个时候页面的生命周期已经完成,一共八个时期,你们能够多尝试看看,了解过程。
在以前的文章中,咱们已经简单地介绍了 vue 的两大特性之一数据驱动,咱们这里简单说下另外一个特性 —— 组件。
注册组件就是利用Vue.component()
方法,先传入一个自定义组件的名字,而后传入这个组件的配置。咱们以前说过,在 Vue 中,只有一个初始页面,而后其余的都是经过路由将各个不一样的组件联系在一块儿,大体以下图:
// 定义一个名为 footer-vue 的新组件 Vue.component('footer-vue', { template: ` <div id="footer-vue"> <p>2018 <a href="#">LZ's Blog</a> - Hosted by <a href="#" style="font-weight: bold">Coding Pages</a></p> <p> <a href="#">京ICP备00000000号</a> </p> </div> ` })
还记得如何定义一个模板么,用反引号 ``,包裹。
<div id="app"> <div>.......</div> <footer-vue></footer-vue> <div class="layout-bg"></div> </div> <script> new Vue({ el: '#app' }) </script>
今天呢,暂时就说下如何定义一个组件,明天我们再深刻了解下组件。
今天呢,我们就说到这里啦,经过动态 class 和 style 绑定,我们了解到能够像经过操做Data来绑定页面元素同样的,操做页面的全部样式;经过简单了解 Vue 的生命周期的八个阶段,能够在以后的开发中,针对不一样的阶段采起不一样的操做,最后简单说了下如何定义并使用一个 全局组件,那如何定义一个局部组件、如何更好的实现复用组件、父子组件之间又是如何通讯、又是如何统一管理组件系统的,我们明天再见吧~~~