05.vue-charp-05 内置指令

vue

目录

  • 基本指令
  • v-cloak
  • v-once
  • 条件渲染

    • v-if、v-else-if、v-else
    • v-show

  • 列表渲染 v-for

    • v-for中可选参数:Index
    • v-for 遍历对象属性

  • 数组更新

    • 数组元素和个数更新

  • 过滤与排序
  • 方法与事件

    • 基本用法
    • 修饰符

  • 练习:购物车

    • index.html
    • index.js
    • style.css

v-cloak

v-cloak不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display: none;配合使用:

这时虽然已经加了指令v-cloak,但其实并没有起到任何作用,当网速较慢、Vue.js文件还没加载完时,在页面上会显示{{ message }}的字样,直到Vue创建实例、编译模板时,DOM才会被替换,所以这个过程屏幕是有闪动的。只要加一句CSS就可以解决这个问题了:

[v-cloak] {

display: none;

}

在一般情况下,v-cloak是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但是在具有工程化的项目里,比如后面进阶篇将介绍webpack和vue-router时,项目的HTML结构只有一个空的div元素,剩余的内容都是由路由去挂载不同组件完成的,所以不再需要v-cloak。

v-once

不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容

<body>

<div >

<input type="text" v-model="message" placeholder="message" />

<h1 v-once>v-once指渲染一次:{{message}}</h1>

<h1>双向绑定,动态显示:{{message}}</h1>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

message: 'hello world'

}

})

</script>

</body>

条件渲染

v-if、v-else-if、v-else

<body>

<div >

<input type="text" v-model="status" placeholder="status值" />

<h1 v-if="status === 1">status值=1</h1>

<h1 v-else-if="status === 1">status值=1</h1>

<h1 v-else="status === 1">status值=1</h1>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

status: 1

}

})

</script>

</body>

v-show

v-show是改变元素的CSS属性display。当v-show表达式的值为false时,元素会隐藏,查看DOM结构会 display: none;

<body>

<div >

<input type="text" v-model="status" placeholder="status值" />

<h1 v-show="status == 1">status值=1时才显示,否则隐藏</h1>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

status: 1

}

})

</script>

</body>

列表渲染 v-for

<body>

<div >

<ul>

<li v-for="book in books">{{ book.name }}</li>

</ul>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

books: [

{ name: '《Vue.js实战》' },

{ name: '《JavaScript语言精粹》' },

{ name: '《JavaScript高级程序设计》' }

]

}

})

</script>

</body>

v-for中可选参数:Index

<body>

<div >

<ul>

<li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>

</ul>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

books: [

{ name: '《Vue.js实战》' },

{ name: '《JavaScript语言精粹》' },

{ name: '《JavaScript高级程序设计》' }

]

}

})

</script>

</body>

v-for 遍历对象属性

遍历对象属性时,有两个可选参数,分别是键名和索引:

<body>

<div >

<ul>

<li v-for="value in user">{{value}}</li>

</ul>

<ul>

<li v-for="(value, key, index) in user">

{{ index }} - {{ key }}: {{ value }}

</li>

</ul>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

new Vue({

el: '#app',

data: {

user: {

name: 'Aresn',

gender: '男',

age: 26

}

}

})

</script>

</body>

数组更新

Vue在检测到数组变化时,并不是直接重新渲染整个列表,而是最大化地复用DOM元素。替换的数组中,含有相同元素的项不会被重新渲染,因此可以大胆地用新数组来替换旧数组,不用担心性能问题。

<body>

<div >

<ul>

<li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>

</ul>

<button type="button" @click="add">添加</button>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

var app = new Vue({

el: '#app',

data: {

books: [

{ name: '《Vue.js实战》' },

{ name: '《JavaScript语言精粹》' },

{ name: '《JavaScript高级程序设计》' }

]

},

methods: {

add: function () {

this.books.push({ name: '《Electron In Action》' });

}

},

})

</script>

</body>

数组元素和个数更新

需要注意的是,以下变动的数组中,Vue是不能检测到的,也不会触发视图更新:

  • 通过索引直接设置项,比如app.books[3] = {…}。
  • 修改数组长度,比如app.books.length = 1。

解决第一个问题可以用两种方法实现同样的效果,第一种是使用Vue内置的set方法:

Vue.set(app.books, 3, {

name: '《CSS揭秘》',

author: '[希] Lea Verou'

});

如果是在webpack中使用组件化的方式(进阶篇中将介绍),默认是没有导入Vue的,这时可以使用$set,例如:

this.$set(app.books, 3, {

name: '《CSS揭秘》',

author: '[希] Lea Verou'

})

// 这里的this指向的就是当前组件实例,即app。在非webpack模式下也可以用$set方法,例如app.$set(…)

另一种方法:

app.books.splice(3, 1, {

name: '《CSS揭秘》',

author: '[希] Lea Verou'

})

第二个问题也可以直接用splice来解决:

app.books.splice(1);

<body>

<div >

<ul>

<li v-for="(book,index) in books">{{index}}.{{ book.name }}</li>

</ul>

<button type="button" @click="updateArrayElement">更新数组元素</button>

<button type="button" @click="deleArray">截取数组</button>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

var app = new Vue({

el: '#app',

data: {

books: [

{ name: '《Vue.js实战》' },

{ name: '《JavaScript语言精粹》' },

{ name: '《JavaScript高级程序设计》' }

]

},

methods: {

updateArrayElement: function () {

//方法1

this.books.splice(0, 1, { name: '《Vue.js实战》(this.books.splice)' });

//方法2

this.$set(this.books, 1, { name: '《JavaScript语言精粹》(app.$set)' });

//方法3

Vue.set(this.books, 2, { name: 'JavaScript高级程序设计》(Vue.set)' })

},

deleArray: function () {

this.books.splice(1);

}

}

})

