Vue系统学习:02、Vue指令、key的作用
1、v-once:
①、可以让数据只渲染一次,不会随着数据的改变而改变。
②、后面不需要跟表达式。
2、v-text、v-html:渲染文本。v-html:可以识别标签
<div id="app">
<h1 v-text='msg'></h1>
<h1 v-html='url'></h1>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg: 'hello word',
url: '<a href="www.baidu.com">百度</a>'
},
})
</script>
3、v-pre指令:不会解析{{}} 语法,原封不动显示
< h1 v-pre> {{msg}} </h1> // {{msg}}
4、v-bind:动态绑定元素属性:语法糖: : :href=""
< a v-bind:src="bdhref">百度</a>y
①、v-bind:对象语法:动态绑定class属性
<div id="app">
// 对象语法
<h1 class="font" v-bind:class="{active: isActive, line: isLine}">{{msg}}</h1>
<button @click='btnClick'>点击</button>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg: 'hello word',
url: '<a href="www.baidu.com">百度</a>',
isActive: true,
isLine: true
},
methods: {
btnClick() {
this.isActive = !this.isActive
}
}
})
</script>
可以将对象语法放入mthods中
<div id="app">
<h1 v-bind:class="getClass()">{{msg}}</h1>
<button @click='btnClick'>点击</button>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg: 'hello word',
url: '<a href="www.baidu.com">百度</a>',
isActive: true,
isLine: true
},
methods: {
btnClick() {
this.isActive = !this.isActive
},
getClass() {
return { active: this.isActive, line: this.isLine }
}
}
})
</script>
②、v-bind:对象语法:动态绑定style属性
<div id="app">
<!-- <h2 :style="{属性名:属性值}">{{msg}}</h2> -->
<!-- 50px必须加上引号,否则会被当做变量去解析 -->
<!-- <h2 :style="{fontSize: '50px'">{{msg}}</h2> -->
<!-- <h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{msg}}</h2> -->
<h2 :style="getStyle()">{{msg}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg: 'hello word',
finalSize: 100,
finalColor: 'red'
},
methods: {
btnClick(index) {
this.isRed = !this.isRed
},
getStyle() {
return { fontSize: this.finalSize + 'px', backgroundColor: this.finalColor }
}
}
})
</script>
4、v-on:事件监听:简写:@
①、事件参数
<div id="app">
<!-- 1、如果没有传入参数,方法后面的小括号可以省略
<button @click='getName'>按钮</button> -->
<!-- 2、如果传入参数时 -->
<!-- <button @click='getName(123)'>按钮</button> -->
<!-- 3、如果省略了小括号,但是方法又需要参数,此时Vue会默认
将浏览器的event事件对象作为参数传入到方法中 -->
<!-- <button @click='getName'>按钮</button> -->
<!-- 4、定义方法是,既要event对象,又要其它参数
为什么要用$符号:不用的话Vue会把event当做变量解析,报错 -->
<button @click='getName(123, $event)'>按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg1: 'hello',
msg2: 'word'
},
methods: {
// getName(number) {
// console.log(number); // 对应第2点: 123
// },
// getName(event) {
// console.log(event); // 对应第3点: mouseevent
// },
getName(abc, event) {
console.log(abc, event); // 对应第4点: 123 mouseevent
}
}
})
</script>
②、v-on修饰符:
a、.stop修饰符:可以阻止冒泡
<button @click.stop='btnClick'></button>
b、.prevent修饰符:阻止默认事件
<button @click.prevent='btnClick'></button>
c、监听某个键盘的按键
<button @keyup.enter='btnClick'></button> // 只有回车键才会触发该方法
d、.once:只能触发一次
二、条件判断元素是否显示:
1、v-if、v-else、v-esle-if
①、当条件成立时,对应的元素及其子元素才会显示。
<div id="app">
<h1 v-if='isShow'>
<div>abc</div>
<div>abc</div>
<div>{{msg1}}</div>
</h1>
<h1 v-else>isShow为false时,显示我</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
msg1: 'hello',
msg2: 'word',
isShow: false
},
})
</script>
②、小案例:切换登录方式:
<div id="app">
<div v-if="isShow">
账号登录: <input type="text">
</div>
<div v-else>
邮箱登录:<input type="text">
</div>
<button @click='isShow=!isShow'>切换登录方法</button>
</div>
2.1、切换登录方式案例中遇到的问题:元素复用问题
a、如果我们已经在input中输入了内容,但是又点击了切换按钮,会发现登录方法变了,但是输入框的值还在,并没有清空。
原因:
a、Vue在进行DOM渲染时,出于性能的考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
b、在案例中,Vue就复用了input元素。
解决:
a、给对应的input添加key,来保证节点的唯一性。
b、并且要保证key值得不同。
<div id="app">
<div v-if="isShow">
账号登录: <input type="text" key="username">
</div>
<div v-else>
邮箱登录:<input type="text" key="email">
</div>
<button @click='isShow=!isShow'>切换登录方法</button>
</div>
2、v-show:元素是否显示
①、与v-if的区别:v-show只是将display:none;而v-if直接将元素在document中删除。
3、v-for:遍历数组、对象
①、注意点:官方推荐我们在使用v-for时,给对应的元素或者组件添加一个 :key属性。key的值尽量等于item值。
原因:key的主要作用是为了高效的更新虚拟DOM。
<div id="app">
<ul>
<li v-for="(item,index) in city" :key='item'>{{index}}.{{item}}</li> <!--遍历数组-->
</ul>
<ul>
<li v-for="item in people">{{item}}</li> <!--遍历对象-->
</ul>
<ul>
<!--遍历数组对象-->
<li v-for="(item, index) in student">{{item.name}}{{item.age}} {{item.hobby}} {{index}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const test = new Vue({
el: '#app',
data: {
city: ['北京', '上海', '广州', '深圳'],
people: { name: '张三', age: 23, hobby: 'ball' },
student: [
{ name: '张三', age: 22, hobby: 'fball' },
{ name: '李四', age: 32, hobby: 'bball' },
{ name: '王五', age: 42, hobby: 'pball' },
]
},
})
</script>
3、一些响应式的数组方法:
// 1、push()方法。在数组最后面追加元素,可以一次追加多个元素。
// this.city.push('aaa', 'bbb')
// 2、pop()方法:删除数组最后一个元素
// this.city.pop();
// 3、shift()方法:删除数组第一个元素
// this.city.shift();
// 4、unshift()方法:在数组最前面添加元素。
// this.city.unshift('aaa', 'bbb');
// 5、splice()方法:删除元素、插入元素、替换元素
// 删除元素:第一个参数:从哪开始删,第二个参数删除几个(如果没有传,就默认删除后面全部)
// this.city.splice(1,2);
// 替换元素:第一个参数:从哪开始替换,第二个参数:替换几个,第三个参数:替换为
// this.city.splice(1, 2, 'aaa', 'bbb');
// 插入元素:第一个参数:从哪开始插入,第二个参数:0, 第三个:插入的元素
// this.city.splice(1,0,'ccc')
三、v-model:双向数据绑定:
1、v-model和radio文本类型:单选框:只要你选了哪个,它的value值就会动态绑定到msg里面。有了v-model就不用name属性
来让两个单选框互斥了。
<div id="label">
<label for="male">
<input type="radio" value="男" id="male" v-model='msg'>男
</label>
<label>
<input type="radio" value="女" id="female" v-model='msg'>女
<h2>{{msg}}</h2>
</label>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: '#label',
data: {
msg: '男',
}
})
</script>
2、v-model和CheckBox复选框:
<div id="label">
<!--CheckBox就有一个复选框-->
<!-- <label for="agree">
<input type="checkbox" id="agree" v-model='isAgree'>同意协议
</label>
<button :disabled='!isAgree'>下一步</button> -->
<!--CheckBox多选框-->
<input type="checkbox" value="篮球" v-model='hobbies'>篮球
<input type="checkbox" value="足球" v-model='hobbies'>足球
<input type="checkbox" value="乒乓球" v-model='hobbies'>乒乓球
<input type="checkbox" value="网球" v-model='hobbies'>羽毛球
<h2>你的爱好是:{{hobbies}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: '#label',
data: {
msg: '男',
isAgree: false,
hobbies: []
},
})
</script>
2.1、v-model和CheckBox复选框的值绑定:动态绑定
<label v-for='item in originHobbies' :for='item'>
<!-- <input type="checkbox" :value='item' :id="item" v-model='originHobbies'>{{item}} -->
<input type="checkbox" :value='item' :id="item" v-model='hobbies1'>{{item}}
</label>
<h2>你的爱好是:{{hobbies1}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: '#label',
data: {
msg: '男',
isAgree: false,
hobbies: [],
hobbies1: [],
originHobbies: ['苹果', '香蕉', '葡萄', '哈密瓜', '水蜜桃']
},
})
</script>
3、v-model的三个修饰符:
①、lazy修饰符:当数据失去焦点或者按了回车之后数据才会更新,而不是输入一个字符就更新一次。
v-model.lazy='name';
②、number修饰符:可以让输入框输入的内容自动转换为数字类型。默认是字符串。
v-model.number='name';
③、trim修饰符:去除用户输入的空格。
v-model.lazy.trim='name';
4、书籍显示案例:
<div id="app">
<div class="content" v-if='books.length'>
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in books">
<td>{{index}}</td>
<td>{{item.booksName}}</td>
<td>{{item.booksDate}}</td>
<td>{{item.booksPrice | showPrice}}</td>
<td>
<button @click='sub(index)' :disabled='item.count <= 1'>-</button>
{{item.count}}
<button @click='add(index)'>+</button>
</td>
<td><button @click='removeHandle'>删除</button></td>
</tr>
</tbody>
</table>
<div class="tprice">
总价:<span>{{totalPrice | showPrice}}</span>
</div>
</div>
<h2 v-else>购物车清空了</h2>
</div>
<script src="../js/vue.js"></script>
<script src="../js/1.books.js"></script>
const books = new Vue({
el: '#app',
data: {
books: [
{ booksName: '鲁宾逊漂流记', booksDate: 1999, booksPrice: 23.00, count: 1 },
{ booksName: '鲁宾逊漂流记', booksDate: 1999, booksPrice: 23.00, count: 1 },
{ booksName: '鲁宾逊漂流记', booksDate: 1999, booksPrice: 23.00, count: 1 },
]
},
methods: {
add(index) {
// this.[index].count++;
this.books[index].count++;
},
sub(index) {
// this.count[index]--;
this.books[index].count--;
},
removeHandle(index) {
this.books.splice(index, 1)
}
},
filters: {
showPrice(booksPrice) {
return '¥' + booksPrice.toFixed(2)
}
},
computed: {
totalPrice() {
let totalPrice = 0;
for (let i = 0; i < this.books.length; i++) {
totalPrice += this.books[i].booksPrice * this.books[i].count
}
return totalPrice;
}
}
})
-
------------恢复内容结束------------