二五(Vue2-01)、创建实例、插值表达式、响应式、Vue指令(v-show v-if v-on v-bind v-for v-model)

发布于:2024-12-18 ⋅ 阅读:(65) ⋅ 点赞:(0)

1. Vue 概念及创建实例

<body>

  <!-- 
  创建Vue实例,初始化渲染
  1. 准备容器 (Vue所管理的范围)
  2. 引包 (开发版本包 / 生产版本包) 官网
  3. 创建实例
  4. 添加配置项 => 完成渲染
-->

  <div id="app">
    <h1>{{msg}}</h1>
    <a href="#">{{num}}</a>
  </div>

  <!-- 
    Vue是一个用于构建用户界面的渐进式框架
      构建用户界面 -- 基于数据动态渲染出用户看到的页面
      渐进式 -- 循序渐进
      框架 -- 一套完整的项目解决方案,提升开发效率
  -->
  <!-- 引入的是开发版本包 - 包含完整的注释和警告 -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

  <script>
    // 创建Vue实例 new Vue()
    const app = new Vue({
      // el 指定挂载点,选择器指定控制的是哪个盒子
      el: '#app',
      // data 提供数据
      data: {
        msg: 'hello world',
        num: 100
      }
    })

  </script>

</body>

2. 插值表达式

<body>

  <!-- 
  插值表达式:Vue的一种模板语法
  作用:利用表达式进行插值,将数据渲染页面中
  语法:{{ 表达式 }}
  表达式:是可以被求值的代码,JS引擎会将其计算出一个结果

  注意点:
    1. 使用的数据要存在
    2. 支持的是表达式,不是语句  if  for
    3. 不能在标签属性中使用 {{ }}
-->

  <div id="app">
    <!-- 插值表达式 -- 正确使用 -->
    <h3>{{ msg }}</h3>
    <p>{{ num }}</p>
    <p>{{ `num值为${num}` }}</p>
    <p>{{ num + 1 }}</p>
    <p>{{ num > 10 ? '大于10' : '小于等于10' }}</p>
    <p>{{ obj.name }}</p>
    <p>{{ arr[2] }}</p>

    <!-- 错误使用 -->
    <!-- 1. 数据不存在 -->
    <!-- <p>{{ price }}</p> -->
    <!-- 2. 插入语句 -->
    <!-- <p>{{ if(num>10) {console.log('num大于10')} }}</p> -->
    <!-- 3. 在标签属性中使用 -->
    <!-- <p title="{{ num }}"></p> -->
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        msg: 'Hello World',
        num: 20,
        obj: {
          name: 'Tom',
          age: 18
        },
        arr: [1, 5, 7, 2, 45, 89]
      }
    })

  </script>

</body>

3. 响应式特性

<body>

  <!-- 
    数据的响应式处理 → 响应式:数据变化,视图自动更新
    聚焦于数据 → 数据驱动视图
    使用 Vue 开发,关注业务的核心逻辑,根据业务修改数据即可
  -->

  <div id="app">
    <h3>在一个插值表达式中引用多个 data 属性</h3>
    <p>+拼接 {{name + ' ' + age}}</p>
    <p>模板字符串 {{ `${name} ${age}` }}</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        name: 'Tom',
        age: 18,
      }
    })

  </script>

</body>

4. Vue 指令

4.1 v-html v-text

<body>
  <!-- 
    Vue 指令
      指令就是带有 v- 前缀 的特殊 属性,不同属性 对应 不同的功能
      学习不同指令 → 解决不同业务场景需求

    动态解析标签:
      v-html = "表达式 " → 动态设置元素 innerHTML
  -->
  <!-- v-html 相当于 innerHTML,识别标签 -->
  <!-- v-text 相当于 innerText,不识别标签,把标签当成普通字符串 -->
  <div id="app">
    <div v-html="str"></div>
    <div v-html="str1">html超链接</div>
    <div v-text="str1">text超链接</div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        str: 'Hello',
        str1: '<a href="#">超链接</a>'
      }
    })
  </script>

</body>