</script>

</body>

过滤与排序

<body>

<div >

<ul>

<li v-for="(book,index) in books">{{book.id}}.{{ book.name }}</li>

</ul>

<ul>

<li v-for="(book,index) in filterBooks">{{book.id}}.{{ book.name }}</li>

</ul>

<ul>

<li v-for="(book,index) in sortedBooks">{{book.id}}.{{ book.name }}</li>

</ul>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

var app = new Vue({

el: '#app',

data: {

books: [

{ id: 1, name: '《Vue.js实战》' },

{ id: 2, name: '《JavaScript语言精粹》' },

{ id: 3, name: '《JavaScript高级程序设计》' }

]

}, computed: {

filterBooks: function () {

return this.books.filter(function (book) {

return book.name.match(/JavaScript/);

});

},

sortedBooks: function () {

return this.books.sort(function (a, b) {

return b.id - a.id;

});

}

},

})

</script>

</body>

方法与事件

基本用法

@click的表达式可以直接使用JavaScript语句,也可以是一个在Vue实例中methods选项内的函数

  • 无参数 可以不用写括号,如:@click="handleAdd"

  • 特殊变量$event:

    Vue提供了一个特殊变量$event,用于访问原生DOM事件,例如下面的实例可以阻止链接打开:

<body>

<div >

count:{{count}}

<button @click="add()">+1</button>

<button @click="add(10)">+10</button>

<button @click="add2">+1</button>

<a href="http://baidu.com" @click="addWithEvent('禁止打开', $event)">打开链接</a>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

var app = new Vue({

el: '#app',

data: {

count: 0,

}, methods: {

add: function (count) {

count = count || 1;

this.count += count;

},

add2: function () {

this.count += 1;

},

addWithEvent: function (msg, event) {

event.preventDefault();

alert(msg);

}

}

})

</script>

</body>

修饰符

在上例使用的event.preventDefault()也可以用Vue事件的修饰符来实现,在@绑定的事件后加小圆点“.”,再跟一个后缀来使用修饰符。Vue支持以下修饰符:

<body>

<div >

<a href="http://baidu.com" @click="addWithEvent1($event)">正常打开链接</a>

<a href="http://baidu.com" @click="addWithEvent2('禁止打开', $event)">禁止打开链接</a>

<a href="http://baidu.com" @click.prevent="addWithEvent3('禁止打开')">禁止打开链接</a>

</div>

<script src="../lib/vue.2.6.11.js"></script>

<script>

var app = new Vue({

el: '#app',

data: {

count: 0,

}, methods: {

addWithEvent1: function (event) {

alert(msg);

},

addWithEvent2: function (msg, event) {

event.preventDefault();

alert(msg);

},

addWithEvent3: function (msg, event) {

alert(msg);

}

}

})

</script>

</body>

练习:购物车

index.html

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>Vue 示例:购物车</title>

<link rel="stylesheet" type="text/css" href="style.css">

</head>

<body>

<div v-cloak>

<template v-if="list.length">

<table>

<thead>

<th>序号</th>

<th>商品名称</th>

<th>商品单价</th>

<th>购买数量</th>

<th>操作</th>

</thead>

<tbody>

<tr v-for="(item, index) in list">

<td>{{index + 1}} </td>

<td>{{item.name}}</td>

<td>{{item.price}}</td>

<td>

<button @click="handleReduce(index)" :disabled="item.count === 1">-</button>

{{item.count}}

<button @click="handleAdd(index)">+</button>

</td>

<td>

<button @click="handleRemove(index)">移除</button>

</td>

</tr>

</tbody>

</table>

<div>

总价:¥{{totalPrice}}

</div>

</template>

<div v-else>

购物车为空

</div>

</div>

<script src="../../lib/vue.2.6.11.js"></script>

<script src="index.js"></script>

</body>

</html>

index.js

var app = new Vue({

el: '#app',

data: {

list: [

{

id: 1,

name: "iphone7",

price: 6188,

count: 1

},

{

id: 2,

name: "IPad pro",

price: 5888,

count: 1

}, {

id: 3,

name: "MacBook Pro",

price: 21488,

count: 1

}

]

}, methods: {

handleReduce: function (index) {

if (this.list[index].count === 1) {

return;

}

this.list[index].count--;

},

handleAdd: function (index) {

this.list[index].count++;

},

handleRemove: function (index) {

this.list.splice(index, 1);

},

}, computed: {

totalPrice: function () {

let total = 0;

for (let i = 0; i < this.list.length; i++) {

const item = this.list[i];

total += item.price * item.count;

}

// return total;

return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');

}

}

})

style.css

[v-cloak] {

display: none;

}

table{

border: 1px solid #e9e9e9;

border-collapse: collapse;

border-spacing: 0;

empty-cells: show;

}

th, td{

padding: 8px 16px;

border: 1px solid #e9e9e9;

text-align: left;

}

th{

background: #f7f7f7;

color: #5c6b77;

font-weight: 600;

white-space: nowrap;

}[v-cloak] {

display: none;

}

table{

border: 1px solid #e9e9e9;

border-collapse: collapse;

border-spacing: 0;

empty-cells: show;

}

th, td{

padding: 8px 16px;

border: 1px solid #e9e9e9;

text-align: left;

}

th{

background: #f7f7f7;

color: #5c6b77;

font-weight: 600;

white-space: nowrap;

}

以上是 05.vue-charp-05 内置指令 的全部内容, 来源链接: utcz.com/z/380541.html

回到顶部