Vue3 学习笔记 —— 自动导入 Vue3 APIs、v-model

news2024/11/20 14:38:02

目录

1. 自动导入 Vue3 APIs —— unplugin-auto-import/vite

2. v-model

2.1 相较于 Vue2,Vue3 做出了哪些变化?

2.2 绑定一个 v-model

2.2.1 父组件

2.2.2 子组件

2.3 绑定多个 v-model

2.3.1 父组件

2.3.2 子组件

2.4 v-model 中的自定义修饰符 modelModifiers

2.4.1 父组件

2.4.2 子组件 

2.5 v-model 源码分析 / emit 源码分析

2.5.1 v-model 源码分析

2.5.2 emit 源码分析


1. 自动导入 Vue3 APIs —— unplugin-auto-import/vite

GitHub - antfu/unplugin-auto-import: Auto import APIs on-demand for Vite, Webpack and RollupAuto import APIs on-demand for Vite, Webpack and Rollup - GitHub - antfu/unplugin-auto-import: Auto import APIs on-demand for Vite, Webpack and Rolluphttps://github.com/antfu/unplugin-auto-import

 

Vue3 中的 APIs 无需导入,可直接使用

使用示例:

// 使用前
import { computed, ref } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)

// 使用后
const count = ref(0)
const doubled = computed(() => count.value * 2)

 

安装命令:

npm i -D unplugin-auto-import

vite 配置: 


import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 注意:不能缺少 /vite
import AutoImport from 'unplugin-auto-import/vite'

// https://vitejs.dev/config/

export default defineConfig({
  plugins: [vue(), AutoImport({
    imports:['vue'],
    dts:"src/auto-import.d.ts"
  })]
})

2. v-model

v-model 是一个语法糖,通过 props + emit 组合而成

2.1 相较于 Vue2,Vue3 做出了哪些变化?

props:value -> modelValue;

emits:input -> update:modelValue;

v-bind 的 .sync 修饰符和组件的 model 选项已移除

新增 支持多个v-model

新增 支持自定义 修饰符 Modifiers

2.2 绑定一个 v-model

2.2.1 父组件

在父组件中引入子组件,并给子组件添加 v-model 的绑定值 show

注意:此处的 v-model 只有一个,所以后面不用跟具体的名字,比如 v-model:title

<template>
  <button @click="show = !show">是否展示 -- {{ show }}</button>
  <Dialog v-model="show"></Dialog>
</template>
 
<script setup lang='ts'>
  import Dialog from "./components/Dialog/index.vue";
  import { ref } from 'vue'

  const show = ref(false)
</script>

 

2.2.2 子组件

在子组件中定义 v-model 需要的 props:

如果没有定义名字(比如 v-model:title 表示有名字),则使用默认写法 —— modelValue

在子组件中定义 v-model 需要的 emits:

如果没有定义名字(比如 v-model:title 表示有名字),则使用默认写法 —— update:modelValue

<template>
     <div v-if='propData.modelValue'>
         <div class="dialog-header">
           <div @click="closeDialog">关闭按钮</div>
         </div>
         <div class="dialog-content">
            内容
         </div>
     </div>
</template>
 
<script setup lang='ts'>
  type Props = {
     modelValue:boolean
  }
 
  const propData = defineProps<Props>()
 
  const emit = defineEmits(['update:modelValue'])

  // 关闭事件
  const closeDialog = () => {
     // 双向绑定更新值
     emit('update:modelValue', false)
  }
</script>

 

 

2.3 绑定多个 v-model

2.3.1 父组件

在父组件中引入子组件,并给子组件添加 v-model 的绑定值 show

注意:此处的 v-model 有多个:

  • 后面可以跟具体的名字,比如 v-model:title;
  • 后面也可以不跟名字,使用默认值(只能有一个默认的 v-model)
<template>
  <button @click="show = !show">是否展示 -- {{ show }} -- {{ title }}</button>
  <Dialog v-model="show" v-model:title="dialogTitle"></Dialog>
</template>
 
<script setup lang='ts'>
  import Dialog from "./components/Dialog/index.vue";
  import { ref } from 'vue'

  const show = ref(false)
  const dialogTitle = ref('弹框名字')
</script>

2.3.2 子组件

在子组件中定义 v-model 需要的 props:

  • 如果没有定义名字,则使用默认写法 —— modelValue
  • 如果有名字(比如 v-model:title),则这么写 —— title