4.2 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>Document</title>
  <style>
    .box {
      width: 200px;
      height: 100px;
      line-height: 100px;
      margin: 10px;
      border: 3px solid #000;
      text-align: center;
      border-radius: 5px;
      box-shadow: 2px 2px 2px #ccc;
    }
  </style>
</head>

<body>
  <!-- 
    v-show 底层原理:切换 css 的 display: none 来控制显示隐藏
      场景:频繁切换显示隐藏的场景

    v-if 底层原理:根据 判断条件 控制元素的 创建 和 移除(条件渲染)
      场景:要么显示,要么隐藏,不频繁切换的场景
  -->

  <div id="app">
    <div class="box" v-show="blF">我是v-show控制的盒子</div>
    <div class="box" v-if="blF">我是v-if控制的盒子</div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        blT: true,
        blF: false
      }
    })
  </script>

</body>

</html>

4.3 v-else v-else-if

<body>
  <!-- 
    v-else v-else-if
    作用:辅助 v-if 进行判断渲染
    注意:需要紧挨着 v-if 一起使用
  -->

  <div id="app">
    <p v-if="gender === 0">性别:♂ 男</p>
    <p v-else>性别:♀ 女</p>
    <hr>
    <p v-if="score >= 90">成绩评定A: 奖励电脑一台</p>
    <p v-else-if="score >= 70">成绩评定B: 奖励周末郊游</p>
    <p v-else-if="score >= 60">成绩评定C: 奖励零食礼包</p>
    <p v-else>成绩评定D: 惩罚一周不能玩手机</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        gender: 0,
        score: 99
      }
    })
  </script>

</body>

4.4 v-on

4.4.1 内联语句

4.4.2 无参函数

<!-- 
  v-on
  1. 作用:注册事件 = 添加监听 + 提供处理逻辑
  2. 语法:
    v-on:事件名 = "内联语句"
    v-on:事件名 = "methods中的函数名"
  3. 简写:@事件名 = "内联语句"
  4. 注意:methods函数内的 this 指向 Vue 实例
-->

<body>
  <div id="app">
    <!-- 1. 内联语句 -->
    <!-- <button v-on:click="num--" v-show="num>1">-</button>
    <span>{{ num }}</span>
    <button @click="num++">+</button> -->

    <!-- 2. 无参函数 -->
    <!-- 需要传参必须写(), 无参函数()有无不影响界面效果 -->
    <button v-on:click="reduce()" v-show="num>1">-</button>
    <span>{{ num }}</span>
    <button @click="add">+</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <!-- <script src="lib/vue.js"></script> -->
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        num: 5
      },
      // 封装函数的配置项
      methods: {
        add() { this.num++ },
        reduce() { this.num-- }
      }
    })
  </script>
</body>

4.4.3 案例 - 点击切换隐藏

<body>
  <div id="app">
    <button @click="fn">切换显示隐藏</button>
    <h1 v-show="flag">黑马程序员</h1>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        flag: true
      },
      methods: {
        fn() { this.flag = !this.flag }
      }
    })
  </script>

</body>

4.4.4 有参函数 案例 - 小黑自动售货机

<!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>
    .box {
      border: 3px solid #000000;
      border-radius: 10px;
      padding: 20px;
      margin: 20px;
      width: 200px;
    }

    h3 {
      margin: 10px 0 20px 0;
    }

    p {
      margin: 20px;
    }
  </style>
</head>

<body>

  <div id="app">
    <div class="box">
      <h3>小黑自动售货机</h3>
      <!-- v-bind:disabled="balance>0?false:true" -->
      <button @click="fn(5)" v-bind:disabled="flag">可乐5元</button>
      <button @click="fn(10)" v-bind:disabled="flag">咖啡10元</button>
      <button @click="fn(8)" v-bind:disabled="flag">牛奶8元</button>
    </div>
    <p>银行卡余额:{{balance}}元</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        balance: 100,
        // data 对象的属性初始化时不能直接引用其他属性,因为它们还没有被定义。
        // flag: this.balance > 0 ? false : true
      },
      // 计算属性
      computed: {
        flag() {
          return this.balance <= 0;
        }
      },
      methods: {
        fn(price) {
          // this.balance = this.balance - price
          // this.balance -= price
          if (this.balance >= price) {
            this.balance -= price;
          } else {
            alert('余额不足');
          }
        }
      }
    })
  </script>
