Vue3全家桶 - Vue3 - 【3】模板语法(指令+修饰符 + v-model语法糖)

news/2024/6/19 3:11:04 标签: vue.js, javascript, 前端, 笔记, 前端框架

一、模板语法

  • 主要还是记录一些指令的使用和vue2的区别;
  • vue3指令导航;

1.1 v-text 和 v-html

  • 指令的区别:
    • v-text:
      • 更新元素的文本内容;
      • v-text 通过设置元素的 textContent 属性来工作,因此它将覆盖元素中所有现有的内容。如果你需要更新 textContent 的部分,应该使用 mustache interpolations 代替。
      • 不能解析标签;
    • v-html:
      • 更新元素的innerHTML
      • v-html 的内容直接作为普通 HTML 插入—— Vue 模板语法是不会被解析的。如果你发现自己正打算用 v-html 来编写模板,不如重新想想怎么使用组件来代替。
      • 可以解析标签;
      • 在单文件组件,scoped 样式将不会作用于 v-html 里的内容,因为 HTML 内容不会被 Vue 的模板编译器解析。如果你想让 v-html 的内容也支持 scoped CSS,你可以使用 CSS modules 或使用一个额外的全局 <style> 元素,手动设置类似 BEM 的作用域策略。
  • vue2:这两个指令的使用的时候,没什么需要注意的地方,即使标签里面有内容,也可以正常使用和在浏览器中正常显示内容;
  • vue3:绑定指令的元素必须是空标签,如果该标签里面有内容或其他标签,都会报错;
    • 相比vue2,vue3源码在这两个指令绑定的时候去做了进一步的处理;
      image.png

1.2 v-model

  • 注意
    • 一般情况下,v-model指令用在表单元素中;
    • 文本类型的 input、textarea 会绑定元素的 value 属性并侦听 input 事件;
    • 单选和复选 radio、checkbox 会绑定元素的 checked 属性,并侦听 change 事件;
    • 下拉菜单 select 会绑定元素的 value 属性,并侦听 change 事件;
      • 指令绑定在 select元素 上,给 子元素option 设置 value属性;
  • 示例展示:
    <script setup>javascript">
        import { ref, reactive, toRef, toRefs, onMounted } from 'vue';
        let text = ref('111')
        let textarea = ref('222')
        let radio = ref('man')
        let open = ref(true)
        let determine = ref('确定')
        let checkbox = ref(['YMQ'])
        let select = ref('B')
        let selects = ref(['苏C', '苏B'])
    
        onMounted(() => {});
    </script>
    
    <template>
        <h4>单行文本框</h4>
        <input type="text" v-model="text">
        <hr>
    
        <h4>多行文本框</h4>
        <input type="textarea" v-model="textarea">
        <hr>
    
        <h4>单选框</h4>
        <input type="radio" value="man" v-model="radio"><input type="radio" value="woman" v-model="radio"><hr>
    
        <h4>默认复选框</h4>
        <input type="checkbox" name="" id="" v-model="open"><h4>自定义复选框的值</h4>
        <!-- 默认状态下,复选框的值是 true / false ,既 open 的值为 true / false-->
        <input type="checkbox" true-value="确定" false-value="不确定" v-model="determine"> 是否确定
        <!-- 
            true-value - 表示选中状态下,既 determine 的值
            false-value - 表示未选中状态下,表示选中状态下,既 determine 的值
        -->
        <hr>
    
        <h4>复选框</h4>
        <input type="checkbox" value="LQ" v-model="checkbox"> 篮球
        <input type="checkbox" value="ZQ" v-model="checkbox"> 足球
        <input type="checkbox" value="YMQ" v-model="checkbox"> 羽毛球
        <input type="checkbox" value="PPQ" v-model="checkbox"> 乒乓球
        <hr>
    
        <h4>单选下拉菜单</h4>
        证书等级:
        <select v-model="select">
            <option value="C">初级</option>
            <option value="B">中级</option>
            <option value="A">高级</option>
        </select>
        <hr>
    
        <h4>多选下拉菜单</h4>
        去过的城市:
        <select multiple v-model="selects">
        <!--
            NOTE
            multiple - 规定可同时选择多个选项
            值 - 布尔值(写该属性表示true,不写表示false)
        -->
            <option value="苏A">南京</option>
            <option value="苏B">无锡</option>
            <option value="苏C">徐州</option>
            <option value="苏D">常州</option>
        </select>
    </template>
    

