Vue template syntax (1)

1. Template syntax

The development mode of React:

  • React uses jsx , so the corresponding code is written in a syntax similar to js ;
  • Then compile jsx into React.createElement function call through Babel ;

Vue also supports jsx development mode:

  • But mostly, using HTML- based templating syntax ;
  • In the template, developers are allowed to bind the DOM and the data of the underlying component instance in a declarative manner ;
  • In the underlying implementation, Vue compiles templates into virtual DOM rendering functions ;

2. Mustache double braces syntax

        If we wish to display data into a template , the most used syntax is text interpolation with " Mustache" syntax ( double curly braces ) .

  • And as we mentioned earlier , the object returned by data is added to Vue 's responsive system ;
  • When the data in data changes , the corresponding content will also be updated .
  • Of course, Mustache can not only be an attribute in data , but also a JavaScript expression .
<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>Document</title>
</head>
<body>

    <div id="app">

        <!-- 1.基本使用 -->
        <h2>{
   
   { message }}</h2>
        <h2>当前计数: {
   
   { counter }} </h2>

        <!-- 2.表达式 -->
        <h2>计数双倍: {
   
   { counter * 2 }}</h2>
        <h2>展示的信息: {
   
   { info.split(" ") }}</h2>

        <!-- 3.三元运算符 -->
        <h2>{
   
   { age >= 18 ? "成年人" : "未成年人" }}</h2>

        <!-- 4.调用methods中函数 -->
        <h2>{
   
   { formatDate(time) }}</h2>

        <!-- 5.注意: 这里不能定义语句 -->
        <!--这是一个赋值语句,不是表达式-->
        <!-- <h2>{
   
   { const name = "why" }}</h2> -->

        <!--控制流的if语句也是不支持的,可以使用三元运算符-->
        <!-- <h2>{
   
   { if (true) { return message } }}</h2> -->

    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    message: "Hello Vue",
                    counter: 100,
                    info: "my name is why",
                    age: 22,
                    time: 123
                }
            },

            methods: {
                formatDate: function (date) {
                    return "2022-10-10-" + date
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

3. v -once command

v-once is used to specify that an element or component is rendered only once :

  • When the data changes, the element or component and all its child elements will be regarded as static content and skipped;
  • This instruction can be used for performance optimization ;

If it is a child node, it will only be rendered once:

<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>Document</title>
</head>
<body>

  <div id="app">

    <!-- 指令: v-once -->
    <h2 v-once>
      {
   
   { message }}
      <span>数字: {
   
   {counter}}</span>
    </h2>

    <h1>{
   
   {message}}</h1>

    <button @click="changeMessage">改变message</button>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      // data: option api
      data: function() {
        return {
          message: "Hello Vue",
          counter: 100
        }
      },

      methods: {
        changeMessage: function() {
          this.message = "你好啊, 李银河"
          this.counter += 100
          console.log(this.message, this.counter)
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>
</html>

4. v -text command

For updating the textContent of the element:

<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>Document</title>
</head>
<body>

    <div id="app">
        <h2> aa {
   
   {message}} bbb</h2>
        <!-- 与{
   
   {}}方式不同,v-text会将元素原本的内容清空,然后再添加内容 -->
        <h2 v-text="message">aaa</h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    message: "Hello Vue"
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

5、v-html

  • By default, if the content we display is HTML , Vue will not parse it specially .
  • If we want this content to be parsed by Vue , we can use v-html to display it;
<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>Document</title>
</head>
<body>

    <div id="app">
        <h2>{
   
   { content }}</h2>
        <h2 v-html="content"></h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    content: `<span style="color: red; font-size: 30px;">哈哈哈</span>`
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

6、in -for

v-pre is used to skip the compilation process of the element and its children , displaying the original Mustache tag :

Skip the nodes that do not need to be compiled to speed up the compilation;

<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>Document</title>
</head>
<body>

    <div id="app">
        <div v-pre>
            <h2>{
   
   { message }}</h2>
            <p>当前计数: {
   
   { counter }}</p>
            <p>{
   
   {}}</p>
        </div>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    message: "Hello Vue",
                    counter: 0
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

7、v-cloak

  • This directive remains on the element until the associated component instance finishes compiling.
  • When used with CSS rules such as [v-cloak] { display: none } , this directive can hide uncompiled Mustache tags until the component instance is ready.
  • <div>  will not be displayed until the compilation is complete.
<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>Document</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>

    <div id="app">
       <!--这个只有元素编译完成后才会显示-->
        <h2 v-cloak>{
   
   {message}}</h2>
    </div>

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

        setTimeout(() => {
            // 1.创建app
            const app = Vue.createApp({
                // data: option api
                data: function () {
                    return {
                        message: "Hello Vue"
                    }
                },
            })

            // 2.挂载app
            app.mount("#app")
        }, 3000)

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

8、v-memo  

  • Expected bound value type:any[]

  • details

    Cache a subtree of templates. Available on both elements and components. In order to implement caching, this instruction needs to pass in a fixed-length array of dependency values ​​for comparison. If every value in the array is the same as the last render, the update of the entire subtree will be skipped.

<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>Document</title>
</head>
<body>

    <div id="app">
        <div v-memo="[name]"> <!--表示只有在数组中定义的属性发生变化时,才会渲染,数组之外的属性改变,不会引起页面渲染-->
            <h2>姓名: {
   
   { name }}</h2>
            <h2>年龄: {
   
   { age }}</h2>
            <h2>身高: {
   
   { height }}</h2>
        </div>
        <button @click="updateInfo">改变信息</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    name: "why",
                    age: 18,
                    height: 1.88
                }
            },

            methods: {
                updateInfo: function () {
                    // this.name = "kobe"
                    this.age = 20
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

9、v-bind

The series of instructions mentioned above are mainly to insert values ​​into the template content .

However, in addition to the content that needs to be determined dynamically, we also want to bind certain attributes dynamically.

  • For example, dynamically bind the href attribute of the a element ;
  • For example, dynamically bind the src attribute of the img element ;

To bind properties we use v-bind:

  • Abbreviation : :
  • 预期:any (with argument) | Object (without argument)
  • Parameters : attrOrProp (optional)
  • Modifiers : .camel - converts kebab-case attribute names to camelCase.
  • Usage : Dynamically bind one or more attributes , or a component prop to an expression.

9.1. Binding basic properties

  • v-bind is used to bind one or more property values , or pass props values ​​to another component (this will be introduced when you learn components);
  • In development, which attributes need to be dynamically bound?
    • There are still many, such as the link src of the picture , the link href of the website , dynamic binding of some classes, styles, etc.
  • v-bind has a corresponding syntactic sugar , which is shorthand .
  • In development, we usually use syntactic sugar because it is more concise.
<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>Document</title>
</head>
<body>

    <div id="app">
        <div>
            <button @click="switchImage">切换图片</button>
        </div>

        <!-- 1.绑定img的src属性 -->
        <img v-bind:src="showImgUrl" alt="">
        <!-- 语法糖: v-bind -> : -->
        <img :src="showImgUrl" alt="">

        <!-- 2.绑定a的href属性 -->
        <a :href="href">百度一下</a>

    </div>
  
    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    imgUrl1: "http://p1.music.126.net/agGc1qkogHtJQzjjyS-kAA==/109951167643767467.jpg",
                    imgUrl2: "http://p1.music.126.net/_Q2zGH5wNR9xmY1aY7VmUw==/109951167643791745.jpg",

                    showImgUrl: "http://p1.music.126.net/_Q2zGH5wNR9xmY1aY7VmUw==/109951167643791745.jpg",
                    href: "http://www.baidu.com"
                }
            },

            methods: {
                switchImage: function () {
                    this.showImgUrl = this.showImgUrl === this.imgUrl1 ? this.imgUrl2 : this.imgUrl1
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

9.2, binding class

In development, sometimes our element class is also dynamic, such as:

  • When the data is in a certain state , the font is displayed in red.
  • When the data is in another state, the font is displayed in black.

There are two ways to bind a class:

  • object syntax
  • array syntax

Object syntax: We can pass an object to :class (short for v-bind:class) to switch classes dynamically .

Array syntax: We can pass an array to :class to apply a class list;

<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>Document</title>
  <style>
    .active {
      color: red;
    }
  </style>
</head>
<body>

  <div id="app">
    <!-- 1.基本绑定class -->
    <h2 :class="classes">Hello World</h2>

    <!-- 2.动态class可以写对象语法 -->
    <button :class=" isActive ? 'active': '' " @click="btnClick">我是按钮</button>

    <!-- 2.1.对象语法的基本使用(掌握) {key:value},value值的类型必须为布尔值,true则会添加,反之则不会添加-->
    <button :class="{ active: isActive }" @click="btnClick">我是按钮</button>

    <!-- 2.2.对象语法的多个键值对 -->
    <button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>
    
    <!-- 2.3.动态绑定的class是可以和普通的class同时的使用 -->
    <button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>
    
    <!-- 2.4.动态绑定的class是可以和普通的class同时的使用 -->
    <button class="abc cba" :class="getDynamicClasses()" @click="btnClick">我是按钮</button>

    <!-- 3.动态class可以写数组语法(了解) -->
    <h2 :class="['abc', 'cba']">Hello Array</h2>
    <h2 :class="['abc', className]">Hello Array</h2>
    <h2 :class="['abc', className, isActive? 'active': '']">Hello Array</h2>
    <h2 :class="['abc', className, { active: isActive }]">Hello Array</h2>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      // data: option api
      data: function() {
        return {
          classes: "abc cba nba",
          isActive: false,
          className: "why"
        }
      },

      methods: {
        btnClick: function() {
          this.isActive = !this.isActive
        },

        getDynamicClasses: function() {
          return { active: this.isActive, why: true, kobe: false }
        }
      }
    })

    // 2.挂载app
    app.mount("#app")
  </script>
</body>
</html>

9.3, binding style

We can use v-bind:style to bind some CSS inline styles :

  • This time, because of some styles, we need to dynamically decide according to the data ;
  • For example, the color, size, etc. of a certain text ;

CSS property names can be named in camelCase or dash-separated (kebab-case , remember to enclose them in quotation marks ) ;

There are two ways to bind a class :

  • object syntax
  • array syntax

The array syntax of :style can apply multiple style objects to the same element;

<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>Document</title>
</head>
<body>

    <div id="app">
        <!-- 1.普通的html写法 -->
        <h2 style="color: red; font-size: 30px;">哈哈哈哈</h2>

        <!-- 2.style中的某些值, 来自data中 -->
        <!-- 2.1.动态绑定style, 在后面跟上 对象类型 (重要) 使用驼峰命名-->
        <!-- <h2 v-bind:style="{ color: fontColor, 'font-size': '30px' }">哈哈哈哈</h2> -->
        <h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">哈哈哈哈</h2>
        <!-- 2.2.动态的绑定属性, 这个属性是一个对象 -->
        <h2 :style="objStyle">呵呵呵呵</h2>

        <!-- 3.style的数组语法 -->
        <h2 :style="[objStyle, { backgroundColor: 'purple' }]">嘿嘿嘿嘿</h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    fontColor: "blue",
                    fontSize: 30,
                    objStyle: {
                        fontSize: '50px',
                        color: "green"
                    }
                }
            },
        })

        // 2.挂载app
        app.mount("#app")

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