</body>

</html>

4.5 v-bind

<body>
  <div id="app">
    <!-- 
      v-bind:src   =>  可简写为 :src
      作用:动态的设置html的标签属性
    -->
    <img v-bind:alt="msg">
    <img :src="url">
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        msg: '图片',
        url: 'imgs/10-01.png'
      }
    })
  </script>
</body>

案例图片切换 - 波仔学习之旅

<body>
  <div id="app">
    <!-- <button @click="reduce">上一页</button> -->
    <button @click="index--" v-show="index>0">上一页</button>
    <div>
      <!-- <img src="imgs/11-00.gif" alt=""> -->
      <img alt="#" :src="imgs[index]">
    </div>
    <!-- <button @click="add">下一页</button> -->
    <button @click="index++" v-show="index<imgs.length-1">下一页</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        imgs: [
          'imgs/11-00.gif',
          'imgs/11-01.gif',
          'imgs/11-02.gif',
          'imgs/11-03.gif',
          'imgs/11-04.png',
          'imgs/11-05.png'
        ],
        index: 0,
      },
      /* methods: {
        add() {
          this.index++
        },
        reduce() {
          this.index--
        }
      } */
    })
  </script>
</body>

4.6 v-for

<!-- 
  v-for
  1. 作用:基于数据循环,多次渲染整个元素 → 数组(重要)、对象、数字...
  2. 遍历数组语法:
    v-for = "(item, index) in 数组" 
    ➢ item 每一项, index 下标
    ➢ 省略 index: v-for = "item in 数组"
-->

<body>
  <div id="app">
    <!-- <h3>小黑水果店</h3> -->
    <!-- 数组 -->
    <ul>
      <li v-for="(item,index) in list">
        {{item}} -- {{index}}
      </li>
      <li v-for="(item) in list">
        {{item}}
      </li>
    </ul>

    <!-- 字符串 -->
    <ul>
      <li v-for="(item) in str">
        {{item}}
      </li>
    </ul>

    <!-- 对象 -->
    <p v-for="(value,key,index) in obj">
      {{value}} -- {{key}} -- {{index}}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        list: ['Tom', 'Jerry', 'Rose'],
        str: 'Hi',
        obj: {
          name: 'Taylor',
          age: 19,
        }
      }
    })
  </script>
</body>

案例图书管理 - 小黑的书架

<!-- 图书管理案例 - 小黑的书架 -->

<body>
  <div id="app">
    <h3 style="margin-left: 30px;">小黑的书架</h3>
    <ul>
      <!-- <li>
        <span>《红楼梦》</span>
        <span>曹雪芹</span>
        <button>删除</button>
      </li> -->
      <li v-for="(item) in booksList">
        <span>{{item.name}}</span>
        <span>{{item.author}}</span>
        <button @click="del(item.id)">删除</button>
      </li>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        booksList: [
          { id: 1, name: '《红楼梦》', author: '曹雪芹' },
          { id: 2, name: '《西游记》', author: '吴承恩' },
          { id: 3, name: '《水浒传》', author: '施耐庵' },
          { id: 4, name: '《三国演义》', author: '罗贯中' }
        ]
      },
      methods: {
        del(id) {
          // console.log(id)
          // 用 filter 根据 id 从数组中删除对应项
          this.booksList = this.booksList.filter((item) => {
            return item.id !== id
          })
        }
      }
    })
  </script>
</body>

v-for 中的 key

<!-- 
  v-for 中的 key
  语法:key属性 = "唯一标识"
  作用:给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用。
  注意点:
    1. key 的值只能是 字符串 或 数字类型
    2. key 的值必须具有 唯一性
    3. 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)

  不加 key
    v-for 的默认行为会尝试 原地修改元素 (就地复用)
-->

