页面展示
基本指令
-
v-text
用于在页面中展示数据,可以简写为{{ }}的形式<p v-text="msg"></p> <p>{{msg}}</p> <!--这两种写法是等价的-->
-
v-html
同样是用于展示数据,与v-text区别相当于innerHtml和textContent<div v-html="msg"></div>
-
v-pre
用来在展示页面是跳过渲染某一段代码,该方法主要可以用来跳过没有指令的代码来提高加载速度<p v-pre>{{msg}}</p>
-
v-once
添加了该指令的元素/组件只会渲染一次,之后vue重新渲染时会直接跳过该元素/组件,即使我们改变元素/组件引用的数据,元素也不会重新渲染,我们可以在内容固定的元素/指令上使用该指令来节省性能<tem v-once></tem> <p v-once>{{msg}}</p>
-
v-bind
可以绑定一个或多个动态,或者一个组件的prop,在vue中可以使用v-bing来将元素本身的属性变为动态特性, 成为动态特性后可以接受变量值,使元素更加灵活,可以简写为 " : " 的形式<div :style="" :class=""></div> <img :src="变量值">
-
v-on
绑定事件监听器,事件类型由参数指定,表达式可以是一个方法的名字或者是一个内联语句,当用在普通元素上时只支持原生DOM事件,用在组件上时可以支持自定义事件,可以简写为"@"形式<div @click="click"></div> <div @click="bool=!bool"></div> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
-
v-cloak
该指令是vue用来配合css样式在vue没有在页面渲染完成之前,使用该指令的元素不显示,使用户界面不会展示在渲染未完成之前的{{msg}}之类的修饰符,该指令会在页面渲染完成之后自动被去除<style> [v-cloak]{ display:none; } </style> <div v-cloak></div>
-
ref
ref用来给元素或者子组件设定引用信息,引用信息将会注册在父组件的$refs对象上,如果在普通的DOM上使用,引用指向的就是DOM元素对象,如果在组件上使用,引用指向的就是子组件对象<p ref="p">{{picked}}</p> new Vue({ ... created(){ console.log(this.$refs.p,"created"); // p undefined this.$refs.p.style.color="red"; //Cannot read property 'style' of undefined" }, mounted(){ console.log(this.$refs,"mounted"); //p:p this.$refs.p.style.color="red"; } })
通过ref注册的元素/组件可以在父组件的this.$refs中获取,但是需要注意的是,我们注册的元素/组件初始渲染时不能被获取到的,只有在创建完成时才能被获取,因为ref本身是作为渲染结果被创建的,同时refs也不是响应式的
绑定HTML class样式
<div id="box">
<!--传入一个对象,对应值来控制当前元素的样式-->
<p :class="{col:bool,weight:bool}" class="size" @click="change">hello</p>
<!--传入一个实例中的计算属性,通过计算属性的返回值控制当前元素的样式-->
<p :class="classList">hello</p>
<!--传入一个实例中的对象,对象中定义的值会控制当前元素的样式-->
<p :class="classObj">hello</p>
<!--传入一个数组,可以用来接收多个样式对象-->
<!--可以通过使用三元表达式来控制当前元素样式-->
<p :class="[bool?classList:'']">hello</p>
<!--也可以通过在数组中传入对象来传入多个样式-->
<p :class="[classList,{col:bool}]">hello</p>
</div>
<script>
new Vue({
data: {
bool: true,
classList: {
colGreen: true,
style: true
},
col: true,
error: {
type: "fatal"
}
},
computed: {
classObj: function () {
return {
col: this.col && !this.error,
weight: this.error && this.error.type === "fatal"
}
}
},
methods: {
change() {
this.bool = false;
}
}
}).$mount("#box")
</script>
:class样式能够和原生的class属性共存,在元素被渲染后,:class样式和class的样式都会被保留
在使用组件的时候,在组件上内部添加的样式将会和在组件上添加的样式一同被渲染
<body>
<div id="box">
<tem class="size"></tem>
</div>
<script>
const Tem={
template:`
<div class="box">
<p class="col">hello</p>
</div>
`
}
new Vue({
el:"#box",
components:{
"tem":Tem
}
})
//模板最后的渲染结果是
//<div class="size box">
//<p class="col">hello</p>
//</div>
</script>
</body>
绑定内联 style样式
-
对象语法
:style的对象语法十分直观,css属性名可以用驼峰命名法或者短横分割命名<div :style="{color:activeColor,fontSize:fontSize+'px'}"> data:{ activeColor:'red', fontSize:30 }
直接绑定到一个样式对象通常更好,让模板更清晰
<div :style="styleObj"></div> data:{ styleObj:{ color:'red', fontSize:'13px' } }
同样可以集合返回对象的计算属性使用
-
数组语法
:style的数组语法可以将多个样式对象应用到一个元素上
<div :style="[baseStyles,overr]"><div> data:{ baseStyles:{ color:"red" }, overr:{ fontSize:"40px" } }
-
自动添加前缀
当:style使用需要特定前缀的css属性时,如transform,vue会自动侦测并添加相应的前缀
条件渲染
v-if,v-else,v-else-if
v-if的判断条件可以是数据表达式,也可以是一个变量的值,或者是一条逻辑判断语句
<div v-if="type==='A'">
A
</div>
<div v-else-if="0<1">
B
</div>
<div v-lese="bool">
C
</div>
也可以通过v-if来控制组件是否能够显示
<div id="box">
<tem v-if="bool"></tem>
</div>
v-show
v--show用法与v-if的大致相同,除了v-show没有v-else,不同的是带有v-show属性的元素始终会被渲染并保留在DOM中,v-show是通过切换元素的css样式disoplay的值来控制元素是否显示,而v-if则是通过创建和销毁来控制元素是否可见,所以相比而言v-if的切换开销更高一些,但是v-if是惰性的,如果初始的条件为false的话,那么它会保持什么也不做,直到条件发生变化,而v-show不论条件是什么都会进行渲染,一般来说,v-show会有更高的初始渲染开销
一般来说,如果需要非常频繁的进行切换,那么我们会使用v-show,如果运行条件不是经常改变,那么我们会使用v-if
列表渲染
v-for
我们使用v-for指令根据一组数组选项的列表进行渲染,v-for指令需要以item in items形式的特殊语法,items是源数据组,item是元素迭代的别名
也可以使用of代替in作为分割符
<li v-for="item of items"></li>
在v-for块中,我们拥有对父级作用域完全的访问权限,还支持可选的第二参数为当前项的索引值
<div id="box">
<p v-for="(item,index) in items">{{item}}{{index}}</p>
</div>
new Vue({
data:{
items:["tom","xm"]
}
}).$mount("#box")
我们也可以使用v-for通过一个对象来迭代
<div id="box">
<p v-for="value in items">{{value}}</p>
</div>
new Vue({
data:{
items:{
name:"tom",
age:18
}
}
}).$mount("#box")
vue对于对象的迭代默认会展示对象的键值对的值,可以通过提供第二个参数来获取对象的键名
<p v-for="(value,ket) in items">{{value}}{{key}}</p>
也可以传入第三个参数来获取索引值
<p v-for="(value,key,index) in items">{{value}}{{key}}{{index}}</p>
这里的遍历顺序遵照JS中Object.keys()的顺序
:key
当vue.js在渲染是时发现已有元素再次被使用时会复用已有元素而不是重新渲染,这会加快vue渲染的速度,同时还有一个好处,例如下面这个例子
<body>
<div id="box">
<user></user>
</div>
<template id="userInfo">
<div>
<div v-if="loginType ==='username'">
<label>Username</label>
<input type="text" placeholder="请输入用户名" >
</div>
<div v-else>
<label>Email</label>
<input type="text" placeholder="请输入邮箱">
</div>
<button @click="change">switch</button>
</div>
</template>
<script>
new Vue({
components:{
"user":{
template:"#userInfo",
data(){
return{
loginType: "username"
}
},
methods: {
change() {
this.loginType = "Email"
}
}
}
}
}).$mount("#box")
</script>
</body>
在这个例子中,我们点击button进行切换时,veu会复用重复的元素,template中相同的元素如llabel,input等元素只会渲染一次,在第二次出现时会被复用,如lable只会替换它的文字,input只会替换元素的placeholder,而不会再次重复渲染标签,所以在点击切换时我们会发现输入框中我们输入的内容会依然存在
这种复用会提高vue的运行效率,但是有时在实际开发中我们可能需要避免这种情况,此时需要我们用到:key,我们可以通过为每一个input设置不同的:key来通知vue需要将该元素重新渲染
<input type="text" placeholder="请输入邮箱" :key="Email">
建议在使用v-for循环时如果要使用:key要给每一个不同的元素不同的key值,推荐使用如下方法
<p v-for="item in items" :key="item.id">{{item}}</p>
显示过滤/排序结果
有时候我们想要显示一个数组的过滤或排序副本,而不改变或重置原始数据,在这种情况下,可以创建返回过滤排序数组的计算属性
<p v-for="item in items">{{item}}</p>
new Vue({
data:{
num:[1,2,3,4,5,6,7,8]
},
computed:{
items:function () {
return this.num.filter(function (item) {
return item % 2 === 0+it
})
}
}
}).$mount("#box")
在计算属性不适用的情况下,可以使用methods来配合filter
<p v-for="item in even(nums)">{{item}}</p>
new Vue({
data:{
nums:[1,2,3,4,5,6,7,8]
},
methods:{
even(n){
return n.filter(function (n) {
return n%2===0
})
}
}
}).$mount("#box")
v-for和v-if
类似于v-if,我们也可以利用带有v-for的<template>渲染多个元素
<ul>
<template v-for="item in items">
<li>{{item.title}}</li>
</template>
</ul>
当v-if和v-for处于同一节点,v-for的优先级比v-if更高,这也意味着v-if将会对每一次的v-for循环进行判断
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
如果是有条件的跳过循环的执行,那么可以将v-if置于元素的外层上
组件的v-for
在自定义组件中,我们可以像普通元素一样使用v-for
<my-component is="my-component" v-for="item in 10" :key="item.id" :item="item"></my-component>
但是注意在组件中不能使用item,也就是不能拿到父级的数据,需要我们通过props获取父级的数据(item)
在vue2.2.0+的版本里,当组件在使用v-for时,key是必须的
表单输入绑定
v-model会忽略所有表单元素的value,checked,selected特性的初始值,因为它会选择Vue实例来作为具体的值,我们应该通过javascript在组件的data选项中声明初始值,对于单选按钮以及列表选项,v-model绑定的是input的value的值,对于勾选按钮绑定的是逻辑值
文本
<input v-model='massage' placeholder='edit me'>
<p>{{massage}}</p>
多行文本
<p style="white-sapce:pre-line">{{massage}}</p>
<br/>
<textarea v-model="massage" placeholder="add multiple lines"></textarea>
复选框
-
单个复选框
<input v-model="massage" id="checkbox" type="checkbox"> <label for="checkbox">
-
多个复选框
<form action="#"> <input type="checkbox" id="jack" v-model="checkedNames"> <label for="jack">jack</label> <input type="checkbox" id="john" value="john" v-model="checkedNames"> <label for="john">john</label> <input type="checkbox" id="moke" value="mike" v-model="checkedNames"> <label for="moke">mike</label> </form> <span>checked names:{{checkedNames}}</span> new Vue({ data:{ checkedNames:[] <!--如果我们将checkedNames设置为数组,那么在复选框选中后会传回复选框的value值, 如果设置为字符串,那么在复选框被选中后会传回当前复选框的选中状态为true/false,并且所有复选框会被同时选中/不选中 --> } })
单选按钮
<input type="radio" value="one" v-model="picked" id="one" >
<label for="one">one</label>
<input type="radio" value="two" v-model="picked" id="two" >
<label for="two">two</label>
<p>{{picked}}</p>
new Vue({
data:{
picked:''
}
}).$mount("#box")
选择列表
-
单选列表
<select v-model="selected"> <option value="" disabled>请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>{{selected}}</span> new Vue({ data:{ selected:'' } }).$mount("#box")
-
动态选项
<select v-model="selected"> <option v-for="option in options" :value="option.value"> {{option.text}} </option> </select> <span>{{selected}}</span> new Vue({ data:{ selected:'A', options:[ {text:'one',value:'A'}, {text:'two',value:'B'}, {text:'three',value:'C'} ] } }).$mount("#box")
动态value
我们可以利用v-bind:将value绑定到Vue实例的一个动态属性上,之后v-model将会绑定到动态value上,动态value可以是对象,字符串,数组等类型
-
复选框
<input type="checkbox" v-model="toggle" :true-value="a" :false-value="b"> <p>{{toggle}}</p> new Vue({ data:{ a:{ text:'您已经选中' }, b:"您没有选中", toggle:'' } }).$mount("#box")
-
单选按钮
<input type="radio" v-model="pick" :value="a"> <p>{{pick}}</p> new Vue({ data:{ a:'你已经选中A', pick:'' } }).$mount("#box")
-
动态列表
参考上一例动态列表例子
修饰符
-
lazy
<input type="text" v-model.lazy="pick"> <!--在默认情况下,v-model会在input事件中同步输入框的值与数据,在使用lazy修饰符后,会变为在change事件中同步--> <!--change事件触发条件:输入框内容发生改变并且失去焦点--> <!--input事件触发条件:输入框内容发生变化-->
-
number
<input type="number" v-model.number="pick"> <!--将用户的输入值转化为number类型,在通常的时候即使我们使用的是type="number"类型的输入框,得到的值也是string-->
-
trim
<!--自动去掉用户输入文本的首尾空格--> <input type="text" v-model.trim="pick">