Vue

在 Vue 中,指令都带有 v- 前缀,以表示它们是 Vue 提供的特殊的 attribute,它们会在渲染 DOM 是进行特殊的响应式行为。

Vue 内置了一些常用的指令

1. v-if 和 v-else 条件渲染指令

2. v-show 条件展示指令;

3. v-for 列表渲染指令;

4. v-bind 条件绑定指令;

5. v-on 事件处理指令;

下面我们来应用一下这些指令的基本使用。

1)内容绑定,事件绑定

1.1)v-text

设置标签文的内容(textContent)

默认写法会替换全部内容,使用差值表达式 {{}} 可以替换指定内容

<!DOCTYPE html>
<html lang="en">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-text</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1 v-text="message">你好</h1>    <!--Cyan-->
            <h1 v-text="ah+'!!!'">你好</h1>   <!--啊哈哈哈哈哈哈!!!-->
            <h1>你好呀 {{message+' !'}}!!</h1><!--你好呀 Cyan !!!-->
        </div>

        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    message: "Cyan",
                    ah: "啊哈哈哈哈哈哈"
                }
            });
        </script>
    </body>
</html>

1.2)v-html

设置标签的 innerHTML

内容中有 html 结构会被解析为标签

v-text 指令无论内容是什么,只会解析为文本

<!DOCTYPE html>
<html lang="en">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-html</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <p v-text="content"></p>
            <p v-html="content"></p><!--能转义html标签-->
        </div>

        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    content: "<a href='http://www.baidu.com' target='_blank'>百度</a>"
                }
            });
        </script>
    </body>
</html>

1.3)v-on

为元素绑定事件,监听事件。

- 事件名不需要写 on

- 指令可以简写为 @

- 绑定的方法定义在 methods 属性中

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-on</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
<!--在这里我们使用了 v-on 绑定了 click 事件,并指定了名为 alertTimechangeFood 的方法-->
<input type="button" value="v-on指令" v-on:click="alertTime"> <input type="button" value="v-on简写" @click="alertTime"> <input type="button" value="双击事件" @dblclick="alertTime"> <h2 @click="changeFood">{{food}}</h2> </div> <script> var vm = new Vue({ el: "#app", data: { food: "西红柿 + 鸡蛋 = ?" }, methods: { alertTime: function () { alert(new Date().toLocaleString()); }, changeFood: function () { this.food = "西红柿炒蛋"; alert(this.food); } } }); </script> </body> </html>

2)显示切换,属性绑定

2.1)v-show

根据数据的真假状态切换元素的显示状态

原理是修改元素的 display,实现显示隐藏

指令后面的内容,最终都会解析为布尔值

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-show</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <div>
                <button @click="changFlag">【点击文字改变显示状态】/button>
                <h2 v-show="flag" style="color: green">你好呀 嘎嘎嘎!!!</h2>
            </div>
            <br/>
            <div>
                年龄:
                <button @click="add">+</button>
                {{age}}
                <button @click="sub">-</button>
                <br/>
                小明是否成年?
                <strong style="color: green" v-show="age>=18"></strong>
                <strong style="color: blue" v-show="age<18"></strong>
            </div>
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    flag: false,
                    age: 16
                },
                methods: {
                    changFlag: function () {
                        this.flag = !this.flag;
                    },
                    add: function () {
                        this.age++;
                    },
                    sub: function () {
                        this.age--;
                    }
                }
            });
        </script>
    </body>
</html>

2.2)v-if

根据表达式的真假,切换元素的显示和隐藏(操纵dom元素)

本质是通过操纵 dom 元素来切换显示状态

表达式的值 为 true 时 元素存在于 dom 树中,为 false 时 从 dom 树中移除

繁的切换时使用 v-show,反之使用 v-if,前者消耗小

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-if</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="button" value="切换状态显示" @click="changeDisplay">
            <h2 v-if="isShow">这是v-if修饰的</h2><!--当表达式为 true 时,dom 元素才显示-->
            <h2 v-show="isShow">这是v-show修饰的</h2><!--无论表达式是否为 true 都显示 dom 元素,show 只是修改添加修改样式 display: none;-->
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                data: { isShow: true },
                methods: {
                    changeDisplay: function () {
                        this.isShow = !this.isShow;
                    }
                }
            });
        </script>
    </body>
</html>

2.3)v-bind

为元素绑定属性(如:src、title、class)

完整写法为 v-bind:属性名

简写为 :属性名

