代码改变世界

前端实验(二)模板语法 - 实践

2025-10-11 21:37  tlnshuju  阅读(27)  评论(0)    收藏  举报

实验目的

熟悉Vue实例模版
熟悉Vue模版语法核心语法
掌握Vue生命周期函数及其执行时机
掌握模板语法中条件渲染语法
掌握模板语法中循环渲染语法

实验步骤

  1. Vue实例解析
    在项目目录 D:/vue/demo 下创建 demo2.html 文件,并引入最新版Vue.js(推荐使用CDN)。该Vue实例拥有常用的配置项,包括生命周期函数、watch、computed等配置项。
<!DOCTYPE html>
  <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Vue3选项式API示例</title>
            <script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
              </head>
                <body>
                  <div id="app" class="container">
                    <h1>{{ title }}</h1>
                      <div class="section">
                        <h2>数据绑定</h2>
                          <p>计数器: {{ counter }}</p>
                            <button @click="increment">增加</button>
                              <button @click="decrement">减少</button>
                                </div>
                                  <div class="section">
                                    <h2>计算属性</h2>
                                      <p>计算属性结果: {{ computedMessage }}</p>
                                        <p>反转消息: {{ reversedMessage }}</p>
                                          </div>
                                            <div class="section">
                                              <h2>侦听器</h2>
                                                <input v-model="inputText" placeholder="输入内容观察watch效果">
                                                  <p>输入内容: {{ inputText }}</p>
                                                    <p>上次输入: {{ lastInput }}</p>
                                                      </div>
                                                        <div class="section">
                                                          <h2>组件生命周期</h2>
                                                            <p>组件创建时间: {{ createTime }}</p>
                                                              <button @click="updateTime">更新时间</button>
                                                                </div>
                                                                  </div>
                                                                    <script>
                                                                      const { createApp } = Vue;
                                                                      <!-- 使用构造函数创建Vue对象 -->
                                                                        createApp({
                                                                        // 
                                                                        <!-- 数据属性,使用闭包函数,隐藏对象的属性 -->
                                                                          data() {
                                                                          return {
                                                                          title: 'Vue3选项式API示例',
                                                                          counter: 0,
                                                                          inputText: '',
                                                                          lastInput: '',
                                                                          message: 'Hello Vue3!',
                                                                          createTime: ''
                                                                          }
                                                                          },
                                                                          <!-- 该对象方法属性,配置在mothod中,定义需要绑定在模板中对应的事件中 -->
                                                                            methods: {
                                                                            increment() {
                                                                            this.counter++;
                                                                            },
                                                                            decrement() {
                                                                            this.counter--;
                                                                            },
                                                                            updateTime() {
                                                                            this.createTime = new Date().toLocaleString();
                                                                            }
                                                                            },
                                                                            <!-- 计算属性,定义模板中需要显式的通过计算得到的数据 -->
                                                                              computed: {
                                                                              computedMessage() {
                                                                              return `当前计数是: ${this.counter}`;
                                                                              },
                                                                              reversedMessage() {
                                                                              return this.message.split('').reverse().join('');
                                                                              }
                                                                              },
                                                                              <!-- 监听属性,监听某个数据发生变化时响应的代码 -->
                                                                                watch: {
                                                                                counter(newVal, oldVal) {
                                                                                console.log(`计数器从 ${oldVal} 变为 ${newVal}`);
                                                                                },
                                                                                inputText(newVal) {
                                                                                this.lastInput = newVal;
                                                                                console.log(`输入内容更新为: ${newVal}`);
                                                                                }
                                                                                },
                                                                                <!-- 生命周期钩子函数,开发者可以在Vue实例的关键节点中插入自定义代码 -->
                                                                                  mounted() {
                                                                                  console.log('mounted: 组件已挂载到DOM');
                                                                                  }
                                                                                  }).mount('#app');
                                                                                  </script>
                                                                                    <style>
                                                                                      body {
                                                                                      font-family: 'Arial', sans-serif;
                                                                                      max-width: 800px;
                                                                                      margin: 0 auto;
                                                                                      padding: 20px;
                                                                                      background-color: #f5f7fa;
                                                                                      }
                                                                                      .container {
                                                                                      background: white;
                                                                                      border-radius: 8px;
                                                                                      padding: 30px;
                                                                                      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                                                                                      }
                                                                                      button {
                                                                                      background: #42b983;
                                                                                      color: white;
                                                                                      border: none;
                                                                                      padding: 8px 16px;
                                                                                      border-radius: 4px;
                                                                                      cursor: pointer;
                                                                                      margin: 5px;
                                                                                      transition: all 0.3s;
                                                                                      }
                                                                                      button:hover {
                                                                                      background: #369f6b;
                                                                                      }
                                                                                      input {
                                                                                      padding: 8px;
                                                                                      border: 1px solid #ddd;
                                                                                      border-radius: 4px;
                                                                                      margin: 5px;
                                                                                      }
                                                                                      </style>
                                                                                        </body>
                                                                                          </html>