<body>
  <div id="app">
    <h3 style="margin-left: 30px;">小黑的书架</h3>
    <ul>
      <!-- <li v-for="(item) in booksList"> -->
      <li v-for="(item) in booksList" :key="item.id">
        <span>{{item.name}}</span>
        <span>{{item.author}}</span>
        <button @click="del(item.id)">删除</button>
      </li>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        booksList: [
          { id: 1, name: '《红楼梦》', author: '曹雪芹' },
          { id: 2, name: '《西游记》', author: '吴承恩' },
          { id: 3, name: '《水浒传》', author: '施耐庵' },
          { id: 4, name: '《三国演义》', author: '罗贯中' }
        ]
      },
      methods: {
        del(id) {
          this.booksList = this.booksList.filter((item) => {
            return item.id !== id
          })
        }
      }
    })
  </script>
</body>

4.7 v-model

<body>
  <div id="app">
    <!-- 
      v-model 可以让数据和视图,形成双向数据绑定
      (1) 数据变化,视图自动更新
      (2) 视图变化,数据自动更新
      可以快速[获取]或[设置]表单元素的内容

      语法: v-model = '变量'
     -->
    账户:<input type="text" v-model="userName"> <br><br>
    密码:<input type="password" v-model="passWord"> <br><br>
    <button @click="login">登录</button>
    <button @click="reset">重置</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        userName: '',
        passWord: ''
      },
      methods: {
        login() {
          console.log(this.userName, this.passWord)
        },
        reset() {
          this.userName = ''
          this.passWord = ''
        }
      }
    })
  </script>
</body>

5. 综合案例 - 小黑记事本

<!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" />
  <link rel="stylesheet" href="./css/index.css" />
  <title>记事本</title>
</head>

<body>
  <!-- 主体区域 -->
  <section id="app">
    <!-- 输入框 -->
    <header class="header">
      <h1>小黑记事本</h1>
      <input placeholder="请输入任务" class="new-todo" v-model="todo" />
      <button class="add" @click="add">添加任务</button>
    </header>
    <!-- 列表区域 -->
    <section class="main">
      <ul class="todo-list">
        <!-- 1. 列表渲染 -->
        <li class="todo" v-for="(item,index) in list" :key="item.id">
          <div class="view">
            <span class="index">{{index+1}}.</span> <label>{{item.txt}}</label>
            <button class="destroy" @click="del(item.id)"></button>
          </div>
        </li>
      </ul>
    </section>
    <!-- 统计和清空 -->
    <footer class="footer">
      <!-- 统计 -->
      <!-- <span class="todo-count">合 计:<strong> 1 </strong></span> -->
      <span class="todo-count">合 计:<strong> {{list.length}} </strong></span>
      <!-- 清空 -->
      <button class="clear-completed" @click="reset" v-show="list.length>0">
        清空任务
      </button>
    </footer>
  </section>

  <!-- 底部 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        todo: '',
        list: [
          { id: 1, txt: '敲代码' },
          { id: 2, txt: '删代码' },
          { id: 3, txt: '改代码' }
        ]
      },
      methods: {
        // 2. 添加功能
        add() {
          /* if (this.todo.trim().length > 0) {
            this.list.unshift({
              id: +new Date(),
              txt: this.todo
            })
            // console.log(this.list[0].id)
            this.todo = ''
          } */
          if (this.todo.trim() === '') {
            alert('请输入任务内容')
            return
          }
          this.list.unshift({
            id: +new Date(),
            txt: this.todo
          })
          this.todo = ''
        },
        // 3. 删除功能
        del(id) {
          this.list = this.list.filter(item => item.id !== id)
        },
        // 4. 清空
        reset() {
          this.list = []
        }
      }
    })
  </script>
</body>
<!-- 
  功能总结:
  1. 列表渲染: v-for key 的设置 {{ }} 插值表达式
  2. 删除功能: v-on 调用传参 filter 过滤 覆盖修改原数组
  3. 添加功能: v-model 绑定 unshift 修改原数组添加
  4. 底部统计 和 清空
      数组.length累计长度
      覆盖数组清空列表
      v-show 控制隐藏
-->

</html>

6. 作业

6.1 哔哩哔哩首页

<!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>bilibili-干杯~~~</title>
  <!-- 引入favicon图标 -->
  <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
  <!-- 引入css文件 -->
  <link rel="stylesheet" href="./css/index.css">
  <!-- 引入字体图标文件 -->
  <link rel="stylesheet" href="./fonts/iconfont.css">
