为什么要学习流行框架
- 企业为了提高开发效率:在企业中,时间就是效率,效率就是金钱;
- 企业中,使用框架,能够提高开发的效率;
- 提高开发效率的发展历程:原生JS -> Jquery之类的类库->前端模板引擎-> Angular.js /Vue.js (能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念[通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心DOM是如何渲染的了] )
- 在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时
间去关注业务逻辑; - 增强自己就业时候的竞争力
- 人无我有,人有我配
- 你平时不忙的时候,都在干嘛?
框架和库的区别
- 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。
- node中的express
- 库〈插件) :提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。.
- 1.从Jquery切换到Zepto
- 2.从EJS切换到art-termplace
Node (后端)中的MVC与前端中的MVVM之间的区别
- MVC是后端的分层开发概念;
- MVVM是前端视图层的概念,主要关注于视图层分离,也就是说: MVVM把前端的视图层,分为了三部分Model, View,VM ViewModel
-
为什么有了MVC还要有MVVM
-
一 : vue简介
1. 什么是vue
vue一词是法语,同英语中的view。
vue.js是一套构建用户界面的MVVM框架。vue的核心库只关注视图层,经常与其他库或者已有的项目整合
MVVM简介 : 见vue特性
2. vue的目的
1). 解决数据绑定问题
2). vue框架生产的主要目的是为了开发大型单页应用(SPA:single page appliacation),对移动端支持较好,PC端也支持,而angular对PC端支持好,移动端支持不是很好
3). vue支持组件化(方便复用),也就是将页面封装成若干个组件,采用积木式编程,使页面的复用度达到最高。实现一次开发多次复用的目的
SPA简介 :在制作APP时,需要运用Android程序员,iOS程序员和.net程序员(Windows phone),很浪费财力物力,于是人们想用HTML5开发APP,但是遇到一个问题:从一个页面调到另一个页面会消耗很长的时间。解决方法是将APP所用到的所有页面构建出来放到一个网页上,根据JavaScript按照一定的规则来控制到底显示哪一个页面,所有切换通过router完成,这就是单页面应用。所以SPA主要是解决H5做APP卡顿的问题。
3. vue的特性
一:vue中的两个核心点
响应的数据绑定
当数据发生改变时,自动更新视图
为什么自动更新:利用Object.definedProperty中的getter/setter代理数据,监控对数据的操作。
注意:由于Object.defineproperty是ES5出现的,所以vue不支持IE8
组合的视图组件
UI界面映射为组件树
划分组件可维护,可重用,可测试
二:渐进式框架
我们开发一个页面,组件,大型的单页面等,不需要全部应用,用到哪个用哪个就行
三:虚拟DOM
产生原因:运行js的速度是很快的,但大量的DOM操作就会使速度变慢。时常在更新数据后重新渲染页面,这就造成在没有改变数据的地方也重新渲染了DOM节点,在很大程度上造成了资源浪费
概念: 利用在内存中生成与真实DOM相对应的数据结构,这个在内存中生成的结构称之为虚拟DOM.
优点:在数据发生改变时,能够智能的计算出重新渲染组件的最小代价并应用到DOM操作上,只重新渲染改变的元素就可以了。虚拟DOM计算之后,会以最小的代价将真实DOM渲染到页面上
MVVM模式 :
M:model 业务模式 用处:处理数据,提供数据
V:view 用户界面,用户视图
业务模式model中的数据发生改变时,用户视图view也随之改变;用户视图view改变时,业务模式model中的数据也可以发生改变
二 : vue 入门
1. vue.js和vue.min.js
vue.js是完整的vue文件,包括换行,空格,注释等,一般用于开发使用
vue.min.js是压缩之后的vue文件,在功能上与vue.js无差别,但它是压缩过的,文件比较小,没有注释,也将错误调试信息关闭了,它的下载速度更快,一般用于线上项目
2. vue.js是一个js库,直接在外部引入即可
注意:script标签里已经引入一个外部文件,就不可以再在里边写JS代码了。只能再另写一个文件书写代码
3. vue.js提供了Vue类,它是一个对象
用Vue类创建一个对象,并保存在变量里。vue在使用时要传入一个对象作为参数。
var app = new Vue({});
4. 对象参数里常用的两个属性:el和data
JavaScript代码
var app = new Vue({
el : '#app', // 管理id为app的元素
data : {} // data的核心作用是存放显示在页面中的数据,data必须是一个对象
})
var app = new Vue({
el : '.app' // 管理class为app的元素
})
var app = new Vue({
el : 'h1' // 管理h1元素
})
HTML代码
范围之内
范围之外
el表示这个对象管理的边界,属性值和CSS选择器是一样的,表示管理的那个元素。其中上边三种写法都是可以的,但是推荐使用id表示,来保证唯一性
上述表示vue对象管理的范围是第一个h1,和第二个h1毫无关联
5. 对象参数的其他属性:methods等
6. 创建一个实例
{{ message }}
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
}
})
运行结果
hello world
实例解析:
在用户界面view中,通过{{}}的形式将data中的数据显示在页面中而在用户界面中,{{}}绑定的是data的key值(这里是message),而页面中显示的是该key的value值(这里是hello world)
app这个变量会代理vue中data的数据,所以我们访问data中的数据时,直接用app.message就可以了
在控制台上的变化(注意左右)
作者:椰果粒
链接:https://www.jianshu.com/p/ab6d1bd0744d
Vue.js基本代码和MVVM之间的对应关系
< !--1.导入Vue的包-->
{{ msg }}
Vue 的指令
一 : 指令的概念:
指令是vue自定义的以v-开头的自定义属性。每个不同的属性都有各自不同的意义和功能
二 : 指令的语法:
v-指令名 = “表达式判断或者是业务模型中属性名或者事件名”
三 : 具体指令
1. v-text
作用 : 操作元素中的纯文本
快捷方式 : {{}}
栗子1
简写形式:将v-text=""换成{{}}
{{ message }}
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
}
})
结果:hello world
栗子2
var app1 = new Vue({
el : "#app1",
data : {
year : new Date().getFullYear(),
month : new Date().getMonth()+1
}
})
结果:今天是2017年5月
等同于:今天是{{year}}年{{month}}月
- 这里v-text="",双引号并不是代表字符串,而是vue自定义的划定界限的符号。如果我们里边输出字符串,就要在里边再添加一对单引号。而且经测验,要想输出字符串,必须添加单引号,否则会报错
- 这里month默认是从0开始的,所以我们要+1
- 这里{{}}代表的就是"",所以在v-text=""中,我们在内容里边就不需要再写{{}}了,直接写data值就行
栗子3
{{ message }}
{{ message.concat('!!!') }}
{{ message? 'has message' : 'no message' }}
下面这两个语句报错
{{ var message = 'message' }}
{{ if(message){return info} }}
var app = new Vue({
el : '#app', // 绑定了上边的id='app'的元素
data : {
message : 'hello'
}
})
结果:
hello
hello!!!
has message
第四五句报错
大胡子{{}}里边支持表达式
但不是所有的表达式都能放在里边,只有单个语句的可以,像var和if就不可以
如果想使用if语句的话,用三元运算符代替
栗子4
可以采用对象的形式传递多个数据
姓名 : {{ person.name }}
性别 : {{ person.sex }}
年龄 : {{ person.age }}
var app2 = new Vue({
el : "#app2",
data : {
person : {
name : '小明',
sex : '男',
age : 8
}
}
})
结果:
姓名 : 小明
性别 : 男
年龄 : 8
补充一点:
用{{}}的弊端:当网速很慢或者下面的JavaScript写错时,会直接将{{message}}渲染到页面
而使用v-text="message" 如果出错是不显示的
所以在实际开发中用v-text比较多
2. v-html
作用 : 操作元素中的HTML标签
v-text会将元素当成纯文本输出,v-html会将元素当成HTML标签解析后输出
栗子1
{{ message }}
var app3 = new Vue({
el : "#app3",
data : {
message : "[图片上传失败...(image-b28bd8-1533127932697)]"
}
})
结果:输出代表图片名称的字符串,而不是将图片输出
由此可见:{{}}/v-text不能解析html元素,只会照样输出
栗子2
var app3 = new Vue({
el : "#app3",
data : {
message : "[图片上传失败...(image-6734f-1533127932697)]"
}
})
结果 : 成功显示图片
注意 : 你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容插值。
3. v-bind
作用 : 绑定标签属性,:后面是标签属性名
栗子1
var app = new Vue({
el : "#app",
data : {
hrefvalue : 'http://www.baidu.com',
source : 'img/1.jpg'
}
})
栗子2
鼠标悬停几秒钟查看此处动态绑定的提示信息!
var app2 = new Vue({
el : '#app2',
data : {
message : '页面加载于' + new Date()
}
})
补充v-bind小例子
根据条件判断绑定
绑定多个class值,数组
绑定三元运算符
绑定style
对象方式绑定style
var app = new Vue({
el : "#app",
data : {
imgSrc : "./img/dele.jpg",
webUrl : "www.baidu.com",
className : "a",
isOk : true,
classA : 'a',
classB : 'b',
red : 'red',
font : '30px',
styleObject : { // 将style写成对象写法
color : 'orange',
fontSize : '40px'
}
}
})
Vue指令之"v-bind"的三种用法
1.直接使用指令v-bind:
2.使用简化指令 :
3.在绑定的时候,拼接绑定内容 :title=" btnTitle + '这是追加的内容' "
4. v-show 指令
-
作用
:通过判断,是否显示该内容。如果值为true,则显示。否则就隐藏。 -
语法
:v-show=”判断表达式” -
特点
:元素会始终渲染在DOM中,只是被设置了display:none
举个栗子
show and hide
var app = new Vue({
el : '#app',
data : {
seen : true
}
})
运行结果 :
从中我们可以看出 :
v-show与否通过内联样式display:none来体现
这里可以给seen赋任何值,浏览器会根据转化后的值来判断是否显示
其中空数组和空对象会显示,undefined,null,0会隐藏,1等也会显示
5. vue v-if && v-else-if && v-else 指令
一 : v-if
-
作用
: 判断是否加载固定的内容,如果为真,就加载,否则不加载 -
用处
: 用在权限管理,页面加载 -
语法
: v-if="判断表达式" -
特点
: 控制元素插入或删除,而不是隐藏(v-show是隐藏) -
v-if与v-show的区别
:
- v-if的安全级别更高,v-show只是隐藏了,通过页面源代码还是可以看到,安全级别低、
- v-if更高的切换消耗(切换消耗指从未加载到加载或者从加载到未加载的状况,需要添加或删除这个元素),v-show需要更高的初始化渲染消耗
- 因此如果需要频繁切换而对安性无要求,使用v-show;如果运行时,条件不能改变,使用v-if
6.v-if和v-for的区别
: 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
举个栗子1
yes
no
var app = new Vue({
el : '#app',
data : {
status : 'ok'
}
});
运行结果 :app.status = 'ok' 则显示yes,status=任何其他的值都显示no
栗子2
: 一个条件渲染多条语句
title
paragraph 1
paragraph 2
运行结果 : 条件成立时,这三条语句同时显示在页面上
title
paragraph 1
paragraph 2
拓展一点:
template用于包裹纯文字或者没有大的父级元素包裹的情况下,比如一段文字需要加载,而没有别的元素包裹它,就可以用template来包裹
栗子3
v-if根据条件显示与隐藏
var app4 = new Vue({
el : '#app4',
data : {
seen : true
}
})
运行结果 :
从上述动图我们可以看到 : v-if如果判断不成立,就不会在DOM中渲染,也不会将对应的语句显示在页面上
二 :v-else
v-else要紧跟在v-if后面,表示v-if条件不成立时执行
三 : v-else-if
表示多次,在v-if和v-else中间
loading
success
fail
var app5 = new Vue({
el : '#app5',
data : {
status : 'loading'
}
})
运行结果 :
6. vue v-for(list rendering)
v-for迭代分为数组迭代和对象迭代
-
作用
: 控制HTML元素中的循环,实现语句列表的生成 -
用法
: v-for = “item in 集合”,其中item指集合的子项,集合指被遍历的元素,通常为数组 -
用处
: 用处:写在谁上边,谁遍历
数组迭代
栗子1
:
运行结果 :
栗子2
: 可以使用of代替in来使用
-
{{ item.message }}
var app = new Vue({
el : '#app',
data : {
items : [
{message : 'foo'},
{message : 'bar'},
{message : 'jewel'}
]
}
})
运行结果 :
foo
bar
jewel
栗子3
: v-for还支持第二个可选参数作为当前项的索引
-
{{ parentMessage }} - {{ index }} - {{ item.message }}
var app2 = new Vue({
el : '#app2',
data : {
parentMessage : 'Parent',
items : [
{ message : 'foo'},
{ message : 'bar'}
]
}
})
运行结果 :
Parent - 0 - foo
Parent - 1 - bar
栗子4
: 可以用template渲染多个元素块
{{ parentMessage }}
- {{ item.message }}
var app2 = new Vue({
el : '#app2',
data : {
parentMessage : 'Parent',
items : [
{ message : 'foo'},
{ message : 'bar'}
]
}
})
运行结果 :
栗子5
: 整数迭代
{{ n }}
var app4 = new Vue({
el : '#app4'
});
运行结果 : 1 2 3 4 5 6 7 8 9 10
栗子6
: 也可以将10替换成一个变量,从data中提取数据
{{ n }}
var app4 = new Vue({
el : '#app4',
data : {
m : 8
}
})
运行结果 : 1 2 3 4 5 6 7 8
对象迭代
栗子1
:默认遍历的是value的值
-
{{ value }}
var app3 = new Vue({
el : '#app3',
data : {
object : {
FirstName : 'john',
lastName : 'bob',
Age : 30
}
}
})
运行结果 :
john
bob
30
栗子2
: 可以提供第二个参数作为键名
-
{{ key }} : {{ value }}
运行结果 :
FirstName : john
lastName : bob
Age : 30
栗子3
:还可以接受第三个参数作为索引
-
{{ index }} : {{ key }} : {{ value }}
运行结果 :
0 : FirstName : john
1 : lastName : bob
2 : Age : 30
v-if and v-for
当它们存在于同一个节点上时,v-for的优先级高于v-if,这意味着v-if将在循环的每个节点上分别运行。当您只想为某些项呈现节点时,这一点非常有用
举个栗子
-
{{ todo }} : {{ index }}
var app6 = new Vue({
el : '#app6',
data : {
todos : ['hello', 'world', 'a', 'b', 'v']
}
});
运行结果 :
hello : 0
world : 1
新增两个例子,分别对应数字排序和对象的属性排序
1. 数字排序
{{num}}
var app = new Vue({
el : '#app',
data : {
number : [1,2,3,4,5,11,32,25] // 元素极其相似,那么就放在数组中
},
computed : {
sortItem : function(){
return this.number.sort(sortNumber);
}
}
})
function sortNumber(a,b){ // 此函数代表了对数字的排序算法。
return a-b;
}
在JavaScript中,默认的排序方式是按照ascll码排序,即12排在1和3之间,所以需要用sortNumber函数将其转化成数字间的排序
在data中存放的是一组或一个数据,最好不要进行数据将的处理(比如排序,转化成大小写等),这些计算属性我们可以放在computed中进行
7. v-on 指令
1. 作用:对页面中的事件进行绑定
2. 语法: v-on:事件类型=“事件处理函数名”
缩写: @事件类型=“事件处理函数名”
3. vue事件绑定提供了两方面的内容:自定义事件和为DOM绑定事件。vue中为DOM元素绑定事件是采用DOM2级事件的处理方式。
例如 : 这里事件处理函数后面有没有括号都可以,但如果传参的话,就必须加()
实际上相当于
el.assEventListener('click',func)
所以addEventListener支持绑定的事件,v-on指令也都支持
4. 举个栗子
一个直观的栗子
- 单击事件
- 双击事件
- 鼠标移入事件
- 鼠标移出事件
var app = new Vue({
el : '#app',
data : {
},
methods : {
clickMe : function(){
console.log('单击事件发生');
},
dblclickMe : function (){
console.log('双击事件发生');
},
mouseover : function() {
console.log('鼠标移入事件');
},
mouseout : function () {
console.log('鼠标移出');
}
}
结果 :
栗子1 : 用v-on指令来监听DOM事件,并进行JavaScript处理
the button above has been clicked {{ counter }} times
var app1 = new Vue({
el : '#app1',
data : {
counter : 0
}
});
结果:
栗子2 : 可以将事件处理函数名放在methods中,这样直接调用函数名即可
var app2 = new Vue({
el : "#app2",
data : {
name : 'vue'
},
methods : {
great : function(event){
alert('hello' + ' ' + this.name + '!');
if(event){
alert(event.target.tagName);
}
}
}
});
结果: hello vue BUTTON
栗子3 :可以给函数传入参数
var app3 = new Vue({
el : '#app3',
methods : {
say : function(message){
alert(message);
}
}
})
结果: hi what
栗子4 :在内联语句处理器中访问原生DOM事件。可以用特殊变量$event把它传入方法
var app4 = new Vue({
el : '#app4',
methods : {
warn : function(message, event){
if(event) event.preventDefault()
alert(message)
}
}
})
结果: form cannot be submitted yet
V-on的缩写和事件修饰符
尽管我们可以在methods中实现阻止默认事件等,但更好的方法是methods中只有纯粹的数据逻辑,而不是去处理DOM事件
为了解决这个问题,vue为v-on提供了事件修饰符。通过由.表示的指令后缀来调用修饰符
事件修饰符:
- stop阻止冒泡
- prevent阻止默认事件
- capture添加事件侦听器时使用事件捕获模式
- self 只当事件在该元素本身(比如不是子元素)触发时触发回调
- once 事件只触发一次
1..stop 阻止单击事件冒泡
栗子 :
var app1 = new Vue({
el : "#app1",
methods : {
doIt : function(){
alert(123);
},
show : function(){
alert(456);
}
}
})
解析 : 因为div是button的父元素,当点击button时,会冒泡到父元素,相当于也点击了button,也就是没阻止冒泡事件时,会弹出123 接着弹出456,阻止冒泡事件之后,不会冒泡到父元素,也就只能弹出123了
2. .prevent 提交事件不再重载页面
v-model指令和双向数据绑定
双向数据绑定的几个修饰符
- v-model.lazy 当焦点离开输入框时才进行渲染
- v-model.number 输入框里边必须是数字,否则会清空。当先输入字符串后输入数字,就无法将字符串省略掉
- v-model.trim 清空空格
原始数据:{{message}}
文本框
文本域
多选框
多选框绑定一个数组
{{names}}
单选按钮的双向数据绑定
你选择的性别是:{{sex}}
var a = new Vue({
el : "#app",
data : {
message : "hello world",
isTrue : false,
names : [],
sex : "男"
}
})
单选下拉菜单
selected : {{ selected }}
var app6 = new Vue({
el : "#app6",
data : {
selected : ' '
}
});
多选下拉菜单
selected : {{ selected }}
selected : []
绑定下拉菜单,且名称与之对应
selected : {{ selected}}
var app8 = new Vue({
el : '#app8',
data : {
selected : 'A',
options : [
{text : 'one', value : 'A'},
{text : 'two', value : 'B'},
{text : 'three', value : 'C'}
]
}
})
9. v-pre,v-once,v-clock指令
- v-text 输出渲染后的值
- v-html 输出解析HTML元素后的值
- v-if 条件判断
- v-else-if
- v-else
- v-for 循环
- v-model 表单双向数据绑定
- v-show 控制元素显示与隐藏
- v-bind 绑定元素的属性和style
- v-on 绑定事件
- v-pre 原样输出
- v-clock 渲染完之后才显示,防止将{{message}}类似的输出到页面
- v-once 只渲染一次
小例子
v-pre: 将内容原样输出
{{message}}
var vm = new Vue({
el : '#app',
data : {
message : 'hello world'
}
})
结果:{{message}}
v-once:只渲染一次
var childOne = {
template : `第一个组件`
}
var childTwo = {
template : `第二个组件`
}
在正常情况下,每个组件切换时都是销毁,创建,销毁,创建的过程,而如果加了v-once,就会在内存中缓存这个组件,这样就不用每次都创建了,能提高效率。
{{count}}
{{count}}
var app = new Vue({
el : '#app',
data : {
count : 1
},
methods : {
add : function(){
this.count++;
}
}
})
结果:上面的message一直在增加,下面有once的message只渲染了1之后就不变了
在Vue中使用样式
使用class样式
- 数组
这是一个邪恶的H1
- 数组中使用三元表达式
这是一个邪恶的H1
- 数组中嵌套对象
这是一个邪恶的H1
- 直接使用对象
这是一个邪恶的H1
使用内联样式
- 直接在元素上通过
:style
的形式,书写样式对象
这是一个善良的H1
- 将样式对象,定义到
data
中,并直接引用到:style
中
- 在data上定义样式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
- 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
这是一个善良的H1
- 在
:style
中通过数组,引用多个data
上的样式对象
- 在data上定义样式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
h1StyleObj2: { fontStyle: 'italic' }
}
- 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
这是一个善良的H1
Vue指令之v-for
和key
属性
- 迭代数组
- 索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}
- 迭代对象中的属性
{{val}} --- {{key}} --- {{i}}
- 迭代数字
这是第 {{i}} 个P标签
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
Vue指令之v-if
和v-show
v-if的特点:每次都会重新删除或创建元素
v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none 样式
一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。
- 如果元素涉及到频繁的切换,最好不要使用v-if, 而是推荐使用v-show
- 如果元素可能永远也不会被显示出来被用户看到,则推荐使用v-if