在子组件中定义 v-model 需要的 emits:

  • 如果没有定义名字,则使用默认写法 —— emit('update:modelValue', false)
  • 如果有名字(比如 v-model:title),则这么写 —— emit('update:title','双向绑定改变 title')
<template>
     <div v-if='propData.modelValue'>
         <div class="dialog-header">
           <div @click="closeDialog">关闭按钮</div>
         </div>
         <div class="dialog-content">
            内容
         </div>
     </div>
</template>
 
<script setup lang='ts'>
  type Props = {
     modelValue: boolean,
     title: string,
  }
 
  const propData = defineProps<Props>()
 
  const emit = defineEmits(['update:modelValue', 'update:title'])

  // 关闭事件
  const closeDialog = () => {
     // 双向绑定更新值
     emit('update:modelValue', false)
     emit('update:title','双向绑定改变 title')
  }
</script>

2.4 v-model 中的自定义修饰符 modelModifiers

添加到 v-model 后边的修饰符,将通过 props 中的  modelModifiers  提供给组件

举个栗子~

  • 在父组件中,定义了 v-model:title.islang,islang 就是自定义修饰符
  • 在子组件的 props 中,通过 titleModifiers 属性接收并判断 —— 用户是否使用了自定义修饰符 islang,该 props 返回布尔值 

2.4.1 父组件

在父组件中,给 v-model 添加修饰符 .islang —— v-model:title.islang

<template>
  <button @click="show = !show">是否展示 -- {{ show }} -- {{ title }}</button>
  <Dialog v-model="show" v-model:title.islang="dialogTitle"></Dialog>
</template>
 
<script setup lang='ts'>
  import Dialog from "./components/Dialog/index.vue";
  import { ref } from 'vue'

  const show = ref(false)
  const dialogTitle = ref('弹框名字')
</script>

 

 

2.4.2 子组件 

在子组件中,使用 titleModifiers 接收 v-model 修饰符,并在更新 title 值时,使用 自定义修饰符,判断应该返回什么值

<script setup lang='ts'>
 
type Props = {
    modelValue: boolean,
    // 默认
    modelModifiers?: {
        default: () => {}
    }

    title?: string,
    // 自定义 名字+Modifiers 即可
    titleModifiers?: {
        default: () => {}
    }
 
}
 
const propData = defineProps<Props>()
 
const emit = defineEmits(['update:modelValue', 'update:title'])
 
const closeDialog = () => {
    // 如果使用 v-model 时,传入了 islang,则返回 true,否则返回 false
    console.log(propData.titleModifiers); // true
 
    emit('update:modelValue', false)
    emit('update:title', propData.titleModifiers ? '有修饰符' : '没修饰符')
}

2.5 v-model 源码分析 / emit 源码分析

2.5.1 v-model 源码分析

源码位置:packages\runtime-dom\src\directives\vModel.ts

从源码位置可以看出,v-model 其实是个指令

首先,进行初始化赋值,v-model 绑定的值,赋值给 value,目前是单向的

  // set value on mounted so it's after min/max for type="range"
  mounted(el, { value }) {
    // 初始化赋值,v-model 绑定的值,赋值给 value,目前是单向的
    el.value = value == null ? '' : value
  },

created 中接收了三个参数:

  • el dom 对象
  • 绑定(bing)对象
  • VNode
created(el, { modifiers: { lazy, trim, number } }, vnode) {
  el._assign = getModelAssigner(vnode)
  const castToNumber =
    number || (vnode.props && vnode.props.type === 'number')
    // 如果有 lazy 属性,则只有当数据改变并且失去焦点时,才会触发事件,相当于 change
    // 如果没有 lazy 属性,则相当于 input
  addEventListener(el, lazy ? 'change' : 'input', e => {
    if ((e.target as any).composing) return
    let domValue: string | number = el.value
    // 如果有 trim,则手动调用 trim() 去掉空格
    if (trim) {
      domValue = domValue.trim()
    }
    // 如果有数字,则转成数字
    if (castToNumber) {
      domValue = toNumber(domValue)
    }
    el._assign(domValue)
  })
  if (trim) {
    addEventListener(el, 'change', () => {
      el.value = el.value.trim()
    })
  }
  if (!lazy) {
    // 针对中文输入法进行特殊处理,当用户选择了输入法中的文字后,才会手动触发 input
    addEventListener(el, 'compositionstart', onCompositionStart)
    addEventListener(el, 'compositionend', onCompositionEnd)
    // Safari < 10.2 & UIWebView doesn't fire compositionend when
    // switching focus before confirming composition choice
    // this also fixes the issue where some browsers e.g. iOS Chrome
    // fires "change" instead of "input" on autocomplete.
    addEventListener(el, 'change', onCompositionEnd)
  }
},

