回顾

哈喽大家好,前后端分离系列文章又开始了,今天周一,还是感谢大家花时间来观看我写的博客,周末呢,没有写文章,但是也没有闲着,主要是研究了下遗留问题,看过之前文章的应该知道,之前的在AOP使用Redis缓存的文章里,遗留了一个问题,周末苦思冥想还是不得其法,想了一个馊主意,但是肯定不是最终解决方案,感兴趣的可以看看,地址《框架之十一 || AOP自定义筛选,Redis入门 11.1》,然后呢,剩下的时间,就是简单搭建了下我在以后的Vue实战中用到的一个小项目,我会手把手在一户的文章中讲到,但是还在搭建中,预计下周可以接触到,因为Vue是重新开始的,所以在基础这一块儿说的比较多,主要也是希望都能好好学习下,也是希望能检查下去,看博客园粉丝破百的时候,能不能有啥小福利啥的哈哈哈

言归正传,上文咱们说到了vue基础的第二章 指令和计算属性,因为时间的问题,上次没有说到Class 与 Style 绑定,那今天咱们就简单说说这个绑定样式问题,然后重点说一下 Vue的生命周期,我感觉这个还是比较重要的,因为任何一个Web程序,生命周期都是重中之重,老生常谈的一个话题,今天咱们也说说。然后如果有时间,可以简单说下Vue的两大核心之组件(另一个大家应该也还记得,就是数据驱动,双向数据绑定,就是不用操作DOM的那个,嗯~),好啦,开始今天的讲解吧!

零、今天完成右下角橙色的部分

一、动态绑定class和style

之前咱们都已经了解到了,Vue是通过Data来控制DOM的,这样可以减少太多的JS操作,从而达到页面的无缝快速渲染的作用,这是一个很好的想法,我们可以想一下,页面内,除了各种标签的DOM需要操作修改以外,还有哪些因素呢,不过,你应该已经想到了,就是样式!页面的三大元素:HTML+CSS+JS。我们也可以使用相同的办法,通过操作Data来控制样式!对,Vue的设计者们也考虑到了这个问题,所以就出来了动态绑定class和style。操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

1、通过对象的方式动态修改页面内的 class,来实现删除效果

还记得当时我们给 a 标签是如何添加 src 的?对,就是 v-bind ,它就是用来统一操作页面内各种属性的,所以我们要修改 class 和 style 也得使用到 v-bind ,这里我们统一使用他们的缩写 ( :),

在我们的博客首页 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: , date: " Just Now ", finished: false, deleted: false }, list: [ //假数据 { name: " Vue前篇:ES6初体验 & 模块化编程", id: , date: "2018年9月5日", finished: false, deleted: true },//我们在这里定义一个删除的true { name: "Vue前篇:JS对象&字面量&this", id: , date: "2018年9月4日", finished: false, deleted: false }, { name: " VUE 计划书 & 我的前后端开发简史", id: , date: "2018年9月3日", finished: false, deleted: false }, { name: " DTOs 对象映射使用,项目部署Windows+Linux完整版", id: , date: "2018年9月1日", finished: false, deleted: false }, { name: " 三种跨域方式比较,DTOs(数据传输对象)初探", id: , date: "2018年8月31日", finished: false, deleted: false }, { name: "VUE 计划书 & 我的前后端开发简史", id: , date: "2018年9月2日", finished: false, deleted: false }, { name: "VUE 实战预告", id: , 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。

我们可以看一看结果:

2、通过数组的方式动态修改页面内的 class,主要的多个样式的时候

我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

 <h2 :class="[hrClass,testClass]">
<span>Contact</span>
</h2> data: {
hrClass: 'hr',
testClass:'test', }

运行出来的结果就是酱紫的:

因此可以看得出来,数组中的值是我们的 Data 属性值,通过渲染,加载出我们对应的真是 class 值,这个在动态多个绑定的时候,还是很有用的。

3、绑定内联样式style

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize:
}

但是这种写法并不是很好,因为会定义很多数据属性,所以我们一般是这么使用的,绑定一个样式对象:

<div v-bind:style="styleObject"></div>

data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}

