一、vue3初体验之模板语法与常用指令

87 阅读4分钟

一. 邂逅Vue.js开发

1.1. Vue介绍

  • Vue的介绍

    • Vue (读音 /vju/,类似于 view) 是一套用于构建用户界面渐进式 JavaScript框架
    • 全称是Vue.js或者Vuejs
    • 它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型
    • 帮助你高效地开发用户界面,无论任务是简单还是复杂
  • 什么是渐进式框架呢?

    • 表示我们可以在项目中一点点来引入和使用Vue,而不一定需要全部使用Vue来开发整个项目
  • Vue在前端的地位

    • react
    • angular
  • 直接学习Vue3

1.2. Vue下载和使用

  • CDN引入

    <script src="https://unpkg.com/vue@next"></script>
    
  • 下载引入

    • 下载Vue的源码,可以直接打开CDN的链接

      • 打开链接,复制其中所有的代码
      • 创建一个新的文件,比如vue.js,将代码复制到其中
    • 通过script标签,引入刚才的文件:

      <script src="../js/vue.js"></script>
      
  • 通过npm包管理工具安装使用

  • 直接通过Vue CLI创建项目,并且使用它

vue的基本体验

<div id="app"></div>
 <!-- CDN地址 -->
 <script src="https://unpkg.com/vue@next"></script>
 <script>
   // 1.创建vue
   const app = Vue.createApp({
     template: `<h2>Hello World</h2><span>呵呵呵</span>`,
   });
   // 2.挂载app
   app.mount("#app");
 </script>

1.3. Vue的三个案例

1.3.1. 动态数据展示

    <div id="app"></div>
    <script src="./lib/vue.js"></script>
    <script>
      const app = Vue.createApp({
        // 插值语法{{title}}
        template: `<h2>{{title}}</h2>`,
        data() {
          return {
            title: "你好啊,vue3",
          };
        },
      });
​
      app.mount("#app");
    </script>

1.3.2. 动态展示列表

  • v-for
    <div id="app"></div>
    <script src="./lib/vue.js"></script>
    <script>
      const app = Vue.createApp({
        template: `
          <h2>电影列表</h2>
          <ul>
            <li v-for="item in movies">{{item}}</li>  
          </ul>
        `,
        data: function () {
          return {
            message: "你好啊,李银河",
            movies: ["大话西游", "星际穿越", "盗梦空间", "少年派", "飞驰人生"],
          };
        },
      });
​
      app.mount("#app");
    </script>

1.3.3. 计数器案例

  • counter
  • increment
  • decrement
   <div id="app">
      <h2>当前计数: {{counter}}</h2>
      <button @click="increment">+1</button>
      <button @click="decrement">-1</button>
    </div>
    <script src="./lib/vue.js"></script>
    <script>
      const app = Vue.createApp({
        data: function () {
          return {
            counter: 0,
          };
        },
        methods: {
          increment:function() {
            this.counter++;
          },
          decrement:function() {
            this.counter--;
          },
        },
      });
​
      app.mount("#app");
    </script>

1.4. 命令式和声明式编程的区别

  • 原生实现计时器
    <h2>当前计数: <span class="counter"></span></h2>
    <button class="add">+1</button>
    <button class="sub">-1</button>
​
    <script>
      // 1.获取DOM
      const h2El = document.querySelector("h2");
      const counterEl = document.querySelector(".counter");
      const addBtn = document.querySelector(".add");
      const subBtn = document.querySelector(".sub");
​
      // 2.定义一个变量记录数据
      let counter = 0;
      counterEl.textContent = counter;
​
      // 2.监听按钮点击
      addBtn.onclick = function () {
        counter++;
        counterEl.textContent = counter;
      };
​
      subBtn.onclick = function () {
        counter--;
        counterEl.textContent = counter;
      };
    </script>
  • 声明式编程

    • 声明式编程关注的是 “what to do”,由框架(机器)完成 “how”的过程

    • 我们会在createApp传入的对象中声明需要的内容,模板template、数据data、方法methods;这样的编写代码的过程,我们称之为是声明式编程

    • 目前Vue、React、Angular、小程序的编程模式,我们称之为声明式编程

      用vue实现计数器就是声明式编程
      
  • 命令式编程

    • 命令式编程关注的是 “how to do”自己完成整个how的过程

    • 我们每完成一个操作,都需要通过JavaScript编写一条代码,来给浏览器一个指令; 这样的编写代码的过程,我们称之为命令式编程

    • 在早期的原生JavaScript和jQuery开发的过程中,我们都是通过这种命令式的方式在编写代码的

      原生实现计数器就是命令式编程
      

1.5. MVC和MVVM的模型区别

  • MVC和MVVM都是一种软件的体系结构

    • MVC是Model – View –Controller的简称,是在前期被使用非常框架的架构模式,比如iOS、前端
    • MVVM是Model-View-ViewModel的简称,是目前非常流行的架构模式
  • 通常情况下,我们也经常称Vue是一个MVVM的框架。

    • Vue官方其实有说明,Vue虽然并没有完全遵守MVVM的模型,但是整个设计是受到它的启发的