9.4, dynamic binding properties

In some cases, the names of our properties may not be fixed either:

  • No matter whether we bind src , href , class , style, the attribute name is fixed;
  • If the attribute name is not fixed , we can use the format of : [ attribute name ] = " value " to define;
  • This binding method is called dynamic binding property ;
<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>Document</title>
</head>
<body>

    <div id="app">
        <!--值需要"''"进行包裹,才是字符串,""包裹的是js代码-->
        <h2 :[name]="'aaaa'">Hello World</h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    name: "class"
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

9.5, bind an object

  • What should we do if we want to bind all properties of an object to all properties of an element ?
    • Very simple, we can directly use v-bind to bind an object ;
  • Case: The infos object will be disassembled into each attribute of the div
<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>Document</title>
</head>
<body>

    <div id="app">
        <!-- 原始方式 -->
        <h2 :name="name" :age="age" :height="height">Hello World</h2>

        <!-- 新的方式直接绑定对象,效果与上述代码一致 -->
        <!-- v-bind绑定对象: 给组件传递参数 -->
        <h2 v-bind="infos">Hello Bind</h2>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    infos: {name: "why", age: 18, height: 1.88, address: "广州市"},

                    name: "why",
                    age: 18,
                    height: 1.88
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

10. v -on binding event

Earlier we bound the content and attributes of elements . Another very important feature in front-end development is interaction .