需要动态的增删 class 建议使用对象的方式

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-bind</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
        <style>
            .active {width: 30%;height: 30%; }
        </style>
    </head>
    <body>
        <div id="app">
            <button @click="changeDisplay">切换显示</button>
            <br/>
            <img v-bind:src="imgSrc1" v-bind:title="imgTitle1" v-bind:class="isActive?'active':''">
            <!-- 三元表达式:isActive?'active':''-->
            <img :src="imgSrc2" :title="imgTitle2" :class="isActive?'':'active'"><!--简写-->
        </div>

        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    imgSrc1: "https://wx3.sinaimg.cn/mw690/5301ff11ly1gb58jyz6fgj20p00p0q5g.jpg",
                    imgTitle1: "喵喵警长",
                    imgSrc2: "https://wx3.sinaimg.cn/mw690/5301ff11ly1gb58jwjhikj20p00p0q4l.jpg",
                    imgTitle2: "皮在痒",
                    isActive: false
                },
                methods: {
                    changeDisplay: function () {
                        this.isActive = !this.isActive;
                    }
                }
            });
        </script>
    </body>
</html>

2.4)图片切换

① 使用 v-bind 绑定 img 的 src 属性来动态显示图片

② 用 v-on 将实现上一页下一页的两个方法绑定到 button 按钮中,button 元素用到了 v-show 指令 当显示图片到达头尾部即不显示按钮。

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <mate charset="UTF-8"></mate>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Demo-1</title>
</head>
<body>
    <!--2.Vue层 模板-->
    <div id="app" style="margin: 0px 200px">
        <button @click="prve" v-show="index>0">上一页</button>
        <button @click="next" v-show="index<imgArr.length-1" style="float: right">下一页</button>
        <img :src="imgArr[index]" style="padding: 5px 0px;" width="100%" height="100%">
    </div>
    <!--1.导入Vue.js-->
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                /* 图片集 */
                imgArr: [
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390251&di=05c50276b28a39223e375c84dea3fe9f&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fe%2F564423fb9d994.jpg",
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=229bcd8fba04a0c3ada3a70c57a41ba3&imgtype=0&src=http%3A%2F%2Fimage.imufu.cn%2Fforum%2F201507%2F14%2F112717k2c3ejgqaelj9aa7.jpg",
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=ad2e4ca9e99c3887a1b0d1636da350a8&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F7%2F58f8549329800.jpg",
                    "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1271003329,4165191310&fm=26&gp=0.jpg",
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390250&di=09d8b4a6ef6eeae3d58f32c496b77aec&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F3%2F583e9b8758dd3.jpg",
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390249&di=36884556d13a815c5aa5093ba8910766&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F1%2F590c26814e7a3.jpg",
                    "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3465729551,2491385452&fm=26&gp=0.jpg",
                    "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3322203117,337153453&fm=26&gp=0.jpg",
                    "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605936390249&di=3c6b7982199fb18d23f824bae344b120&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F6%2F5984113d8db74.jpg",
                ],
                /* 显示索引 */
                index: 0
            },
            methods: {
                /* 上一页 */
                prve: function () {
                    if (this.index > 0)
                        this.index -= 1;
                    else
                        this.index = this.imgArr.length - 1;
                },
                /* 下一页 */
                next: function () {
                    if (this.index < this.imgArr.length - 1)
                        this.index += 1;
                    else
                        this.index = 0;
                }
            }
        });
    </script>
</body>
</html>

3)列表循环,表单元素绑定

3.1)v-for

根据数据生成列表结构

该指令一般都是和数组结合使用的

语法:(item,index) in 数据

item 和 index 可以结合其它指令一起使用

数组长度的更新会响应式的同步到页面上

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-for</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">遍历普通数组:
            <ul>
                <li v-for="(item,index) in arr">索引:{{index+1}} - 城市:{{item}}</li>
            </ul>
            遍历对象数组:
            <input type="button" value="添加数据" @click="add">
            <input type="button" value="删除数据" @click="remove">
            {{vagetables}}
            <ul>
                <li v-for="item in vagetables">{{item.name}}</li>
            </ul>
        </div>
        <script> var vm = new Vue({
            el: "#app",
            data: {
                arr: ["北京", "上海", "广州", "深圳", "杭州", "福建", "天津", "哈尔滨", "武汉", "西藏"],
                vagetables: [{name: "火山飘雪"}, {name: "粉身碎骨小青龙"}, {name: "黑白无常"}, {name: "沉默的羔羊"}, {name: "青龙卧雪"}, {name: "绝代双骄"}, {name: "热情小炒肉"}]
            },
            methods: {
                add: function () {
                    this.vagetables.push({name: "一个小菜"});
                }, remove: function () {
                    // alert("删除 " + this.vagetables.shift().name); /* 弹出队首 */
                    alert("删除 " + this.vagetables.pop().name); /* 弹出队尾 */
                }
            }
        });</script>
    </body>
</html>

3.2)v-on

为元素绑定事件

事件绑定的方法写成 函数调用 的形式,可以传入自定义参数

定义方法时需要定义 形参 来接收传入的实参

