一口气速通Vue3.0

一口气速通Vue3.0💨

🧑‍💻🧑‍💻 终于学完了Vue2.0=>、神清气爽,吃嘛嘛香,一口气能上18层楼🏙️

都说前端技术更新迭代快,这不现在都Vue3.0了,且Vue2.0已经停止更新/维护了,经典:白学🥲

No、No、No: 虽然现实如此,但影响我觉得不大,Vue3.0 是2.0 进行的一个升级🆙,完全兼容Vue2.0的语法;

且就算你要学习Vue3,也离不开学习它的语法,很多的思想、概念:都是2.0=过渡=>3.0, 虽然有些语法变动挺大的;

🧻🧻卷卷卷、🌊🌊与其纠结内耗的时间,就已经掌握了,🤨不信,这篇Blog带你速通Vue3.0🚀🚀🚀

Vue3.0 核心升级🆙

响应式机制: Vue3使用Proxy来实现响应式,而Vue2使用的是getter/setter

组合式API: 引入了setup()函数和Composition API,允许开发者以函数式的方式组织组件逻辑,提高代码复用性;

生命周期钩子的变化: 移除了beforeCreatecreated等,引入了setup阶段,以及新的生命周期钩子;

更好的TypeScript支持: 在设计时就考虑到了TypeScript的集成,提供了更好的类型定义和推断;

移除和新增特性: 移除了filter等较少使用功能,增加了:SuspenseTeleport等新特性;

生态系统更新: 虽然生态仍在发展中,但主要的UI库和工具链已经或正在更新以支持Vue3

组合式API

组合式API是Vue3引入的一种新的编程模式,它彻底改变了Vue组件的编写方式:

与Vue2中的选项式API相比,组合式API不再依赖于传统的data、methods等选项对象结构,

而:组合式API: 通过一系列函数式的API来构建组件的逻辑,更灵活、高效的方法来组织和复用代码逻辑;

在这里插入图片描述
使用Vue2选项式开发过程中,随着业务复杂,经常出现一个函数和变量,相差几十行代码的情况,非常不利于开发;

组合式API通过将逻辑相关部分组合在一起,解决了选项式API在复杂组件中逻辑分散的问题;

对于大型项目和需要高度复用逻辑的场景,组合式API提供了更优的解决方案;

提供了更细粒度的响应性控制,使得组件更新更加精确;

创建Vue3项目:

创建Vue3项目可以通过多种方式完成,主要两种方法:ViteVue-cli

Vue CLI 基于成熟的 Webpack 构建,它是一个全面的脚手架系统,提供了丰富的插件和配置选项,适合复杂和大型项目;

Vite 则是基于 ES6 模块的即时加载机制,利用浏览器原生的模块导入功能,通过HTTP服务器直接提供未经打包的源代码;

Vite 在开发时通过esbuild快速预编译依赖,并在运行时按需编译和加载模块,这大大加快了启动速度📈

  • 启动速度: Vite 因为避免了完整的打包过程,在开发环境中启动速度远快于 Vue CLI,以及快速迭代的开发阶段;

    但生产环境构建时,两者依赖的工具Vite使用Rollup、Vue CLI默认Webpack各有侧重,具体速度取决于项目结构配置;

  • 热模块替换 (HMR): Vite 提供了更快的HMR体验,因为它直接在浏览器中编译和替换模块,而不需要重新构建整个应用;

总结:适用场景=>

Vue CLI: 更适合大型项目,需要高度定制化的构建流程,以及对成熟生态依赖较高的情况;

Vite: 适合快速原型开发、小型项目或对启动速度有高要求的项目,尤其是Vue 3项目,是Vue 3官方推荐开发工具;

create-vue 脚手架:

🆗,既然是官方推荐:那么就免为其难的浅浅尝试一下吧: 感受一下Vite速度🚤

首先,确保Node.js版本: Node.js版本在14.18+,推荐使用16+版本,以兼容ViteVue3的要求;

创建项目: 打开终端,使用命令、输入项目名称、选择框架依赖,确认选择Vue、使用TypeScriptJavaScript

npm create vite@latest	#或
yarn create vite		#或
pnpm create vite

在这里插入图片描述

如此简单,就快速的构建了一个Vue3的项目!! 相比VueCli确实快了不少!!

Vue3项目目录:

VsCode配置:禁用Vu2插件—Vetur、安装Vue3插进volar:、核心配置文件:

在这里插入图片描述

  • vite.config.js: 项目的配置文件,基于vite 的配置;
  • package.json: 项目包文件,核心依赖项变成了Vue3vite
  • main.js - 入口文件: createApp创建Vue实例、初始化Vue应用,配置全局插件,引入根组件;
import './style.css'
import App from './App.vue'
import { createApp } from 'vue'

createApp(App).mount('#app');
//原始new Vue()创建一个应用实例 =升级=> createApp() 将创建实例进行了封装,保证每个实例的独立封闭性
  • app.vue - 根组件: SFC单文件组件:script - templa - style,为方便操作JSCSS、将templa放中间;

    变化一: 脚本script和模板template顺序调整、script添加setup标识支持组合式API

    变化二: 模板template不再要求唯一根元素;

组合式API-setup函数

组合式API是Vue 3引入的核心特性之一: 它通过setup选项提供一种新的组件内部结构,以更模块化的方式组织代码;

setup() 函数\使用:

setup是Vue 3组件中的一个新选项,它在组件实例被创建之前执行=> 生命周期: setup执行早于任何生命周期钩子,

这意味着不能在setup中直接访问如beforeCreatecreated传统生命周期钩子中的数据;

上下文隔离: setup内部,this是不可用的,因为:它不绑定到组件实例,

这促使开发者使用响应式API,如:refreactive,来管理状态;

在这里插入图片描述

<script>
  export default {
    setup(){
      console.log(this);
      console.log('setup 执行中...'); 
    },
    beforeCreate(){ console.log('beforeCreate 执行中...'); }
  }
</script>
<template></template>
<style scoped></style>

setup 中返回值与模板进行绑定: setup中变量不能直接在模板中使用;

属性暴露: setup函数可以返回一个对象,该对象中的属性和方法将被添加到组件实例上;

响应式数据: 通常在setup中使用refreactive来创建响应式数据,这些数据的变化会触发视图更新;

<script>
  export default {
    setup(){
      console.log(this);
      console.log('setup 执行中...');
      //属性暴露:setup 中返回值与模板进行绑定,
      const message = 'this is message'
      const logMessage = ()=>{ console.log(message) }
      return { message, logMessage }    //setup return返回的对象,可以在模板中使用数据、方法等;
    },
    beforeCreate(){ console.log('beforeCreate 执行中...'); }
  }
</script>
<!-- setup与模板的交互: 可以直接获取setup return的函数\属性 -->
<template>
  {{message}}
  <button @click="logMessage" >点击log</button>
</template>
<style scoped></style>

在这里插入图片描述

<script setup> 语法糖🍬

<script setup>语法糖 是Vue 3中引入的一项重要特性:

它极简了单文件组件(SFC)中组合式API的使用,提高了代码的可读性和简洁性;有多极简?

<!-- <script setup>它极简了单文件组件(SFC)中组合式API的使用 -->
<script setup>
  const message = 'this is message'
  const logMessage = ()=>{ console.log(message) }
</script>
<template>
  {{message}}
  <button @click="logMessage" >点击log</button>
</template>

在这里插入图片描述

这这这,简直少了一大半代码,编译时优化: <script setup>在编译阶段处理,减少了运行时的模板编译负担;

直接声明使用: <script setup>内,直接声明变量、方法和导入模块,无需通过return语句暴露给模板;

组合式API入口: setup函数,在生命周期的早期执行,允许访问和处理props,但内部不应使用this关键字;

不支持name属性直接设置: 若需为组件命名,需在外部<script>标签中设置export default对象的name属性;

组合式API-reactive\ref函数:

setup中返回的对象: <script setup > 只是普通对象、属性,并不是响应式的:数据修改,模板自动更新;

通常都需要通过: reactive、ref(推荐) 函数进行响应式处理;

reactive函数:

对象与数组的响应式: reactive用于创建复杂数据结构如:对象、数组)的响应式版本、基本语法:

reactive({对象}); 接受一个对象类型数据,参数传入并返回一个响应式的对象;

<!-- <script setup>中定义的数据,并不是响应式对象 -->
<script setup>
  // const obj = { count : 1 }
  // 在setup中可以通过: reactive\ref函数创建响应式数据\返回;
  import { reactive } from 'vue';
  const obj = reactive({
    count : 1,
  });
  const countAdd = ()=>{ obj.count++ }