In front-end development, we often need to interact with users in various ways:

  • At this time, we must listen to events that occur to the user, such as clicks, drags, keyboard events , etc.
  • How to listen to events in Vue ? Use the v-on directive .

10.1, usage of v-on

The use of v-on :

Abbreviation : @

Expected : Function | Inline Statement | Object

Parameters : event

Modifiers :

  1. .stop  : Call event.stopPropagation ().
  2. .prevent  : Call event.preventDefault (). 
  3. .capture  : Use capture mode when adding event listeners .
  4. .self :  The callback is only fired when the event is fired from the element itself to which the listener is bound.
  5. .{keyAlias}  : Only fire the callback if the event is fired from a specific key.
  6. .once : Trigger the callback only once.
  7. .left  : Fires only when the left mouse button is clicked.
  8. .right  : Fires only when the right mouse button is clicked.
  9. .middle  : Fires only when the middle mouse button is clicked.
  10. .passive  : { passive: true } mode add listener

Usage : bind event listener

10.2 Basic usage of v-on

<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>Document</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: orange;
            margin-top: 10px;
        }
    </style>
</head>
<body>

    <div id="app">
        <!-- 1.基本的写法 -->
        <div class="box" v-on:click="divClick"></div>

        <!-- 2.语法糖写法(重点掌握) -->
        <div class="box" @click="divClick"></div>

        <!-- 3.绑定的方法位置, 也可以写成一个表达式(不常用, 不推荐) -->
        <h2>{
   
   { counter }}</h2>
        <button @click="increment">+1</button>
        <button @click="counter++">+1</button>

        <!-- 4.绑定其他方法(掌握) -->
        <div class="box" @mousemove="divMousemove"></div>

        <!-- 5.元素绑定多个事件(掌握) -->
        <div class="box" @click="divClick" @mousemove="divMousemove"></div>
        <!-- <div class="box" v-on="{ click: divClick, mousemove: divMousemove }"></div> -->
        <!-- <div class="box" @="{ click: divClick, mousemove: divMousemove }"></div> -->
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    counter: 0
                }
            },
            methods: {
                divClick() {
                    console.log("divClick")
                },
                increment() {
                    this.counter++
                },
                divMousemove() {
                    console.log("divMousemove")
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

10.3, v-on parameter passing

When defining methods in methods for @click calls, you need to pay attention to parameter issues:

  • Case 1: If the method does not require additional parameters, then the () after the method may not be added .
    • But note: if there is a parameter in the method itself, the native event event parameter will be passed in by default
  • Case 2: If you need to pass in a certain parameter and event at the same time, you can pass in the event through $event .
<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>Document</title>
</head>
<body>

    <div id="app">
        <!-- 1.默认传递event对象 -->
        <button @click="btn1Click">按钮1</button>

        <!-- 2.只有自己的参数 -->
        <button @click="btn2Click('why', age)">按钮2</button>

        <!-- 3.自己的参数和event对象 -->
        <!-- 在模板中想要明确的获取event对象: $event -->
        <button @click="btn3Click('why', age, $event)">按钮3</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    message: "Hello Vue",
                    age: 18
                }
            },
            methods: {
                // 1.默认参数: event对象
                // 总结: 如果在绑定事件的时候, 没有传递任何的参数, 那么event对象会被默认传递进来
                btn1Click(event) {
                    console.log("btn1Click:", event)
                },

                // 2.明确参数:
                btn2Click(name, age) {
                    console.log("btn2Click:", name, age)
                },

                // 3.明确参数+event对象
                btn3Click(name, age, event) {
                    console.log("btn3Click:", name, age, event)
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

10.4. Modifiers for v -on

v-on supports modifiers , which are equivalent to some special handling of events:

<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>Document</title>
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: orange;
        }
    </style>
</head>
<body>

    <div id="app">
        <div class="box" @click="divClick">
            <button @click.stop="btnClick">按钮</button>
        </div>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
        // 1.创建app
        const app = Vue.createApp({
            // data: option api
            data: function () {
                return {
                    message: "Hello Vue"
                }
            },
            methods: {
                btnClick(event) {
                    console.log("btnClick")
                },
                divClick() {
                    console.log("divClick")
                }
            }
        })

        // 2.挂载app
        app.mount("#app")
    </script>
</body>
</html>

Guess you like

Origin blog.csdn.net/weixin_52851967/article/details/128703416
Recommended