</head>

<body>
  <div id="app">
    <!-- 头部模块 -->
    <header class="suspension">
      <div class="m-navbar">
        <!-- logo -->
        <a href="#" class="logo">
          <i class="iconfont Navbar_logo"></i>
        </a>
        <!-- 右侧 -->
        <div class="right">
          <a href="#" class="search">
            <i class="iconfont ic_search_tab"></i>
          </a>
          <a href="#" class="face">
            <img src="./images/login.png" alt="">
          </a>
          <div class="app-btn">
            <img src="./images/download.png" alt="">
          </div>
        </div>
      </div>
      <div class="channel-menu">
        <div class="tabs">
          <!-- 很宽的盒子 -->
          <div class="tabs-list">
            <a href="#">首页</a>
            <a href="#">动画</a>
            <a href="#">番剧</a>
            <a href="#">果蔬</a>
            <a href="#">音乐</a>
            <a href="#">舞蹈</a>
            <a href="#">鬼畜</a>
            <a href="#">吹鬼</a>
            <!-- 红色线 -->
            <div class="line"></div>
          </div>
        </div>
        <!-- 下拉箭头 -->
        <div class="after">
          <i class="iconfont general_pulldown_s" @click="isShow"></i>
        </div>
      </div>
    </header>
    <!-- 频道下拉模块 -->
    <div class="tabs-dropdown" v-show="flag">
      <div class="tabs-wrap">
        <span v-for="(item) in channelList">{{item}}</span>
        <!-- <span>动画</span>
        <span>番剧</span>
        <span>国创</span>
        <span>音乐</span>
        <span>舞蹈</span>
        <span>游戏</span>
        <span>科技</span>
        <span>运动</span>
        <span>汽车</span>
        <span>生活</span>
        <span>美食</span>
        <span>动物圈</span> -->
        <!-- ''''''' -->
      </div>
      <div class="close-wrap">
        <span @click="isShow">收起︿</span>
      </div>
    </div>
    <!-- 主体部分 -->
    <div class="m-home">
      <div class="video-list">
        <!-- 视频卡片模板 -->
        <a href="#" class="video-item" v-for="(item,index) in videoList" :key="index">
          <div class="card">
            <img :src=item.img>
            <!-- 播放量 -->
            <div class="count">
              <span>
                <i class="iconfont icon_shipin_bofangshu"></i>
                {{item.views}}
                <!-- item.views -->
              </span>
              <span>
                <i class="iconfont icon_shipin_danmushu"></i>
                {{item.commonet}}
              </span>
            </div>
          </div>
          <p class="title ellipsis-2">
            <!-- 黑马程序员前端React入门到实战视频教程,从react18+hooks核心基础到企业级项目开发实战(B站评论、极客园项目等)及大厂面试全通关 -->
            {{item.title}}
          </p>
        </a>
      </div>
    </div>
    <!-- 底部模块 -->
    <footer class="app">
      <div class="btn-app">
        <i class="iconfont Navbar_logo"></i>
        打开App,看你感兴趣的视频
      </div>
    </footer>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
  <!-- <script src="./js/index.js"></script> -->
  <script>
    // TODO:阅读代码,根据提供的数据,实现目标效果
    // DATA字段说明
    /**
     *  channelList 频道列表
     *  videoList 视频列表
     *  title 视频标题
     *  views 播放量
     *  commonet 评论量
     *  img 封面图片
     */

    /* 
      具体需求如下:
        频道列表展开收起:点击下拉箭头,显示频道列表,点击收起,隐藏频道列表
        频道渲染:根据提供数据,循环渲染出每个频道
        播放列表渲染:根据提供数据,循环渲染出每个视频的信息
    */
    const app = new Vue({
      el: "#app",
      data: {
        channelList: [
          "首页",
          "动画",
          "番剧",
          "国创",
          "音乐",
          "舞蹈",
          "游戏",
          "科技",
          "运动",
          "汽车",
          "生活",
          "美食",
          "知识",
          "动物圈",
          "鬼畜",
          "时尚娱乐影视",
          "纪录片",
          "电影",
          "电视剧",
          "直播",
          "相簿",
          "课堂",
        ],
        videoList: [
          {
            title:
              "黑马程序员前端React入门到实战视频教程,从react18+hooks核心基础到企业级项目开发实战(B站评论、极客园项目等)及大厂面试全通关",
            views: "110.6W",
            commonet: "2.3万",
            img: "https://i0.hdslb.com/bfs/archive/4ba435e67fa208ce7a5343c0fc2cd454d8cc50fc.jpg@480w_270h_1c",
          },
          {
            title:
              "黑马程序员前端JavaScript入门到精通全套视频教程,javascript核心进阶ES6语法、API、js高级等基础知识和实战教程",
            views: "238.4W",
            commonet: "8.9万",
            img: "https://i1.hdslb.com/bfs/archive/7cbcf700e3950f40dab97b5e57c8581733fdad22.jpg@480w_270h_1c",
          },
          {
            title:
              "Java八股文面试题视频教程,Java面试八股文宝典(含阿里、腾迅大厂java面试真题,java数据结构,java并发,jvm等最新java面试真题)",
            views: "87.5W",
            commonet: "1.4万",
            img: "https://i1.hdslb.com/bfs/archive/3c0dbdf9863a9e21d8ea5c50892b01db1268a268.jpg@480w_270h_1c",
          },
          {
            title:
              "黑马程序员2023新版JavaWeb开发教程,实现javaweb企业开发全流程(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)",
            views: "231.6W",
            commonet: "8.2万",
            img: "https://i1.hdslb.com/bfs/archive/81c2b09fea6a978a169eeb3fde028066751e06e5.jpg@480w_270h_1c",
          },
          {
            title:
              "黑马程序员Node.js全套入门教程,nodejs新教程含es6模块化+npm+express+webpack+promise等_Nodejs实战案例详解",
            views: "209.6W",
            commonet: "5.5万",
            img: "https://i2.hdslb.com/bfs/archive/a35e28d321c55c783526b2382431409935ddfb9f.jpg@480w_270h_1c",
          },
          {
            title:
              "2023新版数据结构与算法Java视频教程(上篇),java高级程序员必学的数据结构与算法",
            views: "54.6W",
            commonet: "1万",
            img: "https://i1.hdslb.com/bfs/archive/8dae32b310561144385867468a39b3f7cab1ba24.jpg@480w_270h_1c",
          },
          {
            title: "黑马程序员人工智能教程_10小时学会图像处理OpenCV入门教程",
            views: "71W",
            commonet: "1.8万",
            img: "https://i0.hdslb.com/bfs/archive/c6f5409bb52de12370b0cd73d98d0f1dd2019f9e.jpg@480w_270h_1c",
          },
          {
            title:
              "黑马程序员全套Python教程_Python基础入门视频教程,零基础小白自学Python入门教程",
            views: "157W",
            commonet: "4.8万",
            img: "https://i0.hdslb.com/bfs/archive/213b14bfbdbf54248a3f5fa742cb9f9c8f684274.png@480w_270h_1c",
          },
        ],
        flag: true,
      },
      methods: {
        isShow() {
          this.flag = !this.flag;
        },
      },
    });
  </script>
