Vue3之模版语法(二):Mustache插值语法,常见基本指令,v-bind绑定属性,绑定class和style,v-on绑定事件,Vue的条件渲染

VSCode代码片段✨

我们在前面练习Vue的过程中,有些代码片段是需要经常写的,我们再VSCode中我们可以生成一个代码片段,方便我们快速生成。VSCode中的代码片段有固定的格式,所以我们一般会借助于一个在线工具来完成
具体的步骤如下:

  1. 复制自己需要生成代码片段的代码;
  2. https://snippet-generator.app/在该网站中生成代码片段;
  3. 在VSCode中配置代码片段(文件——首选项——配置用户代码片段)
    在这里插入图片描述

模版语法✨

  • React的开发模式
  1. React使用的jsx,所以对应的代码都是编写的类似js的一种语法
  2. 之后通过Babel将jsx编译成 React.createElement函数调用
  • Vue的开发模式
  1. Vue也支持jsx的开发模式,后续会提到,但是大多数下,使用基于HTML的模板语法
  2. 在模板中,允许开发者以声明式的方式将DOM底层组件实例的数据绑定在一起
  3. 在底层的实现中,Vue将模板编译成虚拟DOM渲染函数

1. Mustache插值语法✨

如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号) 的文本插值:

  • Mustache中,不仅仅可以是data中属性,也可以是一个JavaScript的表达式
  • 当·data中的数据发生改变时,对应的内容也会发生更新
  <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> -->

  </div>
  

错误使用;
在这里插入图片描述

2.常见基本指令(了解)✨

接下来的指令都是写在dom标签的属性一样写在标签里面

2.1 v-once⭐

作用:v-once用于指定元素或者组件只渲染一次:

  • 当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过

  • 如果是子节点,也是只会渲染一次
    在这里插入图片描述

  • 该指令可以用于性能优化
    在这里插入图片描述

  <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>

在这里插入图片描述

2.2 v-text⭐

作用:v-text主要用于更新对应标签的textContent,如果标签中已经有内容,那么就会把v-text指令绑定的内容替换原有的内容,因此v-text使用较少,推荐使用Mustache语法更加灵活
在这里插入图片描述

2.3 v-html⭐

作用:在默认情况下,如果内容本身是html形式的字符串,那么vue并不会对其进行特殊的解析。如果我们希望这个内容可以被Vue解析,那么可以使用v-html来完成:

<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>

在这里插入图片描述

2.4 v-pre⭐

作用:v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签,主要就是跳过不需要的编译结点,加快编译的速度。(若有子元素,则子元素也不会进行编译)

<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>

在这里插入图片描述

2.5 v-cloak⭐

作用:根据浏览器的渲染流程,会首先解析body标签中的dom元素,然后才开始解析script引用标签,最后才开始执行脚本。如果文件过大,执行时间过长,就会导致我们写的Mustache语法会以未编译的形式展示在页面中。
因此,这个指令保持在元素上直到关联组件实例结束编译
在这里插入图片描述

2.6 v-memo⭐

作用:缓存一个模板的子树。该指令需要传入一个固定长度的依赖值数组进行比较,只有当其中的某依赖值被更新时,被缓模版的子树才会重写渲染。 若与每个值都与最后一次的渲染相同(就是渲染的时候发现没变,就用原来的旧的),那么整个子树的更新将被跳过。

<div id="app">
    <div v-memo="[name, age]">
      <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>

3. v-bind绑定属性✨

上述常见的基本指令,主要是控制值插到模版内容中,但是处理内容需要动态来决定外,某些属性我们也希望动态来绑定,比如:动态绑定a元素的href属性。

3.1 作用⭐

  1. v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
  2. 在开发中还有很多属性需要动态进行绑定,如:图片的链接src、网站的链接href、动态绑定一些类、样式等
  3. 语法糖 使用 :

3.2 切换图片的案例:⭐

  <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>

4. v-bind绑定class✨

4.1 作用⭐

开发中,有时候我们的元素class也是动态的:当数据为某个状态时,字体显示红色,另外一个状态下,字体显示黑色。

4.2 绑定class有两种方式:⭐

  1. 对象语法:我们可以传给 :class (v-bind:class 的简写) 一个对象,以动态地切换 class。
 <!-- 1.基本绑定class -->
    <h2 :class="classes">Hello World</h2>

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

    <!-- 2.1.对象语法的基本使用(掌握) -->
    <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>
  1. 数组语法:我们可以把一个数组传给 :class,以应用一个 class 列表;
<!-- 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>

实例:

 <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>

5.v-bind绑定style✨

5.1 作用⭐

  1. 因为某些样式我们需要根据数据动态来决定,比如某段文字的颜色,大小。通过使用v-bind:style来绑定一些 CSS内联样式
  2. CSS property名可以用驼峰式(camelCase)短横线分隔(kebab-case,记得用引号括起来)来命名。

5.2 其中绑定style也有两种方式:⭐

1. 对象语法

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

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

2. 数组语法

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

实例:

<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>

5.3 动态绑定属性名⭐

在某些情况下,我们属性的名称可能也不是固定的:

  • 前端我们无论绑定src、href、class、style,属性名称都是固定的
  • 如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义
    这种绑定的方式,属性名会动态变化,我们称之为动态绑定属性名
    在这里插入图片描述

5.4 绑定一个对象⭐

如果我们希望把一个对象中的所有key:value都绑定到元素或者组件上绑定的对象会被拆解作为绑定元素或组件上的属性

<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>

6. v-on绑定事件✨

在前面我们知道了如何用v-bind和Mustache插值语法来绑定来元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互,在Vue中我们可以使v-on指令