可以使用 @keyup.修饰符 来对事件进行限制

@keyup.enter 可以限制触发的按键为回车键

事件修饰符有多种

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-on</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="button" value="点击" @click="sayHi('铁汁','小伙纸')"><!--可以输入参数-->
            <input type="text" @keyup.enter="method('哈喽')"><!--绑定回车键-->
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                methods: {
                    sayHi: function (s1, s2) {
                        alert("你好 " + s1 + " !")
                        alert("你好 " + s2 + " !")
                    },
                    method: function (str) {
                        alert(str);
                    }
                }
            });
        </script>
    </body>
</html>

3.3)v-model

获取和设置表单元素的值(双向数据绑定)

绑定的数据会和表单元素的值相关联

绑定的数据 ← → 表单元素的值

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>v-model</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="message" @keyup.enter="getMsg" placeholder="输入后按回车键弹出"/>
            <h2 style="text-align: center;color: green">
                ↓↓↓ 双向同步显示 ↓↓↓
                <br/>
                {{message}}
            </h2>
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    message: ""
                },
                methods: {
                    getMsg: function () {
                        alert(this.message);
                    }
                }
            });
        </script>
    </body>
</html>

3.4)记事本

使用上面所学指令,实现一个记事本。

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <mate charset="UTF-8"></mate>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>记事本</title>
        <!-- 导入Vue.js -->
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    </head>
    <style>
        #app {width: 650px;min-height: 280px;margin: 0 auto;border: 5px outset rgb(209 224 227);background: beige;}
        /* header */
        .header h1 {text-align: center;color: #ffffff;background-color: rgb(200 220 221)}
        .header input {margin-left: 482px;width: 150px;}
        /* content */
        table {margin: auto; /*垂直居中*/text-align: center; /*文字居中*/width: 88%; /*宽度*/font-family: verdana, arial, sans-serif;font-size: 11px;color: #333333;border-width: 1px;border-color: #999999;border-collapse: collapse;}
        table th {background: #b5cfd2 url('cell-blue.jpg');border-width: 1px;padding: 8px;border-style: solid;border-color: #999999;}
        table td {background: #dcddc0 url('cell-grey.jpg');border-width: 1px;padding: 8px;border-style: solid;border-color: #999999;}
        /* 统计 */
        .census {text-align: right;font-size: 0.7em;padding-right: 10px;}
        /* footer */
        .footer {color: #a0a0a0;text-align: center;font-size: 0.3em;}
    </style>
    <body>
        <!-- 主体区域 -->
        <div id="app">
            <!-- 输入框 -->
            <div class="header">
                <h1>记事本</h1>
                <!-- vue 监听键盘回车事件 -->
                <input type="text" v-model="msg" placeholder="添加任务 回车键确认" @keyup.enter="setMsg"/>
            </div>
            <hr>
            <!-- 列表区域 -->
            <table>
                <tr>
                    <th>序号</th>
                    <th>任务</th>
                    <th>操作</th>
                </tr>
                <tr v-if="messages.length>0" v-for="(item,index) in messages">
                    <td>{{index+1}}</td>
                    <td>{{item}}</td>
                    <td>
                        <button @click="delMsg(index)">delete</button>
                    </td>
                </tr>
                <tr v-if="messages.length<=0">
                    <td>-</td>
                    <td>-</td>
                    <td></td>
                </tr>
            </table>
            <hr>
            <!-- 统计和清空任务 -->
            <div class="census">
                <!-- 表示数组的元素不为0时才显示 -->
                <span>
                    <!-- 统计任务 - 显示数组长度 -->
                    <strong>{{messages.length}}</strong>
                    items left
                </span>
                <!-- 清空任务 - 数组置空 -->
                <button @click="delMsgs" :style="messages.length>0?'cursor: pointer':'cursor: not-allowed'">Clear
                </button>
            </div>
            <!-- 底部 -->
            <hr>
            <div class="footer">
                <p>
                    Copyright © 2020 青 · 大漠孤烟
                    <br/>
                    Powered by .VUE 2.6.12
                </p>
            </div>
        </div>

        <script>
            var vm = new Vue({
                el: "#app",
                data: {
                    msg: "",
                    messages: []
                },
                methods: {
                    setMsg: function () {
                        this.messages.push(this.msg);/* 将数据添加到数组中 */
                        this.msg = "";/* 清空输入框数据 */
                    },
                    delMsg: function (index) {
                        this.messages.splice(index, 1); /* 删除指定下标起的1个元素 */
                    },
                    delMsgs: function () {
                        if (this.messages.length > 0)
                            this.messages = []; /* 将数组置空,实现清空数据 */
                    }
                }
            });
        </script>
    </body>
</html>
原文地址:https://www.cnblogs.com/Dm920/p/14452963.html