方式一:直接CDN引入
开发版本建议在开发过程中使用,未经过压缩,有自动换行,缩进,易于看源码。
发布时使用生产版本,压缩后更快一些
方式二:下载和引入
开发环境 https://vuejs.org/js/vue.js
生产环境 https://vuejs.org/js/vue.min.js
方式三:NPM安装
通过webpack和CLI使用
npm install vue
View层
视图层,主要的作用就是给用户展示各种信息。
Model层
数据层,数据可能是固定的死数据,更多的是来自服务器,从网络请求下来的数据。
VueModel层
视图模型层,视图模型层是View层和Model层沟通的桥梁。
一方面它实现了Data Bingding,即数据绑定,将Model的改变实时的反应到View中。
另一方面它实现了DOM Listener,即DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
el:
类型:string或HTMLElement
作用:决定之后vue实例管理哪个DOM
template:
data:
类型:Object或Function(在组件中,data必须是一个函数)
作用:Vue实例对应的数据对象
methons:
类型:function
作用:定义属于vue的一些方法。
生命周期函数
computers:
beforeCreate—创建实例之前执行的钩子事件
created—实例创建完成后执行的钩子
beforeMount—将编译完成的HTML挂载到对应虚拟DOM时触发的钩子,此时页面并没有内容
mounted—编译好的HTML挂载到页面后执行的事件钩子,此钩子函数中一般会做一些ajax请求获取数据进行数据初始化。注意:mounted在整个实例中只执行一次
beforeUpdata—更新之前的钩子函数
updata—更新之后的钩子函数
beforeDestroy—实例销毁之前执行的钩子函数
destroyed—实例销毁完成执行的钩子函数
mustache语法
双大括号 {{ }} ,在mustache语法中,不仅可以直接写变量,还可以直接加空格。在标签内容中插值,不能在标签的属性中使用。
<p>{{ message }}p>
<p>{{ firstname + '' + lastname}}p>
<p>{{ counetr * 2 }}p>
v-once
只显示第一次的渲染时数据,不会随着数据的改变而改变
<p v-once> {{ message }} p>
v-html
当数据本身就是一个html带有标签的代码时,则需要使用v-html对数据进行解析。
<p v-html=“url”> 谷歌 p>
v-text
v-text的作用和Mustache比较相似,都是用于将数据显示在界面中。v-text通常情况下,接受一个string类型。如下
<p v-text="message">你好啊p>
v-pre
v-pre用于跳过这个元素和它的子元素的编译过程,用于显示原本的Mustache语法。
<p v-pre>{{message}}p>
<p>{{message}}p>
上例中,第一条p标签显示为:,第二条p标签显示为vue实例中变量message的值。
v-cloak
cloak:斗篷。
在某些情况下,浏览器可能会直接显示出未编译的mustache标签。比如在网络较慢的情况下,js代码还没来得及编译,页面已经显示了html标签,标签中的mustache语句会显露出来,为了利于用户浏览,则需要将这些mustache语句隐藏,则用到v-cloak。
<div id="app">
<p>{{message}}p>
div>
<script>
setTimeout(() => {
new Vue({
el:"#app",
data:{
message:"你好啊",
}
})
}, 1000);
script>
以上代码,在页面中会先显示”“,过一秒钟之后显示”你好啊“。如果想要隐藏 ” “,则在p标签中添加v-cloak,然后在样式中将v-cloak的display设为none。
<style>
[v-cloak]{
display: none;
}
style>
<p v-cloak>{{message}}p>
v-bind 作用:动态绑定属性
动态绑定class ( 对象语法 ):
<div id="app">
<h2 :class="{ 'active':isActive,'Line':isLine }">{{ message }}h2>
div>
<script>
new Vue({
el:"#app",
data:{
message:"你好啊",
isActive:false,
isLine:true
}
})
script>
在对象语法中,通过键值对的方式对类名是否添加进行操作,当然也可以把对象添加到一个函数中返回该对象,class的引号中直接写上该函数即可。
对象语法也可以和普通类同时存在,互不影响
<h2 class="title" :class="{ active:isActive,Line:isLine }">{{ message }}h2>
动态绑定class( 数组语法 ):
<h2 :class="['active','line']">{{ message }}h2>
该用法比较少,因为将class添加到数组中和直接给class没什么区别。
动态绑定style( 对象语法 ):
{{ message }}
可以像上面这样直接写,但大多用于下面的写法。
<h2 :style="{ color:messageColor,fontSize:messageFontSize }">{{ message }}h2>
<script>
new Vue({
el:"#app",
data:{
message:"你好啊",
messageColor:'red',
messageFontSize:'50px'
}
})
script>
要注意的是什么时候带引号什么时候不带引号,不需要进行表达式解析时,要加上引号,不然vue会认为那是个变量。当然如果data中传来的数据没有单位的话,可以在style中用表达式添加单位,如fontSize:messageFontSize+‘px’
动态绑定style( 数组语法 ):
<h2 :style="[baseStlye]">{{ message }}h2>
<script>
new Vue({
el:"#app",
data:{
message:"你好啊",
baseStlye:{ color:'yellow',fontSize:'100px' }
}
})
script>
这样的使用也是比较少的,其实就是将对象放到了数组中。
某些情况下,我们需要对数据进行一些操作之后再显示。比如firstname和lastname,将两个字符串用空格隔开显示,虽然有很多方法,比如mustache语法可以在两个字符串之间加个空格( ),也可以通过methods编写方法,但不推荐。可以将这种方式换成计算属性。计算属性写在实例 computed 选项中。
<div id="app"> {{ fullname }}div>
<script>
const app = new Vue({
el:"#app",
data:{
firstname: "Mark",
lastname: "Towen"
},
computed: {
fullname(){
return this.firstname+' '+this.lastname;
}
},
})
例子中的 fullname 并不是一个方法,它是一个属性。因为一个完整的计算属性都包含一个get和一个set
fullname: {
get(){
console.log('调用了fullname的get方法');
return this.firstname+' '+this.lastname;
},
set(newValue){
console.log('调用了fullname的set方法');
const names= newValue.split(' ');
this.firstname = names[0];
this.lastname = names[1];
}
}
调用set方法的时候是要更改内容,所以要有一个参数。
打开网页后,在控制台中可以通过 app.fullname得到 get() 所返回的值(Mark Towen)。
如果对fullname的值做了更改,如在控制台输入: app.fullname=”太上 老君” 。那么控制台会打印两行信息:“ 调用了fullname的set方法 ” ,“ 调用了fullname的get方法 ” ,页面中的 “Mark Towen” 也变成了 “太上 老君” 。
这就是计算属性的 setter 和 getter 。但大多数情况下我们是不使用 set 方法的也不希望使用 set 方法的,所以直接将 set 方法删掉,只保留 get 方法。既然只有一个get方法了,那么就将代码变得更加简洁一些,就变成了如下的写法,所以计算属性不是函数,而是一个属性。
计算属性一般是没有 set 方法,只读属性。
fullname(){
return this.firstname+' '+this.lastname;
}
底层原理:
methods 和 computed 都可以实现这样的功能,那么为什么还要多出来一个计算属性这个东西呢。
因为计算属性会进行缓存,多次使用的话计算属性只会调用一次,而函数要调用N次。
v-on
作用:绑定事件监听 缩写:@ 参数:event
简单使用
<div id="app">
<button v-on:click="counter++">按钮一button> <br>
<p>{{ counter }}p>
div>
<script>
new Vue({
el:"#app",
data:{
counter: 0,
}
script>
可以在标签中直接写操作。
v-on的参数
<div id="app">
<button v-on:click="btn2click">按钮二button> <br>
<button v-on:click="btn2click">按钮三button>
<p>{{ counter }}p>
div>
<script>
new Vue({
el:"#app",
data:{
counter: 0,
},
methods: {
btn2click(){
this.counter++;
}
}
script>
v-on 修饰符
.stop:阻止冒泡
调用 event.stopPropagation()。当点击按钮一时,按钮一的父元素的点击事件也会被调用,这就是事件冒泡。阻止冒泡,则在按钮一点击出添加.prevent。
<div id="app">
<div v-on:click="divclick" style="background-color: yellow;width: 100px;height: 100px;">
<input type="button" value="按钮一" v-on:click.prevent="btnclick">
div>
div>
<script>
new Vue({
el:"#app",
methods: {
btnclick(){
console.log("btnclick");
},
divclick(){
console.log("divclick");
}
<、script>
.prevent:阻止默认行为
调用 event.preventDefault()。在表单提交中,往往不需要按钮自动提交,这时就需要.prevent来阻止这一默认行为。
<div id="app">
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submit()">
form>
div>
.keyup: 键修饰符
当按完某个按键时,执行函数
<input type="text" @keyup="keyup_event()">
<input type="text" @keydown="keydown_event()">
指定某个按键 up 或 down 时执行函数:
<input type="text" @keyup.enter="enter()">
.native:监听组件根元素的原生事件
native:本地的,本地人
给普通的标签添加事件,加native后,事件失效,如下:
<button @click.native="clickNative">点我button>
在我们需要监听一个组件的原生事件时,必须给对应的事件加上.native修饰符才能进行监听,
如下操作时无效的
<cpn @click="cpnClick">cpn>
这样才能生效
<cpn @click.native="cpnClick">cpn>
.once :只出发一次回调。
v-if、v-else-if、v-else
这三条指令和js中的条件语句if、else-if、else类似,在vue中可以根据表达式的值在DOM中渲染或销毁元素或组件。
<div id="app">
<h2 v-if="score>=89">优秀h2>
<h2 v-else-if="score>=70">良好h2>
<h2 v-else-if="score>=60">及格h2>
<h2 v-else>不及格h2>
div>
v-if和v-show的区别
v-if:每次都会删除或者创建元素
v-show:每次不会进行dom的删除或创建,只是切换了元素的display:none样式。
当需要在显示与隐藏之间切片很频繁时,使用v-show
当只有一次切换时,通过使用v-if
案例:点击切换按钮实现分别输入账号和邮箱
<div id="app">
<div v-if="type === 'username'">
用户账号:<input type="text" id="username">
div>
<div v-else-if="type === 'email'">
用户邮箱:<input type="text" id="email">
div>
<input type="button" value="切换类型" @click="changeTpye()">
div>
<script>
const vm = new Vue({
el:"#app",
data:{
type: 'username',
},
methods: {
changeTpye(){
this.type==='username' ? this.type='email' : this.type='username';
}
script>
在实现的过程中,出现一个问题,该问题为:如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容,p但是按道理讲,我们应该切换到另外一个input元素中了,p在另一个input元素中,我们并没有输入内容。
问题解答:(虚拟DOM)这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
解决方案:如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key,并且我们需要保证key的不同。
v-for
遍历数组中的元素:item in items 或 (item, index) in items,第二个参数为索引
-
{{index}} ------- {{item}}
遍历对象中的元素:(value,key,index) in object ,第二个参数为键名,第三个参数为索引
<ul id="v-for-object" class="demo">
<li v-for="(value,key,index) in object">
{{index}}----{{ key }}-----{{ value }}
li>
ul>
<script>
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
script>
执行结果为:0—-firstName—–John
1—-lastName—–Doe
2—-age—–30
组件中的key属性
官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性。key属性可以为每个节点做一个唯一的标识。key的作用主要是为了高效的更新虚拟DOM。
检测数组更新
1.Vue是响应式的,当数据发生变化时,vue自动检测数据变化,视图也会发生对应的更新。但当直接给数组指定位置赋值来更新数据的时候,此时数据虽然改变,但视图并不会更新。
例如上例中循环遍历数组的情况下,在控制台输入vm.names[0]='白骨精'
时,值变了,视图中依然显示孙悟空。
2.当使用如下方法对数组操作时,视图会更新:
push()、pop()、shift()、unshift()、splice()、sort()、reverse() 。
3.使用Vue.set() 方法时,视图也会更新。
Vue.set( target, key, value ) :响应式新增与修改数据。
target:要更改的数据源(可以是对象或者数组)
key:要更改的具体数据
value :重新赋的值
上例中循环遍历数组的情况下,添加一个按钮,点击按钮执行 Vue.set(this.names,0,'白骨精')
,视图会发生改变
Vue中使用v-model指令来实现表单元素和数据的双向绑定。
<div id="app">
<input type="text" v-model='message'>
{{message}}
div>
<script>
const vm = new Vue({
el:"#app",
data:{
message:''
}
})
script>
当我们在输入框输入内容时,因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。所以,通过v-model实现了双向的绑定。
v-model原理
1.v-bind 绑定一个 value 属性
2.v-on 指令给当前元素绑定 input 事件
也就是
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
radio(单选框)
<div id="app">
<label for="Male">
<input type="radio" id="Male" value='Male' v-model='Gender'>男
label>
<label for="Female">
<input type="radio" id="Female" value='Female' v-model='Gender'>女
label>
<p>性别为:{{ Gender }}p>
div>
当有多个单选框时,使用 v-model 时,不必为每一个单选按钮添加 name 属性,v-model 会自动排斥。
checkbox(复选框)
复选框有两种情况,单个勾选框( 比如同意注册协议 )和多个勾选框。
单个勾选框
此时,v-model 为布尔值,而且 input 的 value 并不影响 v-model 的值。
<div id="app">
<input type="checkbox" name="" id="" v-model="isAgree">
{{ isAgree }}
div>
多个勾选框
当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。当选中某一个时,就会将input的value添加到数组中。
<input type="checkbox" value="足球" v-model="hobby">足球
<input type="checkbox" value="篮球" v-model="hobby">篮球
<input type="checkbox" value="羽毛球" v-model="hobby">羽毛球
<input type="checkbox" value="乒乓球" v-model="hobby">乒乓球
<p>爱好:{{ hobby }}p>
div>
<script>
const vm = new Vue({
el:"#app",
data:{
isAgree:false,
hobby:[]
}
script>
select
select 也分单选和多选两种情况。
单选
<select name="" id="" v-model="fruits">
<option value="苹果">苹果option>
<option value="香蕉">香蕉option>
<option value="西瓜">西瓜option>
<option value="番茄">番茄option>
<option value="猕猴桃">猕猴桃option>
select>
<p>{{ fruits }}p>
<script>
const vm = new Vue({
el:"#app",
data:{
fruits:''
script>
此时,v-model绑定的是一个值,当选中option中的一个时,会将它对应的value赋值到fruits中。
多选
在上面单选的代码中的 select 标签中添加 multiple 即可设置为多选。
多选情况下,fruits 应为一个数组。
当选中多个值时,就会将选中的 option 对应的 value 添加到数组 fruits 中。
注意:在 v-model 中使用 select 时,为 option 添加 selected=”selected” 默认值时是无效的,因为 fruits 为空,想要添加默认值需在 fruits 中添加。
值绑定
在实际开发中,比如上面的兴趣爱好,水果选择之类的,不是直接写死的,而是从服务器获取的数据,需遍历使用。如
<div id="app">
<label v-for="item in List">
<input type="checkbox" :value="item" :id="item" v-model="hobby">{{ item }}
label>
<h2>{{ hobby }}h2>
div>
<script>
const vm = new Vue({
el:"#app",
data:{
List:['篮球','羽毛球','足球','高尔夫','橄榄球'],
hobby:[]
script>
通过 v-bind:value 动态的给 value 绑定值,这就是 v-model 中的值绑定。
v-model修饰符
lazy修饰符:lazy修饰符可以让数据在失去焦点或者回车时才会更新‘
number修饰符:默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。number修饰符可以让在输入框中输入的内容自动转成数字类型。
<input type="number" v-model="asd">
{{ asd }} {{ typeof asd }} // string 类型
<input type="number" v-model.number="asd">
{{ asd }} {{ typeof asd }} //number 类型
trim修饰符:如果输入的内容首尾有很多空格,通常我们希望将其去除。trim修饰符可以过滤内容左右两边的空格。
更多 Vue 内容见官网 Vue官网
补充:
高级函数使用
参数:都是传入匿名函数
filter:返回false与true
aaa.filter(funtion(n){
return n < 100
//trun的话就返回该数组中的元素
})
map:遍历数组,直接返回数组中的元素
aaa.map(funtion(n){
return n * 2
//返回结果是数组内每个元素都乘以2
})
reduce:累计总的结果,加减乘除等,后面需要重置为0,例子
aaa.reduce(function (preValue, n){
return preValue+n
//传入两个参数,进行累加,返回结果
// 假如n是[20,40,60,80,100]
// 第一次:0+20
// 第二次:20+40
// 第三次:60+60
// 第四次:120+80
// 第五次:200+100
},0)