</script>
<template>
  {{obj.count}}
  <button @click="countAdd" >+</button>
</template>

在这里插入图片描述

注意:reactive 是浅层响应性: reactive只对最外层对象的属性变更做出响应,如果修改了对象内部的嵌套对象或数组;

需要确保这些嵌套结构也是通过refreactive创建的响应式;

ref函数:

因为:reactive仅支持对象,所以通常使用最多的是ref

ref支持基本数据、对象类型如:NumberStringBoolean的响应式包装,

但,它返回一个Ref对象,该对象有一个.value属性,需要使用.value访问ref包装的值;

Vue 3.2版本后,部分情况可以不加.value深层响应性: ref用于对象或数组时,其内部值的深层属性也是响应式的;

<!-- <script setup>中定义的数据,并不是响应式对象 -->
<script setup>
  // const obj = { count : 1 }
  // 在setup中可以通过: reactive\ref函数创建响应式数据\返回;
  // ref注意事项: 
  // 1. 脚本中访问数据,需要通过 .value
  // 2. 在template中,.value不需要加 (帮我们扒了一层)
  import { reactive, ref } from 'vue';
  const count = ref(0);
  const countAdd = ()=>{ count.value++ }  //需要使用.value访问ref包装的值
</script>
<template>
  {{count}}
  <button @click="countAdd" >+</button>
</template>

注意: ref创建的响应式性是针对其内部值,而不是引用本身,即使原.value发生变化,也不会触发Vue响应式更新;

ref的底层原理: ref函数内部的实现依赖于reactive函数;

在这里插入图片描述

组合式API - computed函数

组合式API—computed函数特性: 允许你创建基于其他数据的计算属性,相当于Vue2的,computed计算属性

和:传统使用类似,仅修改了写法: 导入computed函数在computed函数中return基于响应式数据做计算的值,用变量接收

<script setup>
  // 导入依赖函数,声明响应式数据;
  import { computed, ref } from 'vue'
  const list = ref([1, 2, 3, 4, 5, 6, 7, 8,2,31,4,51,1,-1,-1])
  // 基于list派生计算属性:从list中过滤出 > 2
  const computedList = computed(() => {
    return list.value.filter(item => item > 2)
  })
</script>
<template>
  <div>
    <div>原始数据: {{ list }}</div>
    <div>计算后的数据: {{ computedList }}</div>
  </div>
</template>
<style scoped></style>

在这里插入图片描述

注意事项: 确保计算属性的依赖是响应式的,即通过refreactive的响应式对象,否则Vue将无法追踪变化;

异步计算: Vue3的计算属性不直接支持异步操作,可以考虑使用watchEffect或在外部管理异步逻辑;

类型定义: 在TypeScript项目中,为计算属性提供正确的类型定义,以利用类型检查和自动补全;

返回值: 计算属性函数应该返回一个值,不返回值\返回undefined可能会导致模板渲染错误;

组合式API - watch函数

Vue3的组合式API中的watch函数: 提供了一种监听=>响应式数据变化并执行相应操作的强大机制;

和Vue2-watch属性类似: 不过了换了一种声明方式,语法如下: Vue3支持监听一个、多个,响应式变量;

//watch函数: 监听单个属性
	import { ref, watch } from 'vue';
	watch('ref对象',(oldValue,newValue) => { ... });	
	//函数接收两个参数: 监听对象、操作函数('历史数据','新数据')
                                           
//watch函数: 监听多个属性,和单属性监听类型,不同的是ref对象为一个数组[Array];
watch(['ref对象1','ref对象2'],(oldArray,newArray) => { ... });		//操作函数参数也是,修改前后数组;

在这里插入图片描述

watch函数,参数选项: 👁️‍🗨️watch监听函数除了,必须的:监听对象操作函数还有一个[可选]的,参数选项:

  • immediate: 设置为true时,监听器会在初始运行时立即触发一次;
  • deep: 如果需要深度监听对象或数组内的变化,可以设置为true,默认:false 仅监听基本值、对象地址改变)
watch('ref对象',(oldValue,newValue) => { ... },{
    immediate : true,
	deep : true,
});	

deep 深度监听—对象属性:

在这里插入图片描述

组合式API - 生命周期:

Vue3的组合式API引入了一套新的生命周期钩子:

这些钩子以函数的形式提供,使得开发者能够更清晰、更灵活地组织和管理组件的生命周期;

Vue2和Vue3的生命周期钩子在概念上相似,以下是Vue2与Vue3生命周期钩子的主要对比:

beforeCreate                 ->   setup()
Created                      ->   setup()
类似于Vue2的beforeCreate\created,但更早,且不直接等同,用于设置组件的响应式数据和副作用
beforeMount                  ->   onBeforeMount		在挂载开始之前被调用,此时还没有真实的DOM
mounted                      ->   onMounted			组件被挂载到DOM之后调用,可以访问和操作DOM
beforeUpdate                 ->   onBeforeUpdate	数据更新之前调用,但DOM尚未更新
updated                      ->   onUpdated			数据更新并完成DOM更新之后调用
beforeDestroyed              ->   onBeforeUnmount	组件销毁之前调用,此时组件仍然可用
destroyed                    ->   onUnmounted		组件销毁之后调用,所有指令和事件监听器已被移除
activated                    ->   onActivated		当一个被<keep-alive>包裹的组件被激活时调用
deactivated                  ->   onDeactivated		当<keep-alive>包裹的组件被切换出去,不再显示时调用

组合式API - 父子通信:

在Vue3中,组合式API为父子组件通信提供了更加灵活和现代的手段,以下是几种主要的父子通信方式:

注意事项: Vue3,使用:@ 作为 src/下目录,引用组件、依赖,需要配置:vue.config.js 路径别名;

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

父组件引用子组件:

Vue3中使用组件两种方式:全局注入、局部导入👇👇

  • 局部导入: 导入子组件的地址,定义组件名、直接在父组件 template中使用;

在这里插入图片描述

父传子 通信:

Vue3中,父组件向子组件传递数据主要通过Props进行,这一机制与Vue2相似: 但有一些细节上的更新和改进;

父组件传递数据: 在父组件的模板中,通过属性绑定v-bind、简写:属性名将数据传递给子组件;

<script setup>
    //Vue3中使用组件两种方式: 全局注入、局部导入
    //局部导入、导入子组件的地址、直接在template中使用;
    import { ref } from 'vue'
    import SonCom from '@/components/son-com.vue'
    //父组件定义响应式数据
    const count = ref(0);
    const message = ref("父组件发送消息")
    const getMessage = ()=>{ count.value++; }
</script>

<template>
    <div>
        <p>App父组件</p>
        <button @click="getMessage" >父组件发送消息按钮</button>
        <SonCom :message="message" :count="count"></SonCom>
        <!-- 父组件给子组件 :添加属性的方式传值 -->
    </div>
</template>
<style scoped></style>

子组件通过:defineProps来定义接收的属性: 可以是类型注解的形式,以提供更好的类型安全;

<!-- son子组件 -->
<script setup>
    // 注意:由于写了setup 所以无法直接配置 props 接收数据;
    // 所以:借助于 “编译器宏” 函数接收子组件传递的数据;
    const props = defineProps({
        count: Number,
        message: String 
    })
    console.log("子组件获取父组件参数: "+props.message);
</script>
<template>
    <div class="son" >
        <p>我是子组件,接收:{{ message+count }}</p>
        <!-- 对于props传递过来的数据,模板中可以直接使用 -->
    </div>