由上例可以看书,使用构造函数CreateAPP创建Vue实例,该实例包含一系列属性(Vue提供一套模版),常用属性包括:data,mehtod、computed、watch等。其他属性如:props、compents等属性在后续介绍
2. 常用核心语法
在vue实例中使用函数,而非data属性。组件需要独立的数据空间以避免数据污染。若data为对象类型,所有复用的组件实例会共享同一数据空间,导致数据混乱。而函数返回新对象的方式确保每个组件实例拥有独立的数据副本,互不干扰。
Vue模版语法需使用Vue提供的一系列指令完成,vue指令使用前缀“v-”。新建html文件,演示核心语法,包括v-text指令, 大胡子语法{{}} ,数据绑定指令v-bind,v-bind简写 :,双向绑定:v-model,事件绑定:v-on,简写 @等。

<!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue核心语法演示</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
        </head>
        <body>
            <div id="app">
          <h1>Vue核心语法演示</h1>
            <!-- 1. 大胡子语法演示 -->
                <div class="demo-card">
              <h2>1. 大胡子语法 {{}}</h2>
              <p>消息内容: {{ message }}</p>
              <p>计算属性: {{ reversedMessage }}</p>
              </div>
              <!-- 2. v-text指令演示 -->
                  <div class="demo-card">
                <h2>2. v-text指令</h2>
                <p v-text="'使用v-text显示: ' + message"></p>
                <p>比较显示: <span v-text="message"></span> vs {{ message }}</p>
                </div>
                <!-- 3. v-bind指令演示 -->
                    <div class="demo-card">
                  <h2>3. v-bind数据绑定</h2>
                    <div>
                        <input type="color" v-model="bgColor">
                          <div class="dynamic-style" v-bind:style="{ backgroundColor: bgColor }">
                          动态样式绑定
                        </div>
                      </div>
                      <div>
                      <a v-bind:href="url">完整写法绑定</a>
                      <a :href="url">简写绑定</a>
                      </div>
                    </div>
                    <!-- 4. v-model双向绑定 -->
                        <div class="demo-card">
                      <h2>4. v-model双向绑定</h2>
                          <input v-model="message" placeholder="输入内容...">
                        <p>实时显示: {{ message }}</p>
                            <select v-model="selectedOption">
                              <option v-for="option in options" :value="option.value">
                              {{ option.text }}
                            </option>
                          </select>
                        <p>已选择: {{ selectedOption }}</p>
                        </div>
                        <!-- 5. 事件绑定 -->
                            <div class="demo-card">
                          <h2>5. 事件绑定 v-on/@</h2>
                          <button v-on:click="showAlert('完整写法')">完整写法</button>
                          <button @click="showAlert('简写')">简写@</button>
                          <button @click="counter++">计数器: {{ counter }}</button>
                          </div>
                        </div>
                        <script>
                          new Vue({
                          el: '#app',
                          data: {
                          message: 'Hello Vue!',
                          bgColor: '#42b983',
                          url: 'https://vuejs.org',
                          selectedOption: 'A',
                          options: [
                          { text: '选项A', value: 'A' },
                          { text: '选项B', value: 'B' },
                          { text: '选项C', value: 'C' }
                          ],
                          counter: 0
                          },
                          computed: {
                          reversedMessage() {
                          return this.message.split('').reverse().join('');
                          }
                          },
                          methods: {
                          showAlert(type) {
                          alert(`${type}事件绑定被触发!`);
                          }
                          }
                          });
                        </script>
                        <style>
                          body {
                          font-family: 'Arial', sans-serif;
                          max-width: 800px;
                          margin: 0 auto;
                          padding: 20px;
                          background-color: #f8f9fa;
                          }
                          .demo-card {
                          background: white;
                          border-radius: 8px;
                          padding: 20px;
                          margin-bottom: 20px;
                          box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                          }
                          h1 {
                          color: #42b983;
                          text-align: center;
                          }
                          h2 {
                          color: #35495e;
                          border-bottom: 1px solid #eee;
                          padding-bottom: 10px;
                          }
                          input, button, select {
                          padding: 8px 12px;
                          margin: 5px 0;
                          border-radius: 4px;
                          border: 1px solid #ddd;
                          }
                          button {
                          background-color: #42b983;
                          color: white;
                          border: none;
                          cursor: pointer;
                          transition: background-color 0.3s;
                          }
                          button:hover {
                          background-color: #369f6b;
                          }
                          .dynamic-style {
                          padding: 15px;
                          margin: 10px 0;
                          border-radius: 4px;
                          transition: all 0.3s;
                          }
                        </style>
                      </body>
                    </html>
  1. 生命周期函数
    在vue生命周期关键结点上,预设了一些函数,这些函数称作生命周期钩子函数。钩子函数会在生命周期中自动执行,无须使用事件监听。利用钩子函数,开发人员可以在合适的时机执行相应的业务逻辑代码。开发者必须了解生命周期中各个钩子函数执行的时机和条件。新建html文件,演示生命周期函数的执行时机。代码如下:
<!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue3 选项式生命周期演示</title>
        <script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
        </head>
        <body>
            <div id="app">
          <h1>Vue3 生命周期演示</h1>
          <p>当前计数: {{ count }}</p>
          <button @click="count++">增加计数</button>
          </div>
          <script>
            const { createApp } = Vue;
            const app = createApp({
            data() {
            return {
            count: 0,
            messageCount: NaN
            };
            },
            // 选项式生命周期钩子
            beforeCreate() {
            console.log('beforeCreate vue实例尚未创建,不能读取count数据'+ this.count);
            },
            created() {
            console.log('created,vue实例已创建创建'+ this.count);
            },
            beforeMount() {
            console.log('beforeMount,数据尚未渲染到页面,可以在此提取后台数据,页面可能会出现白屏');
            },
            mounted() {
            console.log('mounted,数据已完成渲染到页面,可以在此提取后台数据,页面可能不会出现白屏');
            },
            beforeUpdate() {
            console.log('beforeUpdate,在内存中的数据更新完成但页面节点尚未更新时触发,此时可以访问内存中的最新数据,但页面渲染的 DOM 还未同步更新 '+ ', 修改后的值为:'+this.count);
            },
            updated() {
            console.log('updated,数据跟新后代码,但页面渲染已完成'+this.count);
            },
            beforeUnmount() {
            console.log('beforeUnmount,实例销毁前,释放资源');
            },
            unmounted() {
            console.log('unmounted,实例销毁后,记录日志');
            }
            });
            app.mount('#app');
          </script>
        </body>
      </html>
  1. 条件渲染
    新建html文件,演示条件渲染,包括v-if v-else,v-show的使用。代码如下:
<style>
  body {
  font-family: 'Arial', sans-serif;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f5f7fa;
  }
  .container {
  background: white;
  border-radius: 8px;
  padding: 30px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  }
  .section {
  margin-bottom: 30px;
  padding: 20px;
  border: 1px solid #eee;
  border-radius: 8px;
  }
  button {
  background: #42b983;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  margin: 5px;
  transition: all 0.3s;
  }
  button:hover {
  background: #369f6b;
  }
  .user-card {
  background: #f8f9fa;
  padding: 15px;
  margin: 10px 0;
  border-radius: 4px;
  }
  .hidden {
  display: none;
  }
</style>
  1. 循环渲染
    新建html文件,演示循环渲染。代码如下:
<!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue3 循环渲染演示</title>
        <script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
        </head>
        <body>
            <div id="app">
          <h1>Vue3 循环渲染演示</h1>
              <div class="controls">
            <button @click="addItem">添加新项目</button>
            <button @click="shuffleItems">随机排序</button>
            <button @click="filterEven">筛选偶数ID</button>
            <button @click="reset">重置列表</button>
            </div>
              <div v-for="(item, index) in items" :key="item.id" class="item-card">
            <h3>项目 #{{ item.id }}</h3>
            <p>名称: {{ item.name }}</p>
            <p>创建时间: {{ item.createdAt }}</p>
            <button @click="removeItem(index)">删除</button>
            </div>
          <p v-if="items.length === 0">暂无项目,点击"添加新项目"按钮开始</p>
          </div>
          <script>
            const { createApp } = Vue;
            createApp({
            data() {
            return {
            items: [
            { id: 1, name: '项目A', createdAt: this.getCurrentTime() },
            { id: 2, name: '项目B', createdAt: this.getCurrentTime() },
            { id: 3, name: '项目C', createdAt: this.getCurrentTime() }
            ],
            nextId: 4
            };
            },
            methods: {
            getCurrentTime() {
            return new Date().toLocaleTimeString();
            },
            addItem() {
            const names = ['项目X', '项目Y', '项目Z', '项目W'];
            const randomName = names[Math.floor(Math.random() * names.length)];
            this.items.push({
            id: this.nextId++,
            name: randomName,
            createdAt: this.getCurrentTime()
            });
            },
            removeItem(index) {
            this.items.splice(index, 1);
            },
            shuffleItems() {
            this.items = [...this.items].sort(() => Math.random() - 0.5);
            },
            filterEven() {
            this.items = this.items.filter(item => item.id % 2 === 0);
            },
            reset() {
            this.items = [
            { id: 1, name: '项目A', createdAt: this.getCurrentTime() },
            { id: 2, name: '项目B', createdAt: this.getCurrentTime() },
            { id: 3, name: '项目C', createdAt: this.getCurrentTime() }
            ];
            this.nextId = 4;
            }
            }
            }).mount('#app');
          </script>
          <style>
            body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            }
            .item-card {
            background: #f5f5f5;
            border-radius: 8px;
            padding: 15px;
            margin: 10px 0;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            transition: transform 0.2s;
            }
            .item-card:hover {
            transform: translateY(-3px);
            }
            button {
            background: #42b983;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
            }
            button:hover {
            background: #369f6e;
            }
            .controls {
            margin: 20px 0;
            }
          </style>
        </body>
      </html>