2.5.2 emit 源码分析

源码位置:packages\runtime-core\src\componentEmits.ts

因为 双向绑定 不止通过 v-model,还要涉及到 emit

首先,读取当前实例的 props 对象

  // 读取当前实例的 props 对象
  const props = instance.vnode.props || EMPTY_OBJ

读取完 props 对象后,获取下 emits 中类似 update:title 的事件

  // 读取完 props 对象后,获取下 emits
  const isModelListener = event.startsWith('update:')

  // for v-model update:xxx events, apply modifiers on args
  // 去掉 update: 这段字符,获取后面的 modelValue
  const modelArg = isModelListener && event.slice(7)
  if (modelArg && modelArg in props) {
    const modifiersKey = `${
      modelArg === 'modelValue' ? 'model' : modelArg
    }Modifiers`
    // 获取 number、trim 
    const { number, trim } = props[modifiersKey] || EMPTY_OBJ
    if (trim) {
      args = rawArgs.map(a => a.trim())
    }
    if (number) {
      args = rawArgs.map(toNumber)
    }
  }

监听事件,并执行回调函数

  // handlerName + on + 事件名称
  let handlerName
  let handler =
    props[(handlerName = toHandlerKey(event))] ||
    // also try camelCase event handler (#2249)
    props[(handlerName = toHandlerKey(camelize(event)))]
  // for v-model update:xxx events, also trigger kebab-case equivalent
  // for props passed via kebab-case
  if (!handler && isModelListener) {
    handler = props[(handlerName = toHandlerKey(hyphenate(event)))]
  }

  if (handler) {
    callWithAsyncErrorHandling(
      handler,
      instance,
      ErrorCodes.COMPONENT_EVENT_HANDLER,
      args
    )
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Material Design之ShapeableImageView(十三)

效果图 资源引入 implementation com.google.android.material:material:1.4.0属性 属性描述android:id控件idandroid:layout_width控件长度android:layout_height控件高度app:shapeAppearance控件外观样式app:strokeWidth画笔粗度app:strokeColor画笔颜色android:src图像资源…

MySQL逻辑架构

逻辑架构剖析 服务器处理客户端请求 数据库查询请求流程&#xff1a; 连接层 系统&#xff08;客户端&#xff09;访问 MySQL 服务器前&#xff0c;做的第一件事就是建立 TCP 连接。 经过三次握手建立连接成功后&#xff0c; MySQL 服务器对 TCP 传输过来的账号密码做身份认…

了解Wi-fi频段概念

前言 信道带宽&#xff0c;应该了解wi-fi频段&#xff0c;这样才能分析有多少信道带宽可用&#xff0c;以及如何在没有任何干扰&#xff08;失真&#xff09;的情况下有效地使用它。 2.4GHz和5GHz频段可用于wi-fi。 2.4 GHz Wi-Fi频段&#xff1a;在2.4 GHz频段&#xff0c;…

通过Shell脚本自动安装HiveJDBC测试提供CDH5网盘地址

〇、参考地址 1、Linux下编写脚本自动安装hive https://blog.csdn.net/weixin_44911081/article/details/121227024?ops_request_misc%257B%2522request%255Fid%2522%253A%2522163695916016780269859534%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%252…

Linux——网络配置(重点)

目录 一、查看网络IP和网关 1.1 那怎么看连接成功呢&#xff1f; 1.1.1 虚拟机接受主机 1.1.2 主机可以接收到虚拟机 1.2 怎么查看电脑的IP地址 方法一&#xff1a; 方法二&#xff1a; 1.3 怎么查看虚拟机的IP地址 二、网络连接模式 2.1 基本了解 2.2 VMware三种网络…

夯实算法-每日温度

题目&#xff1a;LeetCode 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。…

【关系抽取】基于Bert的信息抽取模型CasRel

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

冒名顶替综合症:悄悄地杀死你的梦想

如今&#xff0c;越来越多的开发人员自学成才&#xff0c;很容易消极地与那些拥有计算机科学学士学位或硕士学位的同事进行比较&#xff0c;但请不要这样做。 你们中的很多都很出色&#xff0c;只是你们不清楚这一点。看到那些认为自己不够优秀&#xff0c;但实际上很了不起的人…

MySQL语句

目录 一、常用查询 二、高级SQL语句 1、按关键字排序 单字段排序 按分数降序排列 结合条件过滤 多字段排序 查询学生信息先按兴趣id升序排列&#xff0c;相同分数的&#xff0c;id按升序排列 区间判断及查询不重复记录 嵌套/多条件 对hobbyid进行分组查询&#xff0c…

RabbitMQ学习笔记之Work Queues

工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务&#xff0c;而不得不等待它完成。 相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进 程将弹出任务并最终执行作业。当有多个工作线程时&#xff0c;这些工作线程将一起…

Nacos2.0.3集群搭建

集群搭建 前置条件 JDK 1.8MySQL 5.7.29Nacos 2.0.3 搭建过程 将Nacos安装包上传至三个服务器&#xff0c;本次搭建使用三个端口来模拟三个不同的主机解压&#xff1a; tar -zvxf nacos-server-2.0.3.tar.gzNacos持久化&#xff0c;首先确保服务器已经安装MySQL(Nacos持久化要…

爆肝!阿里最新版的Spring Security源码手册,强行霸占GitHub榜首

写在前面 Spring Security 的前身是 Acegi Security&#xff0c;在被收纳为Spring 子项目后正式更名为Spring Security。在笔者成书时&#xff0c;Spring Security已经升级到5.1.3.RELEASE版本&#xff0c;加入了原生OAuth2.0框架&#xff0c;支持更加现代化的密码加密方式。 …

你入职的时候一定要问领导要的maven私服配置文件,它是什么?Nexus入门使用指南

上一篇教大家如何在Linux搭建Nexus Linux安装Nexus&#xff08;图文解说详细版&#xff09; 文章目录&#x1f64b;登录Nexus&#x1f470;在maven中配置自己的私服地址&#x1f647;在idea中使用nexus作为maven私服&#x1f491; 引用nexus里面的jar包&#x1f487;配置maven文…

【NLP】自然语言处理的语料库与词库

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

双十二有哪些实用性强的数码好物?值得入手的实用数码好物推荐

赶在年末的双十二快来了&#xff0c;大家有没有心仪的数码好物正在购物车里蠢蠢欲动呢&#xff1f;入手数码产品最重要的还是要看其实用性强不强&#xff0c;下面&#xff0c;我整理了一份值得入手的实用数码好物清单&#xff0c;希望能给大家有个参考。 一、蓝牙耳机 蓝牙耳…

10、Springboot整合Security很全

1.什么是Security SpringSecurity是基于Spring AOP和Servlet过滤器的安全框架。 它提供全面的安全性解决方案&#xff0c;同时在Web 请求级和方法调用级处理身份确认和授权。 2.Spring Security核心功能&#xff1f; &#xff08;1&#xff09;认证&#xff08;你是谁&…

Java集合容器面试题(2023最新版)

集合容器概述 什么是集合 集合框架&#xff1a;用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。 任何集合框架都包含三大块内容&#xff1a;对外的接口、接口的实现和对集合运算的算法。 接口&#xff1a;表示集合的抽象数据类型。接口…

王洪伟:流体力学与微积分方法求解水池进排水问题

作者 | 王洪伟 北京航空航天大学副教授&#xff0c;仿真秀专栏作者 导 读&#xff1a;经过了几篇略显烧脑的文章后&#xff0c;来一篇轻松一点的&#xff0c;经典的小学数学应用题。 1、问题分析 题&#xff1a;一个水池有一个进水管和一个排水管。只开进水管&#xff0c;2个…

Linux常用命令总结

目录和文件命令 &#xff08;1&#xff09;用户目录&#xff1a;位于/home/user&#xff0c;称之为用户工作目录&#xff1b; &#xff08;2&#xff09;ls&#xff1a;是英文单词list的简写&#xff0c;其功能为列出目录的内容&#xff1b; ls -a 列出隐藏文件&#xff0c;文…

CAS号:67131-52-6, 三肽Ala-Ala-Tyr

H-Ala-Ala-Tyr-OH 用于合成突变型多肽。H-Ala-Ala-Tyr-OH can be synthesized mutant peptides[1][2]. 编号: 193893中文名称: 三肽Ala-Ala-TyrCAS号: 67131-52-6单字母: H2N-AAY-OH三字母: H2N-Ala-Ala-Tyr-COOH氨基酸个数: 3分子式: C15H21N3O5平均分子量: 323.34精确分子量:…