</template>
<style scoped>
	.son { border: 1px solid #000; padding: 30px; }
</style>

在这里插入图片描述

子传父 通信:

Vue3中子组件向父组件传递数据主要通过自定义事件emit来实现:

子组件 定义自定义事件: 在子组件的<script setup>标签内使用defineEmits函数来定义监听事件;

<!-- son子组件 -->
<script setup>
  // 注意:由于写了setup 所以无法直接配置 props 接收数据;
  // 所以:借助于 “编译器宏” 函数接收子组件传递的数据;
  const props = defineProps({
    count: Number,
    message: String 
  })
  console.log("子组件获取父组件参数: "+props.message+props.count);

  //子组件传递父组件数据: 通过 defineEmits 定义父组件监听事件;
  import { defineEmits,ref } from 'vue';
  const scount = ref(0);
  const emit = defineEmits(['sonMessage']);
  //子组件中定义函数, 触发函数,给父组件发送数据;
  const sendMsg = () =>{ 
    emit('sonMessage',"子组件发送消息"+(scount.value++))
  }
</script>
<template>
  <div class="son" >
    <p>我是子组件,接收:{{ message+count }}</p>
    <!-- 对于props传递过来的数据,模板中可以直接使用 -->
    <button @click="sendMsg" >子组件给父组件发送消息</button>
  </div>
</template>
<style scoped>
	.son { border: 1px solid #000; padding: 30px; }
</style>

父组件监听事件: 通过监听子组件触发的事件来接收数据,注意:事件名称与子组件中定义的一致;

<script setup>
  //Vue3中使用组件两种方式: 全局注入、局部导入
  //局部导入、导入子组件的地址、直接在template中使用;
  import { ref } from 'vue'
  import SonCom from '@/components/son-com.vue'

  //父组件定义响应式数据
  const count = ref(0);
  const message = ref("父组件发送消息")
  const getMessage = ()=>{ count.value++; }

  //父组件: 监听子组件触发的事件来接收数据,事件名称与子组件中定义的一致;
  const smessage = ref();
  function sonMessage(data) {
    smessage.value = data;
    console.log('从子组件收到的数据:', data);
  }
</script>

<template>
  <div>
    <p>App父组件: {{smessage}}</p>
    <button @click="getMessage" >父组件发送消息按钮</button>
    <!-- 父组件给子组件 :添加属性的方式传值、通过 @绑定监听子组件传递数据函数;-->
    <SonCom :message="message" :count="count" @sonMessage="sonMessage" ></SonCom>
  </div>
</template>
<style scoped></style>

在这里插入图片描述

模板引用 \ 宏函数

模板引用

组合式API—模板引用: 模板引用的概念与Vue 2有所不同,Vue2 ref、$ref使用

Vue 2中,我们通常使用ref、v-ref获取DOM元素引用: Vue 3中,这一过程被统一和简化;

Vue3 使用ref进行模板引用:ref不仅用于创建响应式数据,也可以用来获取DOM元素的引用

<script setup>
  // 模板引用:可以用于获取dom,也可以获取组件)
  import { onBeforeMount, onMounted, ref } from 'vue'
  
  const inp = ref(null);                              //1.首先通过 ref(null); 定义一个空属性;
  //3.如此即可在 JS中直接获取到对应的Dom,对其进行操作,如: 进行焦点获取,
  //同时注意:要保证Dom已成功渲染,否则返回undefined
  //生命周期钩子 onMounted
  onMounted(()=>{ console.log(inp.value) });          //Dom已渲染完成
  onBeforeMount(()=>{ console.log(inp.value) });      //Dom未渲染完成

  //定义函数,点击让输入框聚焦:
  const clickFn = ()=>{ inp.value.focus() };
</script>
<template>
  <div>
    <input ref="inp" type="text">&nbsp;         <!-- 2.在模板要获取的标签中定义同名的的 ref="属性值" -->
    <button @click="clickFn">点击让输入框聚焦</button>
  </div>
</template>

在这里插入图片描述

注意事项:

返回null的初始值: 在组件挂载之前,ref值.value会是null因为:Dom并未加载完成;

生命周期钩子: 通常在onMounted或适当的生命周期钩子中使用这些引用,确保DOM已经渲染完成;

模板引用+宏 操作组件

ref 模板引用: 强大之处,在于它可以获取Dom元素、组件元素、并操作,没错:可以获取操作组件;

默认情况下在,组件<script setup>语法糖下组件内部的属性和方法是,不开放给父组件访问的:

子组件定义: 需要通过:defineExpose编译宏指定哪些属性和方法容许访问;

<script setup>
  import { ref } from 'vue'
  //创建定义组件内部:属性、函数
  const sayHi = () => { console.log('打招呼')};
  const count = ref(999);
  //通过:defineExpose编译宏指定哪些属性和方法容许访问
  defineExpose({
    count,
    sayHi
  })
</script>
<template>
  <div> 我是用于测试的组件 - {{ count }} </div>
</template>

父组件: 使用ref来创建一个对子组件实例的引用,获取子组件defineExpose暴露的响应式数据或方法;

<script setup>
  // 模板引用:可以用于获取dom,也可以获取组件)
  import TestCom from '@/components/test-com.vue'
  import { ref,onMounted } from 'vue'
  
  const testRef = ref(null);                        //1.首先定义ref null对象属性;
  onMounted(()=>{ console.log(testRef.value) });    //3.Dom已渲染完成,操作获取组件;
  
  //4.定义函数操作组件:数据、函数
  const getCom = () => {
    testRef.value.sayHi();
    testRef.value.count += 1;
    console.log(testRef.value.count);
  }
</script>
<template>
  <div>
    <p>父组件: 模板引用获取操作子组件</p>
    <TestCom ref="testRef" ></TestCom>            <!-- 2.要获取的组件、Dom标签上绑定ref="对象属性名" -->
    <button @click="getCom">获取组件: 减少子组件数据;</button>
  </div>
</template>

在这里插入图片描述

组件跨层传递provide、inject

组合式API中的provideinject特性允许在Vue组件树中进行依赖注入:

这是一种跨组件通信的方式,尤其适用于:祖先组件 =向其=> 子孙组件传递数据的问题,无需通过中间组件逐层传递props

在这里插入图片描述

//在父组件的setup函数中,你可以使用provide来注入数据或对象;
import { provide } from 'vue';
provide('传递对象|属性|名', '对象|属性|值');

//子\后代组件: 使用inject接收父组件提供数据;
const 自定义变量名 = inject('对应的对象|属性|名');    //接收父组件匹配传递的值;
//根据各个组件管理自己数据原则,一般不允许跨组件修改数据,
//所以修改组件数据,一般直接暴漏一个: 修改函数 => 子孙后代提供函数修改数据的方法;

在这里插入图片描述

Vue3.3 新特性:

defineOptions

defineOptions 特性概述: defineOptions宏的引入是为了在Vue 3.3中提供一个更简洁和统一的方式来定义组件选项;

Vue3开始, 大家都在使用<script setup> 但,很多时候我们还需要使用:Vue2的一些特定的属性:组件名 …之类的;

如何解决? Vue3.3之前为了使用,只能定义一个新的<script> 专门用来写原始的配置;

<script>
  //vue2 定义配置属性
  export default{
    name : "组件名",
  }
</script>
<script setup>/* vue3 setup配置 */</script>

<template> <!-- 页面主体 --></template>
<style scoped>/* css */</style>

defineOptions允许开发者在保持<script setup>简洁性的同时,定义更复杂的组件选项;

<script setup>
import { defineOptions } from 'vue';

defineOptions({
  name: 'MyComponent',
  inheritAttrs: false,
});
</script>

defineModel

在Vue3中,自定义组件上使用v-model 相当于传递一个modelValue属性,同时触发 update:modelValue 事件

//父组件在子组件上定义v-model
<Child v-model="isVisible">
/* 相当于 :modelValue 属性、 匹配一个 @update:modelValue 事件对象 */ 
<Child :modelValue="值" @update:modelValue="更新同步值,函数">
    
//子组件: 定义与父组件通信
defineProps({ modelValue: String })
const emit = defineEmits(['update:modelValue'])

我们需要先定义 props,再定义 emits 其中有许多重复的代码,如果需要修改此值,还需要手动调用 emit 函数;

于是乎 defineModel 诞生了: 生效需要配置 vite.config.js 设置 defineModel: true

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue({
    script: {
      defineModel: true
    }
  })],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

子组件设置:defineModel, 给需要进行父子通信的表单元素设置,无需手动使用refreactive来创建响应式状态;

<script setup>
    //子组件导入 defineModel 并创建对象, 并在模板表单元素中使用
    import { defineModel } from 'vue'
    const modelValue = defineModel()
</script>

<template>
<div>
    <!-- :value="modelValue" 匹配defineModel -->
    <!-- @input 给表单绑定input 输入事件处理,父组件给子组件绑定v-model 自动匹配其数据、函数 -->
    <input 
        type="text" 
        :value="modelValue"
        @input="e => modelValue = e.target.value"
    >
</div>
</template>

父组件: 直接通过 v-model 绑定至,子组件匹配的defineModel() 函数返回对象上,通常用于表单;

<script setup>
  import MyInput from '@/components/my-input.vue'
  import { ref } from 'vue'
  const txt = ref('123456')
</script>

<template>
<div>
  <!-- 直接在子组件上使用 v-model='响应式数据' -->
  <MyInput v-model="txt"></MyInput>
  {{ txt }}
</div>
</template>

在这里插入图片描述

代码管理:

本代码已经使用Git进行管理: 公众号回复:Vue项目工程化
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慈様や

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值