这样看起来,像不像我们把 <style> 中的样式定义,转到了 Data 里,但是好处就是可以控制变化,这个具体的使用还是看具体的安排,目前我主要是使用的原来的写法,静态的写到 <style> 里,但是需要样式变化的地方,写到 Data 里,还是很爽快的~

二、探究 Vue 实例的生命周期

在编程的世界其实和现实世界是一样的,一切皆是对象,都是有生命的,只不过没有感情而已,就比大到一个机器人,它有生命周期(设计,生产,销毁,死亡),也有自己的神经网络,但是如果要是有自己的感情支配的话,啧啧,那就是妥妥的一个人呀 [哭笑],小到一个项目的启动,一个页面的加载,都是由生命周期,Vue把整个生命周期划分为创建、挂载、更新、销毁等阶段,每个阶段都会给一些“钩子”让我们来做一些我们想实现的动作(这个钩子叫法很贴切,很形象的表现了每到一个阶段会钩住,并执行相应的操作,而不会跳跃过去)。学习实例的生命周期,能帮助我们理解vue实例的运作机制,更好地合理利用各个钩子来完成我们的业务代码,不同的时期处理不同的逻辑,比如 loading 的加载。

0、首先我们看一下这个经常出现的图片,其实简单看一下,也就大概明白了

其实,在 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结构依然存在

我们分别来看看这几个阶段:

1、beforeCreate —— 创建之前

此阶段为实例初始化之后,此时的数据观察和事件配置都没好准备好。我们试着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
  }, 

});

2、created —— 创建完成

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); //已被初始化
},

3、beforeMount —— 准备挂载( 挂载成功才能去渲染页面 )

上一个阶段我们知道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); //已被初始化
},

4、mounted —— 挂载完毕,页面渲染完成

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实例,然后挂载,到最后页面渲染完成)


5、beforeUpdate —— 更新前(修改Data,但未渲染至页面)

当修改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 数据已经更新了,但是页面里还没有更新,那什么时候更新呢,请往下看。

6、updated —— 更新数据,页面渲染

  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);
},

7、beforeDestroy —— 页面销毁前

调用实例的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);
},

8、destroyed —— 销毁完成

成功销毁之后,会触发 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 的两大特性之一数据驱动,我们这里简单说下另一个特性 —— 组件。

注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传入这个组件的配置。我们之前说过,在 Vue 中,只有一个初始页面,然后其他的都是通过路由将各个不同的组件联系在一起,大致如下图:

1、这里简单说下如何定义一个组件,这里我们定义一个页脚组件( 注意:一定要写在 Vue 实例之前 )

 // 定义一个名为 footer-vue 的新组件
Vue.component('footer-vue', {
template: `
<div id="footer-vue">
<p> <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>
`
})

还记得如何定义一个模板么,用反引号 ``,包裹。

2、然后在 Vue 定义的元素内的任何一个地方,使用页脚组件

 <div id="app">
<div>.......</div> <footer-vue></footer-vue> <div class="layout-bg"></div>
</div> <script>
new Vue({
el: '#app'
})
</script>

3、这时候就可以看到页面效果了

今天呢,暂时就说下如何定义一个组件,明天咱们再深入了解下组件。

四、结语

今天呢,咱们就说到这里啦,通过动态 class 和 style 绑定,咱们了解到可以像通过操作Data来绑定页面元素一样的,操作页面的所有样式;通过简单了解 Vue 的生命周期的八个阶段,可以在之后的开发中,针对不同的阶段采取不同的操作,最后简单说了下如何定义并使用一个 全局组件,那如何定义一个局部组件、如何更好的实现复用组件、父子组件之间又是如何通信、又是如何统一管理组件系统的,咱们明天再见吧~~~

五、CODE

https://github.com/anjoy8/Blog.Vue/tree/master/Demo/Vue_17

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十九║Vue基础: 样式动态绑定+生命周期的更多相关文章

  1. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║Vue基础:JS面向对象&字面量& this字

    缘起 书接上文<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史>,昨天咱们说到了以我的经历说明的web开发经历的 ...

  2. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十六 ║Vue基础:ES6初体验 & 模块化编程

    缘起 昨天说到了<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║ Vue前篇:JS对象&字面量&this>,通过总体来看,好像大家对这一块不是很 ...

  3. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十八║Vue基础: 指令(下)+计算属性+watch

    回顾 今天来晚辣,给公司做了一个小项目,一个瀑布流+动态视频控制的DEMO,有需要的可以联系我,公司的项目就不对外展示了(一个后端程序员真的要干前端了哈哈哈). 书接上文,昨天正式的开始了Vue的代码 ...

  4. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单

    前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...

  5. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史

    ---新内容开始--- 番外 大家周一好呀,又是元气满满的一个周一呀!感谢大家在周一这个着急改Bug的黄金时期,抽出时间来看我的博文哈哈哈,时间真快,已经到第十四篇博文了,也很顺顺(跌跌)利利 (撞撞 ...

  6. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】

    缘起 哈喽大家好,兜兜转转终于来到了Vue实战环节,前边的 6 篇关于Vue基础文章我刚刚简单看了看,感觉写的还是不行呀,不是很系统,所以大家可能看上去比较累,还是得抽时间去润润色,修改修改语句和样式 ...

  7. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十四║ Vuex + JWT 实现授权验证登录

    壹周回顾 哈喽,又是元气满满的一个周一,又与大家见面了,周末就是团圆节了,正好咱们的前后端也要团圆了,为什么这么说呢,因为以后的开发可能就需要前后端一起了,两边也终于会师了,还有几天Vue系列就基本告 ...

  8. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十五║初探SSR服务端渲染(个人博客二)

    缘起 时间真快,现在已经是这个系列教程的下半部 Vue 第 12 篇了,昨天我也简单思考了下,可能明天再来一篇,Vue 就基本告一段落了,因为什么呢,这里给大家说个题外话,当时写博文的时候,只是想给大 ...

  9. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明

    缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ...

随机推荐

  1. 如何把Python脚本导出为exe程序

    一.pyinstaller简介 pyinstaller将Python脚本打包成可执行程序,使在没有Python环境的机器上运行 最新版是pyinstaller 3.1.1.支持python2.7和py ...

  2. scrapy分布式爬虫scrapy_redis二篇

    =============================================================== Scrapy-Redis分布式爬虫框架 ================ ...

  3. MAC下的mysql忘记密码该怎么办??

    不要着急,不要慌,好多人会忙手忙脚,以为自己安装了一个假软件,其实是你打开的方式不对而已! step1: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击 ...

  4. 2个byte类型数据相加(转型问题的分析)

    转自https://blog.csdn.net/alinshen/article/details/53571857 今天看到网上有网友问到关于final修饰的面试题目,题目如下: <span s ...

  5. CocoaPods 安装 使用&常见操作错误

    CocoaPods 安装 使用 1.开启 terminal 2.移除现有 Ruby 默认源 $ gem sources --remove https://rubygems.org/ 3.使用新的源 $ ...

  6. 谈谈.NET架构师面试及如何设计面试题

    上星期:应老东家的要求,帮其面试.NET架构师. 于是:老东家进行了一星期的简历收集: 终于:在一堆简历里,精挑细选了四个: 约了:周末上午下午各两个. 面试者年龄:在30-35岁左右,差不多10年. ...

  7. Python 命令行(CLI)基础库

    在 CLI 下写 UI 应用 前阵子看了一下自己去年写的 Python-视频转字符动画,感觉好糗..所以几乎把整篇文章重写了一遍.并使用 curses 库实现字符动画的播放. 但是感觉,curses ...

  8. ES 19 - Elasticsearch的检索语法(_search API的使用)

    目录 1 Search API的基本用法 1.1 查询所有数据 1.2 响应信息说明 1.3 timeout超时机制 1.4 查询多索引和多类型中的数据 2 URI Search的用法 2.1 GET ...

  9. 我眼中的 Nginx(三):Nginx 变量和变量插值

    张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...

  10. C#读写EXCEL单元格的问题

    最近, 我在用C#开发一个EXCEL Add-In的时候,发现了一些害人不浅的坑,特来总结列举如下: 这里我读写EXCEL引用的是using Excel = Microsoft.Office.Inte ...