6.1 v-on的基本使用

  1. 基本写法
<!-- 1.基本的写法 -->
<div class="box" v-on:click="divClick"></div>
  1. v-on绑定事件的语法糖(重点掌握)
<!-- 2.语法糖写法(重点掌握) -->
<div class="box" @click="divClick"></div>
  1. 绑定的方法位置,直接写表达式(一般不推荐使用)
<!-- 3.绑定的方法位置, 也可以写成一个表达式(不常用, 不推荐) -->
    <h2>{{ counter }}</h2>
    <button @click="increment">+1</button>
    <button @click="counter++">+1</button>
  1. 绑定多个事件,对象写法和一般写法
<!-- 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> -->

案例-vue实例

  <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>

6.2 v-on的参数传递

当通过methos的方法,以供事件调用时,需要注意:

  • 无传参
    1. 在绑定事件时,可以省略 ()
    2. 如果methos里的方法本身有一个参数,那么会默认将原生事件event参数传进去
<!-- 1.默认传递event对象 -->
    <button @click="btn1Click">按钮1</button>
<!-- 2.只有自己的参数 -->
    <button @click="btn2Click('why', age)">按钮2</button>
  • 传入参数,并且需要event事件对象
    1. 需要传入多个参数且希望event也有时,我们需要在绑定事件那里用$event来指定哪一个是event
<!-- 3.自己的参数和event对象 -->
    <!-- 在模板中想要明确的获取event对象: $event -->
    <button @click="btn3Click('why', age, $event)">按钮3</button>
<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>

6.3 v-on的修饰符

v-on支持修饰符,修饰符相当于对事件进行了一些特殊的处理:

修饰符作用
.stop调用 event.stopPropagation()
.prevent调用 event.preventDefault()
.capture添加事件侦听器时使用 capture 模式
.self只当事件是从侦听器绑定的元素本身触发时才触发回调
.{keyAlias}仅当事件是从特定键触发时才触发回调
.once只触发一次回调
.left只当点击鼠标左键时触发
.right只当点击鼠标右键时触发
.middle只当点击鼠标中键时触发
.passive{ passive: true } 模式添加侦听器

7. Vue的条件渲染✨

在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断了

7.1 v-if、v-else、v-else-if

这三个指令与JavaScript的条件语句if、else、else if 类似,只有在条件为true时,才会被渲染出来。

<!-- 模板语法 -->
  <div id="app">
    <ul v-on:click="" v-if="names.length > 3">
      <li v-for="item in names">{{item}}</li>
    </ul>
    <h2 v-else-if="0 < names.length <3">当前names长度在0到3</h2>
    <h2 v-else>当前names没有数据, 请求获取数据后展示</h2>
  </div>

  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      // data: option api
      data: function () {
        return {
          names: [1, 2, 3, 4]
        }
      },
    })

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

v-if的渲染原理是惰性的:

  • 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉
  • 当条件为true时,才会真正渲染条件块中的内容

可以看到只有 “优秀”的h1元素才被渲染了,其他的内容连dom结构都是不存在的,完全没有加载

<div id="app">
    <h1 v-if="score > 90"> 优秀</h1>
    <h2 v-else-if="score > 80">良好</h2>
    <h3 v-else-if="score >= 60">及格</h3>
    <h4 v-else>不及格</h4>
  </div>

在这里插入图片描述

7.2 template元素

为什么要有temple元素:

  • 因为v-if是一个指令,所以必须将其添加到一个元素上,让其是一个整体。
  • 但如果这个元素是一个div那么就存在一个弊端:最外层的div在每次渲染出来都是没有存在的必要的
  • 在vue2就必须要用div包起来,而vue3就用template元素

template元素

  • 目的是将一个整体包裹在一起,元素本身没有特殊含义,最终template是不会渲染的,总结作用就是可以当做不可见的包裹元素,并且在v-if上使用,但是最终template不会被渲染出来,类似于小程序中的block
<div id="app">
    <!-- v-if="条件" -->
    <div class="info" v-if="Object.keys(info).length">
      <h2>个人信息</h2>
      <ul>
        <li>姓名: {{info.name}}</li>
        <li>年龄: {{info.age}}</li>
      </ul>
    </div>

    <!-- v-else -->
    <div v-else>
      <h2>没有输入个人信息</h2>
      <p>请输入个人信息后, 再进行展示~</p>
    </div>
  </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>
  <style>
    img {
      width: 200px;
      height: 200px;
    }
  </style>
</head>
<body>

  <div id="app">
    <div>
      <button @click="toggle">切换</button>
    </div>
    
    <template v-if="isShowCode">
      <img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
    </template>
  </div>
  
  <script src="../lib/vue.js"></script>
  <script>
    // 1.创建app
    const app = Vue.createApp({
      // data: option api
      data() {
        return {
          isShowCode: true
        }
      },

      methods: {
        toggle() {
          this.isShowCode = !this.isShowCode
        }
      }
    })

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

7.3 v-show

v-show和v-if的用法看起来是一致的,也是根据一个条件决定是否显示元素或者组件

<div v-show="isShowCode">
      <img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
</div>

7.4 v-if和v-show的区别

  1. 用法上的区别:
    • v-show是不支持template元素的
    • v-show不可以和v-else一起使用
  2. 本质的区别:
    • v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有存在的,只是通过CSS的display属性来进行切换
    • v-if当条件为false时,其对应的原生压根不会被渲染到DOM中
  3. 开发时如何选择:
    • 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用v-show
    • 如果不会频繁的发生切换,那么使用v-if
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值