Vue基础03模板语法

171 阅读2分钟

Vue基础03模板语法

学习Vue的模板语法(插值文本、列表渲染、表单输入绑定、事件处理、class与style绑定)及了解模板语法是如何实现的

1 模板语法

Vue.js使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue.js的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。

什么是模板语法?能够把Vue中声明的数据动态的展示在页面中。

下面以实现一个购物车为例介绍模板语法

1.1 插值文本,显示标题

数据绑定的实现方式

  1. 文本,双大括号
  2. 原始html,v-html
  3. 属性,v-bind
  4. 使用Javascript表达式,只能访问全局变量的一个白名单,如Date,Math
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
       <p>使用插值文本:{{title}}</p>
       <p>使用指令v-html:<span v-html="title"></span></p>
       <p>使用指令v-bind:<span v-bind:title="title" v-html="title"></p>
       <p>使用js表达式: {{title.split('').reverse().join('')}}</p>
    </div>

    <script src="../js/vue.js"></script>
    
    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '<span style="color:red">购物车</span>',
                    count: 1,
                }
            }
        })
    </script>
</body>
</html>

1.2 列表渲染,显示课程列表

使用v-for指令基于一个数组来渲染一个列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>
        <ul>
            <li v-for="c in courses" :key="c">{{c}}</li>
        </ul>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: ['Java开发', 'Vue开发']
                }
            }
        })
    </script>
</body>
</html>

1.3 输入绑定,显示课程表单

使用v-model指令在表单input、textarea、select上实现数据双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>
        <input v-model="course"> {{course}}
        <div v-for="item in courses" :key="item">
            {{ item }}
        </div>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: ['Web开发', 'Java开发'],
                    course: ''
                }
            }
        })
    </script>
</body>
</html>

1.4 事件处理,新增课程

使用v-on指令监听DOM事件,并在触发时运行JavaScript代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>
        <input v-model="course" v-on:keydown.enter="addCourse">
        <button v-on:click="addCourse">新增</button>
        <div v-for="item in courses" :key="item">
            {{ item }}
        </div>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: ['web开发', 'java开发'],
                    course: ''
                }
            },
            methods: {
                addCourse() {
                    if (this.course == '' || this.courses.indexOf(this.course) > -1) {
                        return
                    }
                    this.courses.push(this.course)
                    this.course = ''
                }
            },
        })
    </script>
</body>
</html>

1.5 class与style绑定,选中效果

class和内联样式的绑定

class实现选中效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
    <style>
        .active {
            background-color: #ddd;
        }
    </style>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>

        <input type="text" v-model="course" v-on:keydown.enter="addCourse"> 
        <button v-on:click="addCourse">新增</button>

        <div v-for="item in courses" :key="item" @click="selectedCourse = item" :class="{active: selectedCourse == item}">
            {{ item }}
        </div>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: ['web开发', 'java开发'],
                    course: '',
                    selectedCourse: ''
                }
            },
            methods: {
                addCourse() {
                    if (this.course == '' || this.courses.indexOf(this.course) > 0) {
                        reutrn
                    }
                    this.courses.push(this.course)
                    this.course = ''
                }
            },
        })
    </script>
</body>
</html>

style实现选中效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>

        <input type="text" v-model="course" v-on:keydown.enter="addCourse">
        <button v-on:click="addCourse">新增</button>

        <div v-for="item in courses" :key="item" 
            @click="selectedCourse = item"
            :style="{backgroundColor: (selectedCourse === item ? '#ddd' : 'transparent')}">
            {{ item }}
        </div>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: ['web course', 'java course'],
                    course: '',
                    selectedCourse: ''
                }
            },
            methods: {
                addCourse() {
                    if (this.course == '' || this.courses.indexOf(this.course) > 0) {
                        return
                    }
                    this.courses.push(this.course)
                    this.course = ''
                }
            },
        })

    </script>
</body>
</html>

1.6 条件渲染,课程为空时提示无课程

使用v-if指令根据条件来显示内容

v-if与v-show的区别?

v-if使用注意事项

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车</title>
</head>
<body>
    <div id="app">
        <h2>{{title}}</h2>

        <input type="text" v-model="course" v-on:keydown.enter="addCourse">
        <button @click="addCourse">新增</button>

        <div v-if="this.courses.length == 0">没有课程</div>
        <div v-if="this.courses.length > 0">
            <div v-for="item in courses" :key="item">
                {{ item }}
            </div>
        </div>
    </div>

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

    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    title: '购物车',
                    courses: [],
                    course: '',
                    selectredCourse: ''
                }
            },
            methods: {
                addCourse() {
                    if (this.course == '' || this.courses.indexOf(this.course) > -1) {
                        return
                    }
                    this.courses.push(this.course)
                    this.course = ''
                }
            },
        })
    </script>
</body>
</html>

2 模板语法是如何实现的

在底层的实现上,Vue将模板编译成虚拟DOM渲染函数.结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最少

// 输出vue替我们生成的渲染函数
console.log(app.$options.render)

image-20211023042103964.png

重写渲染函数

image-20220310142141910.png

结论:Vue通过它的编译器将模板编译成渲染函数,在数据发生变化的时候再次执行渲染函数,通过对比两次执行结果得出要做的dom操作.