</body>

</html>

6.2 Boss 直聘技能选择 - 二次开发

<!DOCTYPE html>
<html>

<head>
    <title>Boss直聘技能选择</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/index.css">
</head>

<body>
    <div id="app">
        <h2>
            <span class="logo-head"></span>
        </h2>
        <div class="skill-tip">
            <h3>拥有技能</h3>
            <p>请选择技能标签,被选中的标签将突出展示给BOSS</p>
        </div>
        <div class="skill-wrap">
            <div class="title">自定义标签</div>
            <div class="add-wrap">
                <input type="text" class="tip" placeholder="请输入关键词" v-model="newSkill" />
                <button class="add-btn" @click="add">添加</button>
            </div>
        </div>
        <ul class="skill-wrap select">
            <div class="title">已选</div>
            <!-- <li>html5 <span>x</span></li> -->
            <li v-for="(item,index) in sT()" :key="index" @click="item.select = !item.select">{{item.skillName}}
                <span>x</span>
            </li>
        </ul>
        <ul class="skill-wrap">
            <div class="title">可选</div>
            <!-- <li>css3</li> -->
            <li v-for="(item,index) in sF()" :key="index" @click="item.select = !item.select">{{item.skillName}}</li>
        </ul>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
    <!-- <script src="./js/index.js"></script> -->
    <script>
        // TODO:阅读代码,根据提供的数据,实现目标效果
        // DATA字段说明
        /**
         *  skillList 技能列表
         *  skillName 技能名称
         *  select 已选择
        */

        /* 
        具体需求如下:
            渲染数据:将提供的数据绑定到页面对应的位置
            已选标签:数据中select字段为true的数据对应显示已选列表中,点击标签时更改为可选
            可选标签:数据中select字段为false的数据对应显示可选列表中,点击标签时更改为已选
            添加自定义标签:
            输入框内容为空时,点击添加,不处理
            当输入框内容不为空时,点击添加,在已选列表中新增标签
            新增标签后,清空输入框内容
            新增的自定义标签可以点击切换可选和已选的状态
        */
        const app = new Vue({
            el: '#app',
            data: {
                skillList: [
                    {
                        skillName: "html5",
                        select: true,
                    },
                    {
                        skillName: "css3",
                        select: true,
                    },
                    {
                        skillName: "javascript",
                        select: true,
                    },
                    {
                        skillName: "webapi",
                        select: true,
                    },
                    {
                        skillName: "ajax",
                        select: true,
                    },
                    {
                        skillName: "git",
                        select: true,
                    },
                    {
                        skillName: "echarts",
                        select: true,
                    },
                    {
                        skillName: "node",
                        select: true,
                    },
                    {
                        skillName: "vue",
                        select: true,
                    },
                    {
                        skillName: "微信小程序",
                        select: false,
                    },
                    {
                        skillName: "uni-app",
                        select: false,
                    },
                    {
                        skillName: "react",
                        select: false,
                    },
                ],
                newSkill: "",
            },
            methods: {
                sT() {
                    // return this.skillList.filter((item) => item.select === true);
                    return this.skillList.filter((item) => item.select);
                },
                sF() {
                    // return this.skillList.filter((item) => item.select === false);
                    return this.skillList.filter((item) => !item.select);
                },
                add() {
                    if (this.newSkill.trim() === "") {
                        alert("请输入有效标签");
                        return;
                    }
                    this.skillList.push({
                        skillName: this.newSkill,
                        select: true,
                    });
                    this.newSkill = "";
                },
            },
        });
    </script>
