目录
4. Vue中Class与Style的绑定 ( v-bind )
1. Vue中v-if与v-show的区别(条件渲染)
v-if vs v-show
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被 销毁 和 重建 。
v-if 也是 惰性 的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的 切换开销 ,而 v-show 有更高的 初始渲染开销 。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
<div id="app">
<div v-if="isIf">
<p>我被 v-if 控制</p>
</div>
<div v-show="isShow">
<p>我被 v-show 控制</p>
</div>
<button @click="pChange">Change</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
isIf: true,
isShow: true
},
methods: {
pChange() {
this.isIf = (this.isIf === true ? false : true);
this.isShow = (this.isShow === true ? false : true);
}
}
})
</script>
用一个 button 按钮控制 v-if 和 v-show 的 true 、false 切换,当两个指令值都为 false 时,v-if 控制的 元素 是直接从 DOM 树 销毁 的;而 v-show 控制的 元素 还在 DOM 树中,只是以 display:none 样式 隐藏元素 内容 。
2. Vue中的列表渲染( v-for )
用 v-for
渲染普通数组
- 在 data 中定义 普通数组
data:{
list:[1,2,3,4,5]
}
- 在 html 中使用 v-for 指令渲染
<p v-for="(item,index) in list">索引值:{{index}} --- 每一项:{{item}}</p>
用 v-for
渲染对象数组
- 在 data 中定义 对象数组
data: {
list: [1, 2, 3, 4, 5], // 用 v-for 渲染普通数组
listObj:[ // 用 v-for 渲染对象数组
{id:1, name:'赵一'},
{id:2, name:'钱二'},
{id:3, name:'张三'},
{id:4, name:'李四'},
{id:5, name:'王五'}
]
}
- 在 html 中使用 v-for 指令渲染
<p v-for="(user,index) in listObj">id:{{user.id}} --- 姓名:{{user.name}}</p>
用 v-for
渲染对象
- 在 data 中 定义 对象
data: {
user: {
id: 1,
name: 'Tom',
gender: '男'
}
}
- 在 html 中使用 v-for 指令渲染
<p v-for="(val,key) in user">key:{{key}} --- val:{{val}}</p>
用 v-for
渲染数值
v-for
也可以接受整数。在这种情况下,它会把模板重复对应次数。
<div>
<span v-for="n in 10">={{ n }}=</span>
</div>
结果 :
=1==2==3==4==5==6==7==8==9==10=
3. Vue中的事件监听( v-on )
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。用在普通元素上时,只能监听原生 DOM 事件,用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
案例 :
<!-- 方法处理器 -->
<button v-on:click="doThis"></button>
<!-- 动态事件 (2.6.0+) -->
<button v-on:[event]="doThis"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
<!-- 动态事件缩写 (2.6.0+) -->
<button @[event]="doThis"></button>
v-on 传值
情况一:methods 的方法有参数传值
注意:@click="msg('xhl')"传值时必须加上单引号,不加就传 data 里的参数
<button @click="msg('xhl')">有参数传值</button>
methods: {
msg(event) {
console.log(event); //输出的 xhl
}
}
情况二:methods 的方法有参数但没有传值
返回的是 event(Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态)
<button @click="msg">有参数没有传值</button>
methods: {
msg(event) {
console.log(event); //输出的 Event
}
}
情况三:methods的方法有参数,传值同时也要event
<button @click="msg('xhl',$event)">传值, Event</button>
methods: {
msg(name, event) {
console.log(name); // xhl
console.log(event); // Event
}
}
v-on 的事件修饰符
.stop:停止冒泡
<div @click="upthis">
abc
<!-- 阻止事件冒泡 -->
<a v-on:click.stop="doThis"></a>
</div>
.prevent:阻止默认行为
<form action='baidu'>
<!-- 提交事件不再重载页面(不会跳转页面) -->
<input @click.prevent="doThat">
</form>
.once:只会触发一次
<!-- 点击事件将只会触发一次,防止重复提交 -->
<a v-on:click.once="doThis"></a>
监听某个键盘的键帽
<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">
<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">
4. Vue中Class与Style的绑定 ( v-bind )
绑定 Class
我们可以传给 v-bind:class
一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }"></div>
上面的语法表示 active
这个 class 存在与否将取决于数据 isActive
的 true 或 false。
你可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class
指令也可以与普通的 class 共存。当有如下模板:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
和如下 data:
data: {
isActive: true,
hasError: false
}
结果渲染为:
<div class="static active"></div>
当
isActive
或者hasError
变化时,class 列表将相应地更新。例如,如果hasError
的值为true
,class 列表将变为"static active text-danger"
。
绑定的数据对象不必内联定义在模板里:
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
渲染的结果 :
我们也可以在这里绑定一个返回对象的 计算属性 。这是一个常用且强大的模式:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
数组语法
我们可以把一个数组传给 v-bind:class
,以应用一个 class 列表:
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染为:
<div class="active text-danger"></div>
如果你也想根据条件切换列表中的 class,可以用三元表达式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
这样写将始终添加 errorClass
,但是只有在 isActive
是 truthy[1] 时才添加 activeClass
。
不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
组件中的用法
当在一个自定义组件上使用 class
property 时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。
例如,如果你声明了这个组件:
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
然后在使用它的时候添加一些 class:
<my-component class="baz boo"></my-component>
HTML 将被渲染为:
<p class="foo bar baz boo">Hi</p>
对于带数据绑定 class 也同样适用:
<my-component v-bind:class="{ active: isActive }"></my-component>
当 isActive
为 truthy[1] 时,HTML 将被渲染成为:
<p class="foo bar active">Hi</p>
绑定 Style
对象语法
v-bind:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: { activeColor: 'red', fontSize: 30 }
直接绑定到一个样式对象通常更好,这会让模板更清晰:
<div v-bind:style="styleObject"></div>
data: { styleObject: { color: 'red', fontSize: '30px' } }
同样的,对象语法常常结合返回对象的计算属性使用。
数组语法
v-bind:style
的数组语法可以将多个样式对象应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>
自动添加前缀
当 v-bind:style
使用需要添加浏览器引擎前缀的 CSS property 时,如 transform
,Vue.js 会自动侦测并添加相应的前缀。
多重值
2.3.0+
从 2.3.0 起你可以为 style
绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex
。
5. Vue中的双向绑定( v-model )
你可以用 v-model
指令在 表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。 v-model
本质上是个 语法糖 。它负责监听用户的输入事件以更新数据。
v-model
会忽略所有表单元素的value
、checked
、selected
的值而是将 Vue 实例的 data 数据作为 数据来源 。
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
文本( text )
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
data: {
message: 'hello Vue'
}
多行文本( textarea )
<span>Multiline message is:</span> <p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
复选框( checkbox )
单个复选框,绑定到布尔值
<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
data: { checked: true }
多个复选框,绑定到同一个数组
<input type="checkbox" id="jack" value="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="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span>
data: { checkedNames: true }
new Vue({ el: '...', data: { checkedNames: [] } })
单选按钮( radio )
<input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span>
data: { picked: '' }
选择框( select )
<select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span>
data: { selected: '' }
修饰符
1 .lazy
失去焦点或者按回车时触发
<!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg">
2 .number
转为数值类型
<input v-model.number="age" type="number">
3 .trim
去除首尾空格
<input v-model.trim="msg">