首先,在页面中我们要引入Vue脚本。
我们通过new Vue( )
来初始化一个Vue实例,需要传入一个对象,其中对象的el 属性用来指定挂载的元素,data属性用来初始化数据。
new Vue({//初始化 Vue 实例
el : "#box",//指定挂载元素
data : {//初始化数据
msg : "Hello Vue !"
}
})
在页面渲染依然使用双花括号。
1、绑定
我们可以定义一个变量vm 来接收这个实例,这样data上的数据都会挂载到vm上。所以我们在调用data里的数据的时候直接使用 vm.msg,而不是vm.data.msg。
在Vue中给元素绑定属性的时候,要使用v-bind:attr 的形式。它的简写形式为:attr
;绑定多个class值的时候我们可以使用使用数组、对象、甚至三木运算符。
绑定属性之后,在属性里写data里的数据时,直接写入data里的数据名,不用写花括号即可
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "",//务必在 data 中初始化要使用的数据,否则会抛出警告
a : "testId",
isA : true,
isB : true,
first : "a",
second : "c",
isShow : true,
third : "d",
styleObject : {
fontSize : "30px",
color : "red"
},
styleObj : {
textDecoration: "underline"
}
}
});
HTML代码
<div id="box">
{{3}}
<span v-bind:title="msg" v-bind:style="styleObject" v-bind:id="a" v-bind:diy="msg">鼠标停一下</span>
<!-- :attr 是 v-bind:attr 的简写形式 -->
<span :style="styleObject">第二个</span>
<!--绑定class可以用对象和数组的形式-->
<div :class="{ a : isA,b : isB }" class="c">
内容
</div>
<div :class="[first,second]">
内容二
</div>
<div :class="[first,isShow ? '' : third]">
内容三
</div>
<div :style="[styleObject,styleObj]">
内容四
</div>
<div :class="{a : isA}" class="b">
内容五
</div>
</div>
其中,若我们在vm 中没有传入el 这个属性时,也可以在对象下指定要挂载的元素。
vm.$mount("#box");
2、条件
Vue中我们可以使用v-if,v-else用来判断显示或隐藏哪个标签,其中Vue2.1版本还新增了v-else-if。
注:v-if 和 angular中 ng-if 一样,元素消失时会直接从DOM中删除;而v-show 和 ng-show 一样,元素消失时,就相当于display : none;元素隐藏掉了
JS代码
var vm = new Vue({
el : "#box",
data : {
isShow : false
}
})
HTML代码
<div id="box">
<!--v-if 和 ng-if 一样,消失时直接把元素删除-->
<span v-if="isShow">加油</span>
<!--<span v-else-if="">2.1版本新增</span>-->
<!--v-else不需要有值-->
<p v-else>看不到我</p>
<!--v-show---display:none;和angular是一样的-->
<span v-show="isShow">v-show</span>
</div>
3、遍历数组和对象
在Vue中,通过v-for来遍历。其中遍历对象时,一个参数时会直接将属性值解析出来;需要解析属性时需要传两个参数,下标时传三个参数。具体看下面代码:
JS代码
var vm = new Vue({
el : "#box",
data : {
arr : ["a","b","c"],
num : 5,
obj : {
name : "liu",
address : "北京",
age : 20
},
arr2 : [1,2,2,3]
}
})
HTML代码
<div id="box">
<!--ng-repeat ng-for-->
<ul>
<li v-for="a in arr">{{ a }}</li>
</ul>
<ul>
<li v-for="(val,index) in arr">{{index +"-"+ val }}</li>
</ul>
<ul>
<li v-for="x in obj"> {{ x }}</li>
</ul>
<ul>
<li v-for="(val,key) in obj">{{ key +"-"+ val }}</li>
</ul>
<ul>
<li v-for="(val,key,index) in obj">{{ index +"-"+ key +"-"+ val }}</li>
</ul>
<ul>
<!--整数遍历-->
<li v-for="i in num">{{ i }}</li>
</ul>
<ul>
<li v-for="a in arr2"> {{ a }}</li>
</ul>
</div>
4、事件
Vue中添加事件的方法为v-on:eventName,简写的形式为@event。它有一个默认的参数event。下面是具体代码和注释:
JS代码
new Vue({
el : "#box",
data : {
msg : "hello vue",
isShow : true,
firstName : "刘",
lastName : "禹锡"
},
//创建方法
methods : {
changeEvent : function (e,a,b) {
//this指向new Vue()创建的实例,而data下的数据会直接挂载到这个实例上
this.isShow = !this.isShow;
console.log(e,a,b);
},
foo : function () {
return Math.random();
},
fullName : function () {
return this.firstName + this.lastName;
},
p1 : function () {
console.log("点击了div");
},
input : function () {
console.log(this.firstName);
}
}
})
HTML代码
<div id="box">
<button v-on:click="isShow = !isShow">点击</button>
<button v-on:click="changeEvent">点击2</button>
<!--@eventName 为 v-on:eventName 简写形式
$event是默认的参数,如果在事件处理程序中想同时使用事件对象,
和其余的参数,需要显式的传入$event
-->
<button @click="changeEvent($event,'a','b')">点击3</button>
<h1 v-show="isShow">{{ msg }}</h1>
{{ foo() }}
{{ fullName() }}
<div v-on:click="p1">
这是DIV
<!--
修饰符: v-on:eventName.modifier
stop : 阻值冒泡
-->
<button @click.stop="changeEvent">点击4</button>
<input type="text" v-model="firstName" @keydown.left.right.up.down="input"/>
{{ firstName }}
</div>
</div>
触发自定义事件:
this.$emit("事件名",参数);
。值得注意的是,有参数时在添加事件出不需要一个括号来接收这个参数。
5、表单与数据的双向绑定
使用的是v-model,其中我们可以给checkbox和一个数组绑定来实现添加或删除的操作。以及设置checkbox为true和false时的值。具体代码如下:
JS代码
new Vue({
el : "#box",
data : {
c1 : true,
c2 :["tom"],
c3 : "",
a : "真",
b : "假",
msg : "Hello Vue !" ,
}
})
HTML代码
<div id="box">
<!--v-model 将表单项与数据实现双向绑定-->
<input type="text" v-model="msg" />
<h1>{{ msg }}</h1>
<input type="checkbox" v-model="c1" />{{ c1 }}
<br />
<input type="checkbox" v-model="c2" value="a"/>
<input type="checkbox" v-model="c2" value="b"/>
<input type="checkbox" v-model="c2" value="c"/>
{{ c2 }}
<br />
<!--分别指定 true 和 false 时的值-->
<!--<input type="checkbox" v-model="c3" true-value="a" false-value="b" />-->
<input type="checkbox" v-model="c3" :true-value="a" :false-value="b" />
<input type="checkbox" v-model="c3" :true-value="a" :false-value="b" />
{{ c3 }}
</div>
6、计算属性
在Vue中,我们执行一些计算操作的时候,可以将其定义在computed属性中。代码:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "Hello Vue !",
firstName : "孟",
lastName : "浩然",
str : "<h1>htmlStr</h1>"
//fullName : ""
},
computed : {
fullName : function () {
return this.firstName + this.lastName + new Date().getTime();
}
},
methods : {
clickEvent : function () {
console.log(this.fullName)
}
// computedFullName : function () {
// return this.firstName + this.lastName;
// }
}
})
HTML代码
<div id="box">
<!--{{ firstName + lastName }}
{{ computedFullName() }}-->
<!--{{ fullName }}-->
{{ fullName }}
<button @click="clickEvent">点击</button>
{{ str }}
<!--在vue1.0版本中是用 {{{ str }}}来输出的-->
<div v-html="str"></div>
</div>
7、组件
一个组件的完成需要两步,第一步就是使用Vue.extend( )方法来创建一个全局的组件,并且以一个组件名来接收它;第二步,使用Vue.componet(上面接收的组件名,组件对象)来全局注册一个组件,注册完成后,就可以在整个应用中去使用这个组件了。
var myComponent = Vue.extend({
template : "<h1>第一个Vue组件</h1>"
});
Vue.component("my-component",myComponent);
以上两步可以简写为一步:
Vue.component("my-component2",{
template : "<h1>第二个组件</h1>"
});
这样,第二个传入的参数就会由Vue自己去调用extend( )方法去创建这个对象,而不用我们自己手动去调用。
使用方式就是直接在HTML里添加组件名的标签即可。
<my-component></my-component>
7.1、父子间的传值
在Vue中,组件的作用域默认是隔离的,所以如果想要在子组件中访问到父级的数据,则需要父级显式的向下传递。具体代码如下:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "这是父级的 msg",
age : 30,
isShow : true
},
//配置子组件
components : {
"my-component3" : {
template : "<h1>第三个组件</h1>"
},
"my-component4" : myComponent4
}
});
var myComponent4 = Vue.extend({
template : "<h1>第四个组件---{{ msg }}--{{a}}--{{i}}</h1>",
//props : ["msg","a","i"]
props : {
//msg : String,
msg : null,//不限制
//a : Number,
// a : {
// type : Number,
// required : true//必须传入
// },
a : {
validator : function (val) {
return val > 10;
}
},
i : Boolean
}
});
HTML代码
<my-component3></my-component3>
<!--冒号为v-bind的简写形式-->
<my-component4 :msg="msg" :a="age" :i="isShow"></my-component4>
这样,就实现了在子级访问父级的信息。
7.2、在组件中声明数据和获取DOM元素
在组件中声明数据时,可能会出现多处引用的情况,可是如果当我们声明的数据类型为引用数据类型时,修改一处的值就会导致所有引用该数据的值全部发生变化的情况。所以,我们需要声明的数据时通过函数来返回一个对象来确保每个组件用的data数据都是一块全新的内容地址,数据间就可以互不影响,不会再出现牵一发而动全身的现象。
而获取DOM元素时,需要给元素添加ref="name"属性来进行标识,在JS中,通过this.$refs.name来得到那个DOM元素。具体代码如下:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "Hello Vue !!"
},
components : {
"my-component" : {
template : `<div>
<h1 @click="say">子组件</h1>
<button @click="num++">{{ num }}</button>
<input type="text" value="123" ref="mi"/>
</div>`,
//为了解决地址传递的问题(引入数据类型),在组件的声明 data 必须为函数
//且返回一个新对象,这样每个组件用到的 data 是一快新的内容地址
//这样各个组件间可以互不影响
data : function () {
return {
num : 0
}
},
methods : {
say : function () {
//如果需要获取DOM元素,可给元素添加ref="name"属性来进行标识
//在当前组件中通过this.$refs.name 得到那个DOM元素
this.$refs.mi.focus();
console.log("hello",this.num);
}
}
// data : function () {
// return d;
// }
}
}
});
HTML代码
<div id="box">
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
7.3、父子级组件间信息的传递
通过@属性名给父级添加事件,然后在子级中通过$emit( 属性名)来触发该事件来传递信息。具体代码:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "Hello Vue !!",
num : 0
},
components : {
"my-component" : {
template : `<div>
<h1>子组件</h1>
<button @click="cfun">给父级消息</button>
</div>`,
data : function () {
return {
num : 0
}
},
methods : {
cfun : function () {
console.log("子准备呼叫");
//$emit("pfun")-->触发pfun
this.$emit("pfun",1000);
}
}
}
},
methods : {
fun : function (money) {
console.log("收到来自子级的消息",money);
this.num = money;
}
}
});
HTML代码
<div id="box">
{{ num }}
<my-component @pfun="fun"></my-component>
</div>
7.4、声明动态组件,各个组件之间实现跳转
各个组件之间的跳转是通过绑定is属性来决定渲染哪个子组件的,改变is绑定的值来实现组件间的切换。而组件之间的跳转会让页面重新渲染,我们有时不想让页面重新渲染就需要用keep-alive标签将component标签包裹起来。
JS代码
var vm = new Vue({
el : "#box",
data : {
currentView : "home"
},
components : {
home : {
template : `<h1>这是主页--{{ d }}</h1>`,
data : function () {
return {
d : new Date().getTime()
}
}
},
cart : {
template : `<h1>购物车</h1>`
},
mine : {
template : `<h1>个人中心</h1>`
}
}
});
HTML代码
<div id="box">
<button @click="currentView='home'">首页</button>
<button @click="currentView='cart'">购物车</button>
<button @click="currentView='mine'">个人中心</button>
<hr />
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
</div>
注:在Vue1.0的版本中,keep-alive则需要作为一个属性添加到标签上
7.5、组件名作为标签渲染时,会忽略标签内所有内容的解决方法
页面渲染时,会直接忽略掉组件标签内的所有内容,如果需要在组件里渲染子组件时,就需要给子标签的template中添加一个slot标签来声明要预留一个位置,然后页面渲染时会将所有内容方法这个槽位中。
然而,有时我们多个子组件需要放到对应的位置上去。这时,就需要给slot标签添加一个name属性并赋值,在子组件的标签中添加slot属性等于该name值就可以实现我们想要的效果。直观的代码:
JS代码
var vm = new Vue({
el : "#box",
data : {
},
components : {
"my-header" : {
template : `<h1>这是header</h1>`
},
"my-footer" : {
template : `<h1>这是footer</h1>`
},
"my-main" : {
template : `
<div>
<slot name="h"></slot>
<h1>这是主页</h1>
<slot></slot>
<slot name="f"></slot>
</div>
`
}
}
});
HTML代码
<div id="box">
<my-main>
<my-header slot="h"></my-header>
<my-footer slot="f"></my-footer>
<p>原始内容,无插槽</p>
</my-main>
</div>
8、过滤器
Vue中的过滤器和AngularJS中的过滤器大同小异。都是通过数据+竖杠+过滤器(需要的参数)的形式来添加的。具体代码如下:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "Hello Vue !!"
},
filters : {
filterA : function (val) {
console.log(val);
return val.split("").reverse().join("");
},
filterB : function (val) {
console.log(val);
return val.split("").reverse().join("");
},
//传入参数时,注意让过第一个默认参数,为默认的使用过滤器的值(即msg的值)
filterC : function (val,arg1,arg2) {
console.log(val,arg1,arg2);
return val;
}
}
})
HTML代码
<div id="box">
{{ msg | filterA | filterB | filterC("a","b") }}
</div>
9、自定义指令
我们可以在Vue实例中添加directive属性来添加自定义属性。其中有绑定成功bind阶段、绑定的元素插入到父元素成功时触发的inserted阶段、以及有数据更新变化时,触发的update阶段。上代码:
JS代码
var vm = new Vue({
el : "#box",
data : {
msg : "Hello Vue !!"
},
directives : {
focus : {
inserted : function (el) {
el.focus();
}
},
demo : {
bind : function (el) {
console.log("指令绑定",el);
},
inserted : function (el,binding,) {//绑定元素插入到父元素中时执行
console.log("插入成功",el,binding);
},
update : function (el,binding) {//更新时就会执行
console.log("更新",el,binding);
}
}
}
})
HTML代码
<div id="box">
<span v-demo:click.stop="msg">{{ msg }}</span>
<input type="text" v-focus />
</div>
10、路由
组件中,有提供了动态组件的方法也能实现简单的组件之间的切换。但是我们在大型项目时,还是需要用路由来实现跳转的。这时,我们不但要引入vue.js,也需要引入vue-router.js。
我们需要在Vue的那个实例中,添加一个router属性,该属性值为new VueRouter( )创建的实例。而接受的参数为各个组件组成的数组。
下面是更加直观的代码:
JS代码
var routes = [{
path : "/home",
component : {
template : `<div>
<h1>这是主页</h1>
<router-view></router-view>
<router-link to="/home/a">首页-A</router-link>
<router-link to="/home/b">首页-B</router-link>
</div>`
},
children : [{
path : "a",
component : {
template : "<h2>首页-A</h2>"
}
},{
path : "b",
component : {
template : "<h2>首页-B</h2>"
}
}]
},{
path : "/items",
component : {
template : "<h1>商品展示页</h1>"
}
},{
path : "/mine",
component : {
template : "<h1>个人中心</h1>"
}
}];
var router = new VueRouter({
//mode : "history",//地址栏比较简洁的显示
routes : routes
});
var vm = new Vue({
el : "#box",
router : router,
data : {
msg : "Hello Vue!!!"
}
})
HTML代码
<div id="box">
<router-view></router-view>
<router-link to="/home">首页</router-link>
<router-link to="/items">商品</router-link>
<router-link to="/mine">个人中心</router-link>
</div>
和AngularJS类似,被激活的那个路由会被添加一个router-link-active的class。以供我们设置相关的激活样式。