</body>

</html>

6.3 12306 订单详情 - 变形题

<!DOCTYPE html>
<html>

<head>
    <title>12306订单详情</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/index.css">
</head>

<body>
    <div id="app" :style="showStyle">
        <h1>订单详情</h1>
        <div class="container">
            <!-- 车次信息 -->
            <div class="ticket-info">
                <div class="start">
                    <div class="time">{{orderInfo.startTime}}</div>
                    <div class="origin">{{orderInfo.origin}}<span>&gt;</span></div>
                </div>
                <div class="train-info">
                    <div class="train-number">{{orderInfo.trainNumber}}<span>&gt;</span></div>
                    <div class="station-type">{{orderInfo.stationType === 1?'始发站':'经停站'}}</div>
                    <div class="train-duration">历时{{orderInfo.duration}}</div>
                </div>
                <div class="end">
                    <div class="time">{{orderInfo.endTime}}</div>
                    <div class="destination">{{orderInfo.destination}}<span>&gt;</span></div>
                </div>
            </div>
            <!-- 发车时间 -->
            <div class="train-date">
                <span class="start-date">发车时间:{{orderInfo.trainDate}}</span>
                <span class="expiration-date">车票当日当次有效</span>
            </div>
            <!-- 改签退票 -->
            <div class="btn-wrap">
                <button :disabled="!orderInfo.rebook" @click="showMsg('改签成功')">改签</button>
                <span>|</span>
                <button :disabled="!orderInfo.cancellation" @click="showMsg('退票成功')">退票</button>
            </div>
            <!-- 乘车人列表 -->
            <div class="passenger-list">
                <!-- <div class="passenger-info">
                    <h3 class="passenger">
                        <div class="passenger-name">
                            张三 <span class="passenger-type">成人票</span>
                        </div>
                        <div class="seat-info"><span class="seat-type">过道</span>二等座 04车 11B号</div>
                    </h3>
                    <div class="seat-price">
                        <div class="passenger-passport">
                            中国居民身份证
                        </div>
                        <div class="price">¥263</div>
                    </div>
                    <div class="status">
                        <div class="ticket-status">
                            已出站
                        </div>
                        <div class="illustrate">退改说明</div>
                    </div>
                </div> -->
                <div class="passenger-info" v-for="(passenger) in orderInfo.passengers" :key="passenger.pid">
                    <h3 class="passenger">
                        <div class="passenger-name">
                            {{passenger.pname}} <span class="passenger-type">{{passenger.isAdult ? '成人票':'儿童票'}}</span>
                        </div>
                        <div class="seat-info">
                            <!-- <span class="seat-type">{{seatType(passenger.seatType)}}</span> -->
                            <span class="seat-type" v-if="passenger.seatType!==2">
                                {{passenger.seatType===1?'靠窗':'过道'}}</span>
                            {{passenger.seat}}
                        </div>
                    </h3>
                    <div class="seat-price">
                        <div class="passenger-passport">中国居民身份证</div>
                        <div class="price">¥{{passenger.price}}</div>
                    </div>
                    <div class="status">
                        <div class="ticket-status">已出站</div>
                        <div class="illustrate">退改说明</div>
                    </div>
                </div>
            </div>
        </div>
        <div class="tip">
            🔔 订单信息查询有效期限为30日
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
    <!-- <script src="./js/index.js"></script> -->
    <script>
        // TODO:阅读代码,根据提供的订单信息数据,通过学习的Vue指令将页面渲染成目标效果
        // DATA:数据字段说明
        /**
         *  startTime: 发车时间
         *  endTime: 到站时间
         *  origin: 发车站
         *  destination:目的地
         *  trainNumber:车次
         *  trainDate:发车日期
         *  stationType:车站类型(1为始发站,2为经停站)
         *  duration:历时
         *  rebook:能否改签
         *  cancellation:能否退票
         *  passengers:乘车人列表
         *  pid:乘车人ID
         *  pname:乘车人姓名
         *  isAdult:是否成年
         *  seat:座位
         *  price:票价
         *  seatType:作为类型(1是靠窗,2是中间,3是过道)
        */
        const app = new Vue({
            el: "#app",
            data: {
                // 防止渲染闪烁
                showStyle: "display:block;",
                orderInfo: {
                    startTime: "14:11",
                    endTime: "17:40",
                    origin: "西安北",
                    destination: "成都东",
                    trainNumber: "D1937",
                    trainDate: "2023.09.30 星期六",
                    stationType: 2,
                    duration: "3时29分",
                    // rebook:能否改签 能改签t 按钮不禁用f
                    rebook: false,
                    cancellation: true,
                    passengers: [
                        {
                            pid: "0001",
                            pname: "王大锤",
                            isAdult: true,
                            seat: "二等座 04车 11A号",
                            price: 263,
                            seatType: 1,
                        },
                        {
                            pid: "0002",
                            pname: "李二狗",
                            isAdult: false,
                            seat: "二等座 04车 11B号",
                            price: 263,
                            seatType: 2,
                        },
                        {
                            pid: "0003",
                            pname: "张三疯",
                            isAdult: true,
                            seat: "二等座 04车 11C号",
                            price: 263,
                            seatType: 3,
                        },
                    ],
                },
            },
            methods: {
                /* seatType(num) {
                    switch (num) {
                        case 1:
                            return "靠窗";
                        // case 2:
                        //   return "中间";
                        case 3:
                            return "过道";
                    }
                }, */
                /* reOrCan(msg) {
                    // console.log(11);
                    if (msg === "改签") {
                        alert(`${msg}成功`);
                    } else if (msg === "退票") {
                        alert(`${msg}成功`);
                    }
                }, */
                showMsg(msg) {
                    alert(msg)
                }
            },
        });
    </script>
</body>

</html>


网站公告

今日签到

点亮在社区的每一天
去签到