1.6. options api的data详解

  • data必须是一个函数, 函数会返回一个对象
  • data返回的对象, 会被Vue进行劫持(放到响应式系统中), 所以data的数据发生改变时, 界面会重新渲染

1.7. options api的methods详解

  • 对象 -> 很多函数

  • 里面函数不能是箭头函数:

    • this

二. 基础 - 模板语法

2.1. 添加代码片段

  • 第一步,复制自己需要生成代码片段的代码

  • 第二步,snippet-generator.app/在该网站中生成代码片段

  • 第三步,在VSCode中配置代码片段

    • 文件->首选项->配置用户代码片段

2.2. mustache语法(插值语法)

  • 表达式

        <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>{{formateDate(time)}}</h2>
    
          <!-- 4.注意:这里不能定义语句 -->
          <!-- <h2>{{const name = "why"}}</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: {
              formateDate(date) {
                return "2023-03-06-" + date;
              },
            },
          });
    
          // 2.挂载app
          app.mount("#app");
        </script>
    

2.3. 不算常用的指令

  • 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() {
                this.message = "你好啊,李银河";
                this.counter += 100;
                console.log(this.message,this.counter);
              },
            },
          });
    
          // 2.挂载app
          app.mount("#app");
        </script>
    
  • v-text: 用于更新元素的 textContent:

        <div id="app">
          <h2>{{message}} bb</h2>
          <h2 v-text="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",
              };
            },
          });
    
          // 2.挂载app
          app.mount("#app");
        </script>
    
  • 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>
    
  • v-pre:用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签

    • 跳过不需要编译的节点,加快编译的速度
        <div id="app">
          <div v-pre>
            <h2>{{message}}</h2>
            <h2>当前计数: {{counter}}</h2>
            <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>
    
  • v-cloak:这个指令保持在元素上直到关联组件实例结束编译

    • 和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕
    <!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>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>
    

2.4. 新的指令 v-memo

    <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() {
            // this.name = "kobe";
            this.age = 20;
          },
        },
      });

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

2.5. v-bind绑定属性

2.5.1. v-bind绑定基本属性

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

      <!-- 1.绑定img的src属性 -->
      <!-- 语法糖:v-bind -> : -->
      <img :src="showImageUrl" alt="" />
      <img v-bind:src="showImageUrl" alt="" />
      <!-- 2.绑定a的href属性 -->
      <a :href="href">百度一下</a>
      <a v-bind: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",

            showImageUrl:
              "http://p1.music.126.net/agGc1qkogHtJQzjjyS-kAA==/109951167643767467.jpg",
            href: "http://www.baidu.com",
          };
        },
        methods: {
          switchImage() {
            this.showImageUrl =
              this.showImageUrl === this.imgUrl1 ? this.imgUrl2 : this.imgUrl1;
          },
        },
      });

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

2.5.2. v-bind绑定class

  • 基本绑定

  • 对象语法:

    • { className: Boolean }
  • 数组语法:

<!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>Document</title>
    <style>
      .active {
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- 1.基本绑定class -->
      <h2 :class="classes">Hello World</h2>

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

      <!-- 2.1 对象语法的基本使用 -->
      <button @click="btnClick" :class="{active:isActive}">我是按钮</button>

      <!-- 2.2 对象语法的多个键值对 -->
      <button @click="btnClick" :class="{active:isActive,why:true,kobe:false}">我是按钮</button>

      <!-- 2.3 动态绑定的class是可以和普通的class同时的使用 -->
      <button class="abc cba" :class="{active:isActive,why:true,kobe:false}">我是按钮</button>

      <!-- 2.4 动态绑定的class是可以和普通的class同时的使用 -->
      <button class="abc cba" :class="getDynamicClasses()" @click="btnClick">我是按钮</button>

      <!-- 3.动态class可以写数组语法 -->
      <h2 :class="['abc','cba']">Hello World</h2>
      <h2 :class="['abc',className]">Hello World</h2>
      <h2 :class="['abc',className,isActive ? 'active':'']">Hello World</h2>
      <h2 :class="['abc',className, {active:isActive}]">Hello World</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>

2.5.3. v-bind绑定style

  • 对象语法:

    • { cssname: cssvalue }
  • 数组语法:

    • [obj1, obj2]
    <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,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>

2.6. 动态绑定属性名

:[name]=""
 <div id="app">
      <h2 :[name] ='"aaa"'>Hello World</h2>
    </div>
    <script src="../lib/vue.js"></script>
    <script>
      // 1.创建app
      const app = Vue.createApp({
        // data:option api
        data: function () {
          return {
            name:"title"
          };
        },
      });

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

2.7. v-bind绑定对象

  • 将对象中所有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,
            },
            name: "why",
            age: 18,
            height: 1.88,
          };
        },
      });

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