1.3 v-if 和 v-for 的 优先级

  • vue2:
    • v-for > v-if
  • vue3:
    • v-if > v-for

1.4 v-for 循环 数组 和 对象

  • 这块和 vue2 没啥区别,主要是我自己在 vue2 里面主要是配合数组使用(很少循环对象);
  • 使用 v-for 的时候,记得添加 key
  • 循环数组
    • 写法一:
      • v-for = "item in arr"
      • item:数组的每一项元素;
      • arr:需要循环的数组;
    • 写法二:
      • v-for = "(item, index) in arr"
      • item:数组的每一项元素;
      • index:每一项元素对应的索引;
      • arr:需要循环的数组;
  • 循环对象
    • 使用 v-for 来遍历一个对象的所有属性,遍历的顺序 会基于该对象调用 Object.keys()返回值 来决定;
    • 写法一:
      • v-for = "value in object"
      • value:属性值;
      • object:需要循环的对象;
    • 写法二:
      • v-for = "(value, name) in object"
      • value:属性值;
      • name:属性名;
      • object:需要循环的对象;
    • 写法三:
      • v-for = "(value, name, index) in object"
      • value:属性值;
      • name:属性名;
      • index:索引(Object.keys()的返回值中 name 对应的索引);
      • object:需要循环的对象;
    • 示例展示:
      <script setup>javascript">
          import { reactive } from 'vue'
          let student = reactive({
              styNum: '007', // 学号
              name: 'Jack', // 名字
              age: 18 //年龄
          })
      </script>
      
      <template>
          <h6>Object.keys() 的 返回值</h6>
          <span>{{ Object.keys(student) }}</span>
      
          <!-- 
              value in object
              value:属性值
              object:循环的对象
          -->
          <h6>v-for 渲染对象, v-for="value in object"</h6>
          <ul>
              <li v-for="value in student" :key="value">
                  {{ value }}
              </li>
          </ul>
      
          <hr>
      
          <!-- 
              (value, name) in object
              value:属性值
              name:属性名
              object:循环的对象
          -->
          <h6>v-for 渲染对象, v-for="(value, name) in object"</h6>
          <ul>
              <li v-for="(value, name) in student" :key="name">
                  属性名:{{ name }} --- 属性值: {{ value }}
              </li>
          </ul>
      
          <hr>
      
          <!-- 
              (value, name, index) in object
              value:属性值
              name:属性名
              index: 索引
              object:循环的对象
          -->
          <h6>v-for 渲染对象, v-for="(value, name, index) in object"</h6>
          <ul>
              <li v-for="(value, name, index) in student" :key="name">
                  属性名:{{ name }} --- 属性值: {{ value }} --- 索引:{{ index }}
              </li>
          </ul>
      </template>
      
    • 效果展示:
      image.png
  • 通过 key 提高更新性能:
    • 当列表的数据变化时,默认情况下,vue会尽可能的复用已存在的DOM元素,从而提升渲染的性能;但这种默认的性能优化策略,会导致有状态的列表无法被正确更新;
    • 为了给vue一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲染的性能;此时,需要为每项提供一个唯一的key属性:
    • key的注意事项:
      • key的类型 只能Number/String
      • key值必须具有 唯一性
      • 建议循环的列表有一个属性当 key(该属性的值在此列表中唯一);
      • 不使用 索引 当 key
      • 🔺 使用 v-for 指令时一定要指定 key 的值;
    • 示例展示:
      <script setup>javascript">
          import { ref } from 'vue'
          // 课程
          let subject = ref([
              { id: 1, name: 'Vue' },
              { id: 2, name: 'Java' },
              { id: 3, name: 'Hadoop' }
          ])
          // 添加课程
          function addSubject() {
              // (数组最前面)添加
              subject.value.unshift({ id: 4, name: 'Python' })
          }
      </script>
      
      <template>
          <button @click.once="addSubject">添加课程(数组最前面)</button>
      
          <h3>不使用key值</h3>
          <ul>
              <li v-for="sub in subject">
                  <input type="checkbox">
                  {{ sub }}
              </li>
          </ul>
          <hr>
      
          <h3>使用索引当key值</h3>
          <ul>
              <li v-for="(sub, index) in subject" :key="index">
                  <input type="checkbox">
                  {{ sub }}
              </li>
          </ul>
          <hr>
      
          <h3>使用列表属性当key值(该属性必须再此列表中唯一)</h3>
          <ul>
              <li v-for="sub in subject" :key="sub.id">
                  <input type="checkbox">
                  {{ sub }}
              </li>
          </ul>
      </template>
      
    • 效果展示:
      • 观察 不使用key + 使用索引作为key 的变化(会导致有状态的列表无法被正确的更新);
        image.png

1.5 键盘按键修饰符

  • 这块和 vue2 没啥区别,主要是我自己在 vue2 里面就知道那么几个修饰符,所以在这里记录了一下;
  • 按键别名:.enter.tab.esc.space.up.down.left.right.delete (捕获DeleteBackspace两个按键);
  • 系统修饰符:.ctrl.alt.shift.meta
  • 准确的修饰符:.exact(添加了对应键位的修饰符,就必须按下对应的键位,否则事件不生效)(见【示例展示】);
  • 示例展示:
    <script setup>javascript">
        // 弹出消息
        function showMessage(message) {
            window.alert(message)
        }
    </script>
    
    <template>
        按下的键中包含 Enter 键事件: <input type="text" @keydown.enter="showMessage('你按下了 Enter 键')">
        <hr>
        按下的键中包含 Shift Enter 键事件:<input type="text" @keydown.enter.shift="showMessage('你按下了 Shift + Enter 键')"/>
        <hr>
        按下的键只有 Shift Enter 键事件:<input type="text" @keydown.enter.shift.exact="showMessage('你只有按下了 Shift + Enter 键,这个事件才会触发')"/>
    </template>
    

1.6 鼠标按键修饰符

  • 这块和 vue2 没啥区别,主要是我自己在 vue2 里面基本没遇到过,所以在这里记录了一下;
  • 鼠标按键修饰符:
    • .left:鼠标左键;
    • .middle:鼠标中键(滚轮键);
    • .right:鼠标右键;
  • 示例展示:
    <!-- 脚本区域 -->
    <script setup>javascript">
        function showTest(text) {
            window.alert(text)
        }
    </script>
    
    <!-- 视图区域 -->
    <template>
        <!-- 鼠标右键按下 -->
        <button @mousedown.right="showTest('按下的是鼠标右键')">鼠标右键按下</button>
    
        <hr>
        <!-- 点击时,采用的是鼠标中键 -->
        <button @click.middle="showTest('按下的是鼠标中键')">点击时,采用的是鼠标中键</button>
    
        <hr>
        <!-- 鼠标左键按下 -->
        <button @mousedown.left="showTest('按下的是鼠标左键')">鼠标左键按下</button>
    </template>
    
    <!-- 样式区域 -->
    <style>
        button {
            border: none;
            padding: 15px 20px;
        }
    
        button:active {
            box-shadow: 0 0 5px grey;
        }
    </style>
    

二、vue2 和 vue3 v-model语法糖 区别

  • vue3官网(组件 v-model);
  • vue2v-mode 语法糖 简写的代码:
    • texttextarea<Son :value="msg" @input="msg=$event.target.value" />
    • radiocheckbox<Son :checked="msg" @change="msg=$event.target.checked" />
  • vue3v-model 语法糖 有所调整:
    • <Son :modelValue="msg" @update:modelValue="msg=$event" />
  • 示例展示:
    • 父组件:
      <script setup>javascript">
          import { ref } from 'vue'
      
          // NOTE 在使用 setup 语法糖的 单文件 里面导入组件的时候,无需注册,直接使用即可
          // TODO 导入组件
          import SonComponent from '@/components/SonComponent.vue'
      
          let searchText = ref('禁止摆烂-才浅')
      </script>
      
      <template>
          <!-- <son-component :modelValue="searchText" @update:modelValue="newVal => searchText = newVal"></son-component> -->
          <son-component v-model="searchText"></son-component>
      </template>
      
    • 子组件:
      <script setup>javascript">
          // NOTE 接受父组件传递的数据 - 接收数据有两种形式(数组 + 对象)
          defineProps({
              modelValue: {
                  type: String,
                  required:  true
              }
          })
      </script>
      
      <template>
          <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
      </template>
      
  • 总结
    • vue3封装组件支持 v-model 的时候:
      • 父传子 :modelValue 传递数据;
      • 子传父 @update:modelValue 触发事件,更新数据;
    • vue2的 xxx.sync 语法糖解析:
      • 父传子:xxx
      • 子传父 @update:xxx 在vue3.0 使用 v-model:xxx 代替。

http://www.niftyadmin.cn/n/5423774.html

相关文章

【嵌入式】嵌入式系统稳定性建设:最后的防线

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟。提供嵌入式方向的学习指导、简历面…

qt如何将QHash中的数据有序地放入到QList中

在qt中&#xff0c;要将QHash中的数据有序地放入到QList中&#xff0c;首先要明白&#xff1a; 我们可以遍历QHash中的键值对&#xff0c;并将其按照键的顺序或值的大小插入到QList中&#xff0c;直接用for循环即可。 #include <QCoreApplication> #include <QHas…

深入理解Nginx日志级别

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;广泛用于提供网站和应用服务。它的强大功能之一是灵活的日志记录能力&#xff0c;允许管理员根据需要配置不同的日志级别。正确理解和使用这些日志级别对于监控、调试和保障你的服务稳定运行至关重要。本文旨在深入介绍…

【Datawhale学习笔记】从大模型到AgentScope

从大模型到AgentScope AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff0c;内置…

20240309web前端_第一周作业_完成用户注册界面

作业一&#xff1a;完成用户注册界面 成果展示&#xff1a; 完整代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-…

AIGC——DreamTuner通过单张图片生成与该图片主题风格一致的新图像

简介 DreamTuner的能力在于从单个图像生成主体驱动的新通用方法&#xff0c;这意味着用户只需提供一张图片&#xff0c;DreamTuner就能帮助他们生成与原始图片在主题和风格上一致的新图像。 算法重要之处在于其通用性和个性化定制的能力。无论是需要根据特定主题或条件创建个…

DDR3 NATIVE接口

参考&#xff1a; DDR3 控制器 MIG IP 详解完整版 &#xff08;native&Vivado&Verilog&#xff09;_mig ip核-CSDN博客 APP和AXI接口有许多相似的地方&#xff08;握手部分&#xff09;&#xff0c; 但是由于和物理芯片直接相关&#xff0c;有更多不一样的地方。 a…

【PTA】L1-021 L1-022 L1-023 L1-024 L1-025(C)第四天

目录 L1-021 重要的话说三遍 题解&#xff1a; L1-022 奇偶分家 题解&#xff1a; L1-023 输出GPLT 题解&#xff1a; L1-024 后天 题解&#xff1a; L1-025 正整数AB 题解&#xff1a; L1-021 重要的话说三遍 分数 5 作者 陈越 单位 浙江大学 这道超级简单的题目没…