欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue-内置指令

程序员文章站 2022-05-15 22:49:39
...

条件渲染

v-if v-else-if v-else

vue在渲染元素时,出于效率考虑,会尽可能地复用已有的元素而非重新渲染

example:

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <template v-if="type === 'name'">
        <label>用户名:</label>
        <input placeholder="输入用户名">
    </template>
    <template v-else>
        <label>邮箱:</label>
        <input placeholder="输入邮箱">
    </template>
    <button @click="handleToggleClick">切换输入类型</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        type: 'name'
    },
    methods: {
        handleToggleClick: function() {
            this.type = this.type === 'name' ? 'mail' : 'name';
        }
    }
});

  

输入内容后,点切换按钮,虽然dom变了,只是替换了placehoder,input元素被复用

如果不希望这样做,可以使用vue.js提供的key属性,让你自己决定是否复用元素,key的值必须是唯一的

v-show

v-show是改变元素的css属性display,当v-show表达式的值为false时,元素会隐藏

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <p v-show="status === 1">当status为1时显示该行</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        status: 1
    }
});

  

列表渲染指令v-for

当需要将一个数组遍历或枚举一个对象循环显示时,就用到v-for,表达式需要结合in来实现

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <ul>
        <li v-for="book in books">{{ book.name }}</li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        books: [
            { name:'python核心编程'},
            { name:'go学习笔记'},
            { name:'vue.js实战'}
        ]
    }
});

  

在表达式中,books是数据,book是当前每个元素,元素.name能取出对应的值

v-for也能取出当前项的索引

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

  

v-for也能用在内置标签<template>上,将多个元素进行渲染

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <template v-for="book in books">
        <ul>
            <li>书名:{{book.name}}</li>
            <li>作者:{{book.author}}</li>
        </ul>
    </template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        books: [
            {
                name:'python核心编程',
                author:'a'
            },
            {
                name:'go学习笔记',
                author: 'b'
            },
            {
                name:'vue.js实战',
                author:'c'
            }
        ]
    }
});

  

除数组外,对象的属性也是可以遍历的,两个可选参数,键值和索引

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <ul>
        <li v-for="(value,key,index) in user"> {{index}}-{{key}}:{{value}}
        </li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        user: {
            name:'somebody',
            age:28,
            gender:'男'
        }
    }
});

  

数组更新

vue的核心是数据与视图的双向绑定,当修改数组时m,Vue会检测到数据变化,所以用v-for渲染的视图也会立即更新

push pop shift splice sort reverse

example:将之前一个示例的数据books添加一项

app.books.push({
    name: 'css揭秘',
    author: 'd'
});

  

使用以上方法会该改变被这些方法调用的原始数组,有些方法不会改变原数组

filter slice concat

example:找出书名包含vue的

app.books = app.books.filter(function (item) {
    return item.name.match(/vue/);
});

  

vue在检测到数组变化时,并不是直接重新渲染整个列表,而是最大化复用dom,含有相同元素的项不会被重新渲染,因此新数组来替换旧数据

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

  • 通过索引直接设置项
  • 修改数组长度

解决第一个问题可以用vue内置的set方法

Vue.set(app.books,2,{
    name: 'javascript',
    author: 'd',
});

  

也可以用splice方法

app.books.splice(2,1,{
    name: 'javascript',
    author: 'e'
});

  

过滤与排序

如果不想改变原数组,想通过一个数组的副本来做过滤或排序的显示,可以用计算属性来返回过滤或排序后的数组

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <template v-for="book in filterBooks">
        <ul>
            <li>书名:{{book.name}}</li>
            <li>作者:{{book.author}}</li>
        </ul>
    </template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        books: [
            {
                name:'python核心编程',
                author:'a'
            },
            {
                name:'go学习笔记',
                author: 'b'
            },
            {
                name:'vue.js实战',
                author:'c'
            }
        ]
    },
    computed: {
        filterBooks: function () {
            return this.books.filter(function (book) {
                return book.name.match(/vue/);
            })
        }
    }
});

  

排序和搜索类似,不会修改books

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <template v-for="book in sortedBooks">
        <ul>
            <li>书名:{{book.name}}</li>
            <li>作者:{{book.author}}</li>
        </ul>
    </template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        books: [
            {
                name:'python核心编程',
                author:'a'
            },
            {
                name:'go语言学习笔记',
                author: 'b'
            },
            {
                name:'vue.js实战',
                author:'c'
            }
        ]
    },
    computed: {
        sortedBooks: function () {
            return this.books.sort(function (a,b) {
                return a.name.length < b.name.length
            })
        }
    }
});

  

方法与事件

example:监听一个按钮的点击事件,设置计数器,每次点击加1

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    点击次数:{{ counter }}
    <button @click="counter++">+1</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

js

var app = new Vue({
    el: '#app',
    data: {
        counter:0
    }
})

  

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

example:再加一个加10的按钮

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    点击次数:{{ counter }}
    <button @click="handleAdd()">+1</button>
    <button @click="handleAdd(10)">+10</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

 

js

var app = new Vue({
    el: '#app',
    data: {
        counter:0
    },
    methods:{
        handleAdd:function (count) {
            count = count || 1;
            this.counter += count
        }
    }
})

  

练习:计算属性/指令开发购物车

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车示例</title>
    <link rel="stylesheet" href="main.css"/>
</head>
<div id="app">
    <template v-if="list.length">
        <table>
            <thead>
                <tr>
                    <th>
                        <button @click="allChoose">全选</button>
                    </th>
                    <th></th>
                    <th>商品名称</th>
                    <th>商品单价</th>
                    <th>商品数量</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(item,index) in list">
                    <td>
                        <input type="checkbox" v-model="item.checked">
                    </td>
                    <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="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>

  

 js

var app = new Vue({
    el:'#app',
    data: {
        list:[
            {
                id:1,
                name:'iphone',
                price:6188,
                count:1,
                checked:true,
            },
            {
                id:2,
                name:'ipad',
                price:5888,
                count:1,
                checked:true,
            },
            {
                id:3,
                name:'mbp',
                price:18888,
                count :1,
                checked:true,
            }
        ]
    },
    computed:{
        totalPrice:function () {
            var total=0;
            for (var i=0;i< this.list.length;i++) {
                var item = this.list[i];
                var status = this.list[i].checked;
                if (status === true)
                    total += item.price * item.count;
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g,',');
        }
    },
    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)
        },
        allChoose: function () {
            for (var i=0;i< this.list.length;i++) {
                this.list[i].checked = true;
            }
        }
    }

});

  

css

table {
    border:1px solid #e9e9e9;
}
th,td {
    padding: 8px 16px;
    border: 1px solid #e9e9e9;
    text-align: left;
}

  

 

上一篇: vue 内置指令

下一篇: Vue 内置指令