超详细:Vue入门-Vue 指令

时间:2024-11-09 16:35:46

指令的概念

        指令 (Directives) 是特殊的带有前缀 v- 的特性。指令的值限定为绑定表达式,因此上节提到的插值表达式这里也是可以适用,只是不需要编写双花括号了。指令的职责就是当其表达式的值改变时把某些特殊的行为应用到 DOM 上。

常用指令

        内容输出指令 v-text、v-html,条件渲染指令 v-if、 v-else、v-show,列表渲染指令 v-for,数据绑定指令 v-model、v-bind,事件绑定指令 v-on等。

内容输出指令
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 使用插值表达式 -->
        <p>{{ msg }}</p>
        <!-- 使用 v-text 指令 -->
        <p v-text="msg"></p>
        <!-- 使用 v-html 指令 -->
        <p v-html="msg"></p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                msg: '<h1>Hello Vue!</h1>',
            }
        });
    </script>
</body>

</html>
条件渲染指令

作为模板语言,条件判断也是必不可少的,其中 v-if 和 v-else 指令是控制元素是否需要出现在 DOM 树结构中,注意 v-else 指令必须紧跟着 v-if 指令的后面,中间不能添加其他元素。而 v-show 是控制元素是否需要显示在界面中,此元素会一直存在于 DOM 树结构中。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div v-if="ok">我是 v-if 指令控制的 DIV</div>
        <div v-else>我是 v-else 指令控制的 DIV</div>
        <div v-show="show">我是 v-show 指令控制的 DIV</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                ok: true,
                show: true
            }
        });
    </script>
</body>

</html>

我们设置数据 ok 为 true,show 也为 true,查看浏览器运行效果,并键入 F12 打开“开发者工具”中的 Elements 选项卡,查看对应的 DOM 结构,可以发现我们写了 3 个 DIV 元素,但是在 DOM 结构中只有 v-if 和 v-show 的 DIV 存在,v-else 对应的 DIV 因为不满足条件,被删除了。

 接下来我们把 ok show 都设置为 false,再查看结果。

data : {
    ok : false,
    show : false
}

运行结果如图所示,页面只显示了 v-else 指令内容,而 v-show 是通过将 CSS 样式中 display设置为 none 的方式隐藏的,依然存在于 DOM 结构中。

        下面我们总结一下 v-if 和 v-show 的区别,v-if 控制的是元素是否需要出现在 DOM 结构中,作用是添加和删除元素,v-show 控制的是元素的隐藏和显示,无论是否显示都一直在 DOM 结构中。

        从结果来看 v-if 和 v-show 都是元素是否渲染在界面上,那么使用时就可以随便选么?当然不是,它们各自的使用场景如下:

  •  v-if 指令有更高的切换消耗,因为条件成立时是需要通过添加元素改变 DOM 树结构的,不成立时又要删除元素且内部指令不执行,如果频繁的显示和隐藏性能消耗大,适合首次加载时判断是否需要渲染,后续不再更改条件。
  • v-show 无论条件是否成立,元素都必须添加到 DOM 树中,所以有更高的初始渲染消耗,通过 CSS 样式来控制是否显示,性能消耗小,适合频繁切换显示隐藏的元素。

列表渲染指令
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <ul>
            <!-- 使用 v-for 修饰的 li 标签会重复生成 -->
            <!-- course 是循环元素(课程),index 是下标 -->
            <li v-for="(course,index) in courses" :key="index">
                {{index}} 、课程:{{course.name}}
                <ul>
                    <!-- 嵌套循环,显示课程的章节信息 -->
                    <li v-for="(chapter,idx) in course.chapters" :key="idx">
                        {{idx}} 、章节:{{chapter.name}} 课时:{{chapter.lesson}}
                    </li>
                </ul>
            </li>
        </ul>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                courses: [
                    {
                        name: "前端框架入门", chapters: [
                            { name: "Vue.js", lesson: 4 },
                            { name: "React.js", lesson: 8 },
                            { name: "Angular.js", lesson: 16 }
                        ]
                    },
                    {
                        name: "后端框架入门", chapters: [
                            { name: "MyBatis", lesson: 8 },
                            { name: "Spring", lesson: 8 },
                            { name: "SpringMVC", lesson: 16 }
                        ]
                    }
                ]
            }
        });
    </script>
</body>

</html>
数据绑定指令
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 写死 src,不能动态改变 -->
        <img src="images/vue.png" />
        <!-- 使用 v-bind 指令,可动态改变 src -->
        <img v-bind:src="imageSrc" />
        <!-- 简写写法 -->
        <img :src="imageSrc" />
        <!-- 绑定对象,则属性值为 true 的添加,false 的不添加 -->
        <p v-bind:class="{ classA: hasA, classB: hasB }">段落 1</p>
        <!-- 绑定数组,则数组中的样式都会添加 -->
        <p v-bind:class="classArray">段落 2</p>
    </div>
    <script src=" https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                imageSrc: 'images/vue.png',
                hasA: false,
                hasB: true,
                classArray: ['classA', 'classC']
            }
        });
        setTimeout(function () {
            // 3 秒后修改图片属性值,查看图片是不是变化了
            app.imageSrc = 'images/react.png';
        }, 3000);
    </script>
</body>

</html>

我们需要等待 3 秒后,可以看到后面两张图片的变化,因为我们通过 Vue 实例对象修改了 imageSrc 这个属性,导致用 v-bind:src 绑定此属性的两张图片的 src 跟着变化。再看”开发者工具”中的 Elements 选项卡,会发现段落 1 中只用到了类样式 classB,因为 hasB 为 true值。段落 2 则使用了数组,所以类样式 ClassA 和 ClassC 都存在。

事件绑定指令
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <style>
        .container {
            width: 400px;
            margin: 0 auto;
            text-align: center;
        }

        .square {
            width: 200px;
            height: 200px;
            background-color: red;
            margin: 0 auto;
        }
    </style>
    <div id="app" class="container">
        <div class="square" v-show="show"></div>
        <br />
        <button @click="toggle()">点击切换</button>
        <!-- <button v-on:click="toggle()">点击切换</button> -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                show: true
            },
            // 事件函数需定义在 methods 中
            methods: {
                // ES6 对象函数的简写方式
                toggle() {
                    this.show = !this.show;
                }
            }
        });
    </script>
</body>

</html>