1
指令 v-bind,DOM节点的属性基本都可以使用指令v-bind进行绑定。
省略缩写为 " :"
属性也可以绑定变量、表达式、执行函数等内容,但是都应该满足属性自身约束。
2
类名样式绑定:类名实际是由数组拼接而成,样式则是由对象键值对拼接而成。所以在Vue中,二者的绑定机制不同。
<script type="text/javascript">
let vm = new Vue({
el:"#app",
data(){
return{
classStr:'color-gray size-18 style-italic', //拼接字符串
classArr:['color-gary', 'size-18', 'style-italic'], //数组
classObj1:{
//对象,绑定类名
'color-gray': true,
'size-18': true,
'style-italic': true
},
classObj2:{
//对象,未绑定类名
'color-gray': 0,
'size-18': '',
'style-italic': false
}
} //return
} //data
})
</script>
JS中的真假值问题:
当变量的值为 undefined、 null、 值为0的数字、空字符串(’ ')时,会判定为 false (假);
除一般值外,[ ]、 { }、 -1、 -0.1 会判定为 true(真)。
<script type="text/javascript">
let vm = new Vue({
el:"#app",
data(){
return{
styleStr:'color: gray; font-size: 18px; font-style: italic;', //拼接字符串
styleArr:['color-gary', 'size-18', 'style-italic'], //数组
styleObj1:{
//对象,绑定样式
'color-gray': -1 ? 'gray' : 'black',
'size-18': '18px',
'style-italic': 'italic'
},
styleObj2:{
//对象,未绑定样式
'color-gray': 0 ? 'gray' : '',
'size-18': '' ? '18px' : '',
'style-italic': null ? 'talic' : ''
}
} //return
} //data
})
</script>
<button v-on:click="logInfo()">点击</button>
<button @click="logInfo()">点击</button>
获取事件对象:
<div id="app">
<!-- 1. 在事件函数不必传参时,可以这样写, 注意:不能带 () -->
<input type="text" @keyup="handleKeyUp">
<br>
<!-- 2. 手动传入 $event 对象 -->
<input type="text" @keyup="handleKeyUp($event)">
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
methods: {
handleKeyUp(event) {
console.log(event.key, event);
}
},
})
</script>
获取event对象:
<div id="app">
<!-- <form @submit="handleSubmit">
<h2>不使用修饰符时</h2>
<button type="submit">提交</button>
</form> -->
<form @submit.prevent="handleSubmit">
<h2>使用.prevent修饰符时</h2>
<button type="submit">提交</button>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data () {
return {
counter: 0
}
},
methods: {
handleSubmit () {
console.log(`submit ${
++this.counter} times`)
}
}
})
</script>
不使用 .prevent 修饰符:
多次点击”提交“按钮,控制台均是一闪而过打印信息,之后呈现空白。原因是因为当未指定form表单时,表单会被提交到当前的URL,对应的表现就是页面被重新加载。
使用 .prevent 修饰符:
点击“提交”按钮之后,页面没有被重载。
注意: 当事件后缀多个修饰符时,要注意排列顺序,相应的代码会根据排列顺序依次产生。
<!-- 监听键盘事件 -->
<input type="text" @keyup.13="console.log($event)"> //使用按键键值
<input type="text" @keyup.enter="console.log($event)"> //使用按键别名,事件对象属性中的 key 值(不区分大小写)
鼠标事件修饰符:
修饰符 | 可用版本 | 对应按键 |
---|---|---|
.left | 2.2.0 以上 | 左键 |
.right | 2.2.0 以上 | 右键 |
.middle | 2.2.0 以上 | 中键 |
<div id="app">
<h1 @click.ctrl="logWithCtrl" @click="logSingle">没有ctrl别来点我</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
methods: {
logSingle (event) {
if (!event.ctrlKey) {
console.log('------------- 分割线 -------------')
console.log('$event.ctrlKey:', event.ctrlKey)
console.log('logSingle 点击事件!')
} else {
console.log('不错,进步很快呀!')
}
},
logWithCtrl (event) {
console.log('------------- 分割线 -------------')
console.log('$event.ctrlKey:', event.ctrlKey)
console.log('logWithCtrl 组合事件!')
}
}
})
</script>
第一次,使用鼠标点击节点,此时的事件对象的 ctrlKey 值为 false ,控制台 只打印了鼠标点击事件 的信息;
第二次,按住 Ctrl 键再次点击节点,此时事件对象的 ctrlKey 值为 true ,控制台 先打印了组合事件 的信息,之 后打印了鼠标点击事件 的信息。
综合结果发现,当 Ctrl 键被按下时,事件对象的 ctrlKey 的值被设为 true ;当鼠标点击事件触发时,若 ctrlKey 的值为 true ,则执行组合事件代码。
1 指令 v-model
v-model 和 v-show 是Vue的核心功能中内置的,开发者 不可自定义 的指令。
可以使用 v-model 为可输入元素(input & textarea)创建双向数据绑定,它会根据元素类型自动选取正确的方法来更新元素。
注意: v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而 总是将 Vue 实例的数据作为数据来源 。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
例如:
<div id="app">
<h3>单行文本框</h3>
<input type="text" v-model="singleText" style="width: 240px;">
<p>{
{
singleText }}</p>
<h3>多行文本框</h3>
<textarea v-model="multiText" style="width: 240px;"></textarea>
<pre>{
{
multiText }}</pre>
<h3>单选框</h3>
<!--
由于点击被选中的单选项无法取消其被选中状态,所以实战中基本没有使用单个单选项的场景。
这里,设置v-model共用同一个变量(radioValue)可实现RadioGroup的效果
-->
<input id="ra" type="radio" value="杨玉环" v-model="radioValue">
<label for="ra">A.杨玉环</label>
<input id="rb" type="radio" value="赵飞燕" v-model="radioValue">
<label for="rb">B.赵飞燕</label>
<p>{
{
radioValue }}</p>
<h3>单个复选框</h3>
<!-- 单个复选框被用于true和false的切换 -->
<input id="c" type="checkbox" v-model="toggleValue">
<label for="c">天生丽质</label>
<p>{
{
toggleValue }}</p>
<h3>多个复选框</h3>
<!-- 多个复选框, v-model接收数组类型变量 -->
<input id="ca" type="checkbox" value="漂亮" v-model="checkedValues">
<label for="ca">A.回眸一笑百媚生</label>
<input id="cb" type="checkbox" value="瘦弱" v-model="checkedValues">
<label for="cb">B.体轻能为掌上舞</label>
<input id="cc" type="checkbox" value="得宠" v-model="checkedValues">
<label for="cc">C.三千宠爱在一身</label>
<p>{
{
checkedValues.join(',') }}</p>
<input type="checkbox" value="铁斧头" v-model="checks">铁斧头
<input type="checkbox" value="金斧头" v-model="checks">金斧头
<input type="checkbox" value="银斧头" v-model="checks">银斧头
<br>
<br>
樵夫选择了---{
{
checks}}
<br><br>
<!-- 复选框控制选中和未选中的值, 绑定true-value, false-value属性 -->
<!-- 这里的 true-value 和 false-value attribute 并不会影响输入控件的 value attribute,因为浏览器在提交表单时并不会包含未被选中的复选框。 -->
<input type="checkbox" v-model="toggle" :true-value="value_1" :false-value="value_2"><br>
toggle的值是---{
{
toggle}}
<br>
选中---{
{
toggle===value_1}}
<br>
未选中---{
{
toggle===value_2}}
<br>
<h3>单项下拉选择框</h3>
<!-- v-model一定是绑定在select标签上 -->
<!-- 在select标签上绑定value值对option并没有影响 -->
<select name="" id="" v-model="singleSelect">
<option value="">请选择</option>
<!-- 如果没有设置 value 则 option 节点的文本值会被当作 value 的值 -->
<!-- 如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态 -->
<option value="汉代">汉代</option>
<option value="">唐代</option>
<option value="">宋代</option>
</select>
<p>{
{
singleSelect }}</p>
<h3>多项下拉选择框</h3>
<!-- 如果是多选,就需要v-model来配合value使用,v-model绑定一个数组,与复选框类似 -->
<!-- 注意: v-model一定是绑定在select标签上 -->
<select name="" id="" multiple v-model="multiSelect" style="width: 100px;">
<!-- 按住 ctrl 键,可执行多选 -->
<option value=1>出身傲寒</option>
<option value=2>饱受争议</option>
<!-- 把值绑定到 Vue 实例的一个动态 property 上,这时可以用 v-bind 实现,并且这个 property 的值可以不是字符串。 -->
<option :value="3">结局悲凉</option>
</select>
<p>{
{
multiSelect.join(",") }}</p>
<h3>单选按钮</h3>
<div id="">
<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>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data() {
return {
singleText: '',
multiText: '',
radioValue: '',
toggleValue: false,
checkedValues: [],
//根据 value 设置默认选项
singleSelect: '汉代',
multiSelect: [1, 3],
picked: '',
// 使用字符串时同时全部选中并显示 true 未选中则显示 false
checks: "",
//使用绑定数组时可以任意选中,并且显示 value 值
// checks:[]
toggle: false,
value_1: '被选中',
value_2: '未被选中'
};
}
})
</script>
<input type="text/javascript" v-model.trim.number="text" @keyup="handelKeyUp">
<div id="app">
<!-- 自定义组件v-model -->
<custom-screen v-model="text"></custom-screen>
<br>
<!-- 原生元素v-model -->
<input type="text" v-model="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
Vue.component('custom-screen', {
// 使用value属性接收外部传入的值
props: ['value'],
methods: {
handleReset() {
console.log('重置为\'\'');
// 使用$emit发送input事件,并将目标值作为参数传出
this.$emit('input', '');
}
},
template: `
输入值为: {
{ value }}
`
})
let vm = new Vue({
el: '#app',
data: () => ({
text: ''
})
})
</script>
value 属性用于 接收外部传入的值 以更新组件内部状态;
input 事件由开发者决定什么时候调用,并负责 将组件内部的状态同步到外部 。
<div id="app">
<h2 v-show="visible">v-show, visible = true</h2>
<h2 v-show="!visible">v-show, visible = false</h2>
<h2 v-if="visible">v-if, visible = true</h2>
<h2 v-else>v-if, visible = false</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data () {
return {
visible: false
}
}
})
</script>
由图中可以看到,v-show 判定为假的元素的 display 属性被赋值为 none ,但是其仍然保留在 DOM 中。
而 v-if 判定为假的元素则不会出现在 DOM 中。
注意:
a. v-if 会在切换中将组件上的事件监听器和子组件销毁和重建。当组件被销毁时将无法被任何方式获取,因为它已经不存在于DOM中;
b. 在创建父组件时,若是子组件的 v-if 被判定为假时,Vue在直到其第一次判定为真前都不会对子组件做任何事情;这在使用Vue生命周期钩子函数的时要尤为注意,若是生命周期已经走过了组件的创建阶段,却仍然无法获取组件对象,则需要思考是不是 v-if 的原因;
c. v-if 有更高的切换开销, v-show 有更高的初始渲染开销;这都与它们的实现机制有关。(即,v-if 初始渲染速度快,但是切换速度慢;v-show 初始渲染速度慢,但是切换速度快,初始时需要加载所有元素,但是修改时只需要修改display 样式即可。)
d. v-show 不支持 template 元素.
<div id="app">
<h2>用户列表</h2>
<ul>
<!-- index作为第二个参数,用以标识下标 -->
<li v-for="(user, index) in users">
用户{
{
index + 1 }}
<ul>
<!-- key作为第二个参数,用以标识键名 -->
<li v-for="(value, key) of user">{
{
key }}: {
{
value }}</li>
</ul>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data() {
return {
users: [{
name: 'Clark',
age: 27,
city: 'Chicago'
},
{
name: 'Jackson',
age: 28,
city: 'Sydney'
}
]
}
}
})
</script>
<div id="app">
<h2>用户列表</h2>
<button @click="createUser">创建用户</button>
<button @click="reverse">倒序数组</button>
<ul>
<!-- index作为第二个参数,用以标识下标 -->
<li v-for="(user, index) in users">
用户{
{
index + 1 }}
<ul>
<!-- key作为第二个参数,用以标识键名 -->
<li v-for="(value, key) of user">
<strong style="display: inline-block;width: 60px;">{
{
key }}:</strong>
<span>{
{
value }}</span>
</li>
</ul>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data () {
return {
users: []
}
},
methods: {
random (factor, base) {
// 根据乘积因子和基数生成随机整数
// 使用Math.floor(Math.random())去获取你想要的一个范围内的整数。
// Math.random()*3.99 + 3 //现在这个数就 >=3 且 <(3.99+3) 再使用Math.floor取整(其余同理)
return Math.floor(Math.random() * (factor || 1)) + (base || 0)
},
createUser () {
// 获取 name 大写首字母
let fLetter = 'BJHK'[this.random(3.999)]
// 随机截取 name 字符串
let nameStr = 'abcdefghijklmnopqrstuvwxyz'
let bLetters = nameStr.substr(this.random(19.999), this.random(3.999, 3))
let user = {
name: fLetter + bLetters,
age: this.random(5.999, 25),
city: ['Chicago', 'Sydney', 'ShenZhen', 'HangZhou'][this.random(3.999)]
}
console.log('--------------- 创建用户 ---------------\n', user)
this.users.push(user)
},
reverse () {
console.log('--------------- 倒序列表 ---------------')
console.log('Before:', this.users.map(user => user.name))
this.users.reverse()
console.log('After:', this.users.map(user => user.name))
}
}
})
</script>
注意:
a. Math.floor() 返回小于或等于一个给定数字的最大整数。
Note: Math.floor() === 向下取整 ;
b. Math.random() 函数返回一个浮点, 伪随机数在范围从0到小于1,也就是说,从0(包括0)往上,但是不包括1(排除1),然后您可以缩放到所需的范围。
例如:*Math.random()52 + 1 //现在这个数就 >=1 且 <53,再使用Math.floor 取整 *Math.floor(Math.random()52 + 1)