个人Vue学习笔记css
MVVM是Model-View-ViewModel的简写,即:模型-视图-视图模型.
模型是指后端传递的数据
视图是指咱们看到的页面
视图模型则是MVVM思想的核心部分,它连接了View和Model并做为它们之间通讯的桥梁,它有两个方向:一是将Model转化为View,即后端传递的数据转化成看到的页面,二则是将View转化为Model,也就是将用户操做在页面上的内容转化为后端的数据,这两个功能是经过数据绑定以及DOM事件监听来实现的,咱们称之为数据的双向绑定。如图所示:
html
vue 建立实例的方法以下:vue
<div id="app">
{{myData}}
</div>
<script>
var vueApp = new Vue({
el:'#app',
data:{
myData:'Hello World'
myData2:'Fuck World'
}
});
</script>
复制代码
代码中 el 和 data 都是vue实例的属性,el 用于指定页面当中已存在的用来挂载Vue实例的DOM元素,data则是Vue须要双向绑定的数据。后端
当挂载后,咱们可使用 vue实例.$vue实例的属性
这样的语法来获取vue实例的属性,例如: vueApp.$el
,访问data中的属性则不一样,咱们能够直接使用vue实例.data的属性名
这样的语法来访问,例如:vueApp.myData
数组
vue生命周期钩子是在Vue对象生命周期的某一个阶段执行的已定义的方法。从初始化vue实例对象,到它被销毁,对象会遵循不一样的生命阶段,具体内容我截了一张很著名的生命周期钩子图:
浏览器
vue生命周期有不少阶段,可是咱们最经常使用到的是这三个阶段:缓存
举例说明:bash
var vueApp = new Vue({
el:'#app',
data:{
myData:'Hello World'
},
created:function () {
alert('vue实例建立完毕了,可是尚未挂载到DOM元素上');
},
mounted:function () {
alert('vue实例已经挂载到DOM上了');
}
});
复制代码
对于上述示例页面来讲,打开浏览器,首先会弹出"vue实例建立完毕了,可是尚未挂载到DOM元素上"这样的提示信息,对于created 这个阶段来讲,实际上已经完成了vue实例的建立,可是并无挂载至DOM元素上,而后会弹出“vue实例已经挂载到DOM上了”的提示框,mounted阶段是vue建立的实例挂载到DOM后进行调用的,咱们的第一个业务逻辑也一般会在这里开始,对于beforeDestory 阶段,经过字眼意思也能够知道 这是vue实例销毁前的阶段,经过会在这个阶段进行解绑一些监听事件。app
对于本示例来说,咱们会在页面上看到Hello World 的字样,在html中,咱们书写了这样的语法:框架
<div id="app">
{{myData}}
</div>
复制代码
这种语法就是Vue的文本插值语法,它支持单个表达式,注意只是单个表达式:
{{1<0 ? myData:myData2}}
这是三元运算符表达式,由于它属于单个表达式
因此这是合法的,咱们会在页面上看到Fuck World
{{var a = 6}}
注意:这是非法的
var a = 6 是一个声明表达式 + 一个赋值表达式
咱们提到过 Vue 的文本插值语法只支持单个表达式
因此 这句话会报错
复制代码
vue.js 支持在{{}}插值的尾部添加一小管道符" | "对数据进行过滤,常常用于格式化文本,好比字母所有大写、货币千位使用逗号分隔等,同时也支持过滤器串联写法,传参等等。咱们来看一个示例:
页面实时显示当前时间:
<div id="app">
{{currentDate | format}}
</div>
<script>
function formatTime(value) {
return value <10 ? '0'+value : value;
}
var vueApp = new Vue({
el:'#app',
data:{
currentDate: new Date()
},
filters:{
format:function (currentDate) {
var date = new Date(currentDate);
var year = date.getFullYear(); // 获取当前年
var month = formatTime(date.getMonth()+1); // 获取当前月(须要+1)
var days = formatTime(date.getDate()); // 获取当前天
var hours = formatTime(date.getHours()); // 获取当前小时
var minutes = formatTime(date.getMinutes()); // 获取当前分钟
var seconds = formatTime(date.getSeconds()); // 获取当前秒
return '当前时间为:'+year+'年'+month+'月'+days+'日'+hours+'时'+minutes+'分'+seconds+'秒'
}
},
mounted:function () {
this.timer = setInterval(()=>{
this.currentDate = new Date();
},1000)
},
beforeDestroy:function () {
window.clearInterval(this.timer);
}
});
</script>
复制代码
咱们还能够对过滤器进行传参,咱们将代码作一个小小的改动:
<div id="app">
{{currentDate | format('当前时间为',':')}}
</div>
<script>
function formatTime(value) {
return value <10 ? '0'+value : value;
}
var vueApp = new Vue({
el:'#app',
data:{
currentDate: new Date()
},
filters:{
format:function (currentDate,arg1,arg2) {
var date = new Date(currentDate);
var year = date.getFullYear(); // 获取当前年
var month = formatTime(date.getMonth()+1); // 获取当前月(须要+1)
var days = formatTime(date.getDate()); // 获取当前天
var hours = formatTime(date.getHours()); // 获取当前小时
var minutes = formatTime(date.getMinutes()); // 获取当前分钟
var seconds = formatTime(date.getSeconds()); // 获取当前秒
return arg1+arg2+year+'年'+month+'月'+days+'日'+hours+'时'+minutes+'分'+seconds+'秒'
}
},
mounted:function () {
this.timer = setInterval(()=>{
this.currentDate = new Date();
},1000)
},
beforeDestroy:function () {
window.clearInterval(this.timer);
}
});
</script>
复制代码
咱们在过滤器中加入了参数,获得了和以前同样的结果。这里面须要注意的是:过滤器对应的函数中第一个传入的值是 “ | ” 前的data中的属性值,在本例中即:currentDate ,而并不是是参数,传入的参数是在函数的第二个传递值及之后的值。同时过滤器也可使用"串联写法" ,如:{{currentDate | filter1 | filter2 | filter3 }}
,过滤器的方法会依次执行,而且它们都被定义在 vue的属性 filters 当中。
支持指令操做是vue框架的优势之一,它是vue模板中最经常使用的一项功能,省去了复杂的DOM API,而且及其方便记忆和理解。接下来咱们先简单了解一些指令操做:
v-text
v-text 的功能是解析文本 它的具体做用和文本插值{{}}是一毛同样的
v-html
将内容解析成html
v-bind
动态更新HTML上的元素,例如id,class等等
v-on
用来绑定事件监听
接下来咱们依旧经过示例,来简单认识这几个指令事件。
<style>
.active{
background: red;
height: 1em;
}
</style>
---------------------------------------------------------------
<div id="app">
v-text: <br>
{{apple}} <br>
<!--v-text 的做用和文本插值 是同样的-->
<span v-text="apple"></span>
v-html: <br>
<span v-html="banana"></span> <br>
v-bind: <br>
<div v-bind:class="className"></div>
v-bind的简写格式: <br>
<div :class="className"></div>
v-on: <br>
<button v-on:click="plusOne">{{originalNum}}</button>
<br>
v-on的简写格式: <br>
<button @click="plusOne">{{originalNum}}</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
apple:'苹果',
banana:'<span style="color: yellow;">香蕉</span>',
className:'active',
originalNum:0
},
methods:{
plusOne:function () {
this.originalNum = this.originalNum + 1;
}
}
});
</script>
复制代码
部分html内容如上,对于 v-bind 和 v-on 两个指令 都有响应的简写格式,如示例中:
<div v-bind:class="className"></div>
能够简写为:
<div :class="className"></div>
<button v-on:click="plusOne">{{originalNum}}</button>
能够简写为:
<button @click="plusOne">{{originalNum}}</button>
复制代码
先看一个示例:咱们要实现一个功能 反转字符串,对于字符串 '123,456,789' 咱们要将字符串变为: '321,654,987' ,示例程序以下:
<div id="app">
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
}
});
</script>
复制代码
咱们看到这个程序内心必定一句妈卖批,程序虽然没有什么问题,也符合文本插值的语法,可是看起来就是以为很头疼,而且这样写的代码也很差进行维护。咱们能够将内容作一个优化,建立一个函数并将函数放在methods属性当中:
<div id="app">
<!--将'123,456,789' 这串字符串 变为 '321,654,987'-->
使人头痛的代码: <br>
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}} <br>
methods属性内的方法: <br>
{{reverseMethod()}} <br>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
},
methods:{
reverseMethod:function () {
// ['123',456,'789']
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('');
}).join(',');
}
}
});
</script>
复制代码
除了将方法定义在methods中并调用,咱们还可使用计算属性:
<div id="app">
<!--将'123,456,789' 这串字符串 变为 '321,654,987'-->
使人头痛的代码: <br>
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}} <br>
methods属性内的方法: <br>
{{reverseMethod()}} <br>
计算属性: <br>
{{reverseText}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
},
methods:{
reverseMethod:function () {
// ['123',456,'789']
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('');
}).join(',');
}
},
computed:{
reverseText:function () {
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('')
}).join(',');
}
}
});
</script>
复制代码
咱们将方法定义在了 vue示例的computed 属性当中,乍一看 和 methods并无什么区别,实际上 计算属性能够实现的东西 在methods方法中 均可以实现 ,可是两者也是有差异的。具体的差异,咱们在看完另外一个示例后,再来介绍:
本示例的功能是对购物车的价格总和进行计算,具体代码以下:
<div id="app">
{{prices}}
</div>
<script>
var app2 = new Vue({
el:'#app2',
data:{
msg:'两个购物车的价格总和为:'
}
});
var app = new Vue({
el:'#app',
data:{
// 购物车1
package1:[
{
name:'iphone',
price:6999,
count:2
},
{
name:'ipad',
price:3299,
count:2
}
],
// 购物车 2
package2:[
{
name:'XiaoMi',
price:999,
count:6
},
{
name:'ipod',
price:1099,
count:2
}
]
},
computed:{
prices:{
get:function () {
var prices = 0;
// 第一个购物车的价格总和
for(var i = 0;i<this.package1.length;i++){
prices += this.package1[i].price * this.package1[i].count;
}
// 第一个购物车与第二个购物车的价格总和
for(var j = 0; j<this.package2.length;j++){
prices += this.package2[j].price * this.package2[j].count;
}
return app2.msg+prices;
},
set:function (options) {
if(options.package === 'package1'){
for(var i = 0;i<this.package1.length;i++){
if(this.package1[i].name === options.name){
this.package1[i].price = options.price;
this.package1[i].count = options.count;
break;
}
}
}else if(options.package === 'package2'){
for(var i = 0;i<this.package2.length;i++){
if(this.package2[i].name === options.name){
this.package2[i].price = options.price;
this.package2[i].count = options.count;
break;
}
}
}
}
}
}
});
</script>
复制代码
每个计算属性都有一个getter和 setter方法,当咱们仅仅是调用了计算属性的方法名时,实际上调用的是 该属性的get 方法,当有必要设置一些参数时,咱们也能够提供一个 set方法手动修改计算属性。另外在本示例中,咱们能够看到 计算属性 prices不只依赖了当前vue对象 并且也依赖了其余的实例,尽管 app2 并无挂载到DOM上,可是执行的结果代表 计算属性能够依赖于其余的实例。 代码执行的结果以下:
咱们首先来看一个示例:
<div id="app">
{{text}} <br>
{{getNow()}} <br>
{{now}} <br>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:666
},
methods:{
getNow:function () {
return Date.now();
}
},
computed:{
now:{
get:function () {
return Date.now(); // 获取 1970年 至如今的时间戳
}
}
}
});
</script>
复制代码
咱们在 methods 方法以及 计算属性中都定义了获取 1970年到如今为止的时间戳的函数 ,代码运行的结果以下:
v-bind 的做用只用一句话就能够描述,那就是绑定活的属性,咱们经过一个简单的示例来回顾一下:
<div id="app">
<a v-bind:href="url">连接</a>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
url:'http://www.baidu.com'
}
});
</script>
复制代码
页面点击链接后则会跳转到baidu。
见示例:
<style>
.red{
background: red;
}
.blue{
background: blue;
}
</style>
--------------------------------------------------
<div id="app">
v-bind绑定对象: 对象的key是类名,对象的value是布尔值<br>
<button v-bind:class="{red:isRed,blue:isBlue}" v-on:click="transColor">clickMe</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isRed:true,
isBlue:false,
},
methods:{
transColor:function () {
this.isRed = !this.isRed;
this.isBlue = !this.isBlue;
}
}
});
</script>
复制代码
本示例实现的功能是一个按下去能转换颜色的按钮,同时v-bind:class使用的是对象语法,对象的key为 类名 对象的value则是布尔值,若是值为true则绑定这个类名,若是值为false则和此类名无关联。
见示例:
<style>
.red{
width: 100px;
height: 100px;
background: red;
}
</style>
-----------------------------------------------
<div id="app">
v-bind绑定计算属性: 计算属性返回的也是对象 key为类名 ; value为 布尔值 <br>
<div v-bind:class="computedClass"></div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isRed:true,
},
computed:{
computedClass:function () {
return {
red:'isRed'
}
}
}
});
</script>
复制代码
示例中 v-bind:class绑定了计算属性,可是即使为计算属性,返回的结果也是对象,对象中key为类名,value为布尔值,同上 当value值为真时,元素携带这个类,当value值为false时,元素则不携带这个类
见示例:
<style>
.first{
font-size: 32px;
color: red;
}
.second{
background: #000;
}
</style>
---------------------------------------
<div id="app">
绑定class数组语法:数组中的成员为data中的属性,这些属性直接对应类名 <br>
<div v-bind:class="[classOne,classTwo]">VUE is cool!</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
classOne:'first',
classTwo:'second'
}
});
</script>
复制代码
v-bind绑定class数组的语法相比于前面而言更加简单,数组中的成员为data中的属性,这些属性直接对应类名,经过示例应该不难看懂~
除了绑定class较为经常使用,v-bind也能够绑定内联样式
<div id="app">
绑定内联样式:对象语法,key 表明style的属性,value表明属性对应的值 br>
<div v-bind:style="{'color':color,'fontSize':fontSize}">VUE is cool!</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
color:'red',
fontSize:'32px'
}
});
</script>
复制代码
除了这种对象语法以外,绑定内联样式也支持"数组"语法,可是听说这种语法比较蠢,由于谁也不会把样式分开写,因此我就不在这里列出来了。须要注意的是 css属性名称 使用驼峰命名,或者是短横线分隔命名,可是这里面仍是推荐驼峰式写法~~~~