v-model進階+ref+nextTick

一、v-model進階

復習 v-model

v-model: 雙向數據綁定指令

數據 <-> 視圖: 數據和視圖相互影響, 因此被稱為雙向數據綁定指令

1> 數據變了, 視圖也會跟著變 (數據驅動視圖)

2> 視圖變了, 數據也會跟著變

1. v-model 原理

v-model只是一個語法糖,? 比較好用, 可以減少代碼量, v-model 作用再原生的 input 上本質就是給input傳了value屬性(v-bind綁定value屬性,從而數據可以影響視圖),并且監聽了input事件,通過input事件拿到輸入框的值(實現視圖影響數據)

本質:? :value = "數據" + @input="數據?= 輸入框的值" (v-bind,v-on)

我們先使用v-bind/: 實現數據影響視圖

注意: input 里面的value值是輸入框里面的默認值

現在我們實現視圖影響數據, 把輸入框里面輸入值, 然后影響數據(msg里面會變),此時我們需要監聽輸入框, 給它加一個監聽事件(監聽視圖的變化, 然后數據也跟著變)

而這個輸入框的值,需要這么拿: input是一個原生事件, 原生事件在觸發的是有一個事件對象的,此時需要通過$event來獲取這個事件對象,$event.target拿到的就是這個input標簽本身,$event.target.value拿到的就是原生input的值

<script setup>
import { ref } from 'vue';
const msg = ref('')
</script><template><!-- v-model 實現雙向數據綁定 --><p>{{ msg }}</p><!-- <input type="text" v-model="msg" /> --><!-- 自己實現雙向數據綁定 --><!--v-bind + @input (v-on)  --><br><!-- 此時v-bind只能夠數據影響視圖 --><!-- 使用原生事件, 獲取到input里面的值然后通過賦值操作影響數據 --><input :value="msg"@input="msg=$event.target.value"></template><style scoped></style>

2. v-model用在組件上

v-model作用在組件標簽上:

<Xxx v-model="數據"/>,Xxx是一個組件/自定義標簽

上述代碼完全等同于

<Xxx :modelValue = "數據" @update:modelValue = "數據 = 新值"/>

注意: 在組件上使用v-model,其實就是要實現處理 modelValue屬性 和 update:modelValue 事件?

關于為什么在子組件不能使用v-model, v-bind是單向的,因此不影響

我們此處需要,每次選擇哪個城市, 就把它的value值傳給父組件里面的activeId

其中父組件的$event是emit傳過來的參數, 子組件的$event是事件對象,$event.target 是原生DOM標簽, $event.target.value 是標簽的值

App.vue

<script setup>
//導入組件
import MySelect from './component/MySelect.vue';
import { ref } from 'vue'
//收集當前選中的城市 id
const activeId = ref('333')
</script>
<template><!-- 使用組件 --><!-- <MySelect v-model="activeId" /> --><!-- 原理 --><!-- 父傳子接 --><!-- 組件標簽上的 $event 指的是 emit 傳遞來的參數 --><MySelect :modelValue="activeId" @update:modelValue="activeId=$event"/>
</template><style scoped></style>

MySelect.vue

<script setup>
const props = defineProps({//接收父傳子的 modelValue屬性modelValue: String
})
const emit = defineEmits()
</script>
<template><!-- 原生標簽上的 $event 就是事件對象 --><!-- $event.target: select 原生DOM --><!-- $event.target.value: 選中的 option 的 value--><select :value="props.modelValue" @change="emit('update:modelValue', $event.target.value)"><option value="111">長沙</option><option value="222">上海</option><option value="333">廣州</option><option value="444">蘇州</option></select>
</template><style scoped></style>

3. 使用 defineModel() 簡化上述代碼

v-model用在組件上, 子組件代碼可以簡化:

組件用 defineModel() 接收父傳子的 v-model 數據, defineModel() 返回一個 ref 響應式數據, 這個響應式數據的初始值就是 父傳遞給子的 v-model 數據的值, 并且該數據可讀可寫, 子組件可以直接修改這個響應式數據, 會同步到父組件的數據當中.

今后組件上用v-model指令的格式如下:

父: <Xxx v-model = "父的響應式數據"/>

子: const model = defineModel()? 子可以對model 做讀寫操作

注意: defineModel() 只是一個語法糖(比較好用), 本質還是一下倆部分:?

1> const props = defineProps({modelValue:String})

2> const emit defineEmits()? emit('update:modelValue'.新值)

具體代碼


二、ref

ref 屬性: 和之前學習的 ref 函數不一樣

1. ref 屬性是什么: 是作用在標簽上的屬性, 是vue新增的, 原生不具備的這個屬性

2. ref 屬性的作用: 用來獲取原生 DOM 或 組件實例(進而調用組件提供的方法)

3. 使用步驟

1> 準備一個 ref 數據, 并綁定在想獲取的標簽上, <Xxx ref = "ref 響應式數據"/>

2> 恰當時機,通過 ref.value 來獲取原生DOM 或組件實例

4. 以獲取原生DOM為例

具體代碼

<script setup>
import { onMounted, ref } from 'vue';
//準備 ref 響應式數據
const divRef = ref(null)
//組件掛載后
onMounted(() => {// ref 拿到原生 DOM div// console.log(divRef.value)// 設置字體顏色(DOM操作)divRef.value.style.color = 'blue'
})
</script>
<template><!-- 給目標元素添加 ref 屬性并綁定數據 --><div ref="divRef">xiaohei</div>
</template><style scoped></style>

5. 小案例: 繪制一個簡單的圖表

1> 準備MyChart組件, 在這個組件總來繪制圖表, 使用在App中

2> 在組件中, 準備一個盒子, 給盒子設置寬高

3> 在組件掛載后, 獲取這個div, 繪制圖表

4>繪制圖表

1. 首先我們要用到一個第三方庫: ECharts?

獲取 ECharts - 入門篇 - 使用手冊 - Apache ECharts

npm install echarts

2. 在MyChart組件中, 組件掛載后獲取盒子, 其他的代碼抄官方的即可

具體代碼

App.vue

<script setup>
import MyChart from './component/MyChart.vue';        
</script><template><MyChart />
</template><style scoped></style>

MyChart.vue

<script setup>
import * as echarts from 'echarts'
import { onMounted, ref } from 'vue';
const divRef = ref(null)
onMounted(() => {//基于準備好的dom, 初始化echars實例const myChart = echarts.init(divRef.value)//繪制圖表myChart.setOption({title: {text: 'ECharts 入門示例'},tooltip: {},xAxis: {data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']},yAxis: {},series: [{name: '銷量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]})
})
</script><template><div class="chart-box" ref="divRef"></div>
</template><style scoped>
.chart-box {width: 400px;height: 300px;margin: 100px auto;border: 3px solid #000;
}
</style>

6. 調用組件的方法

ref屬性: 獲取組件實例, 進而是為了調用組件給我們提供的方法

1> 準備MyForm表單組件, 主要需要提供一個檢驗的方法

2> 在App中使用MyForm組件, 添加登錄按鈕, 今后想知道點擊了登錄按鈕之后, 只校驗成功了還是失敗了, 進而可以做后續的工作

我們子組件可以使用 defineExpose 來把屬性和方法進行導出, 然后父組件就可以導入子組件然后進行使用

整體流程

相當于 ref屬性值鏈接的就是一個子組件的組件實例, 子組件的組件實例里面, 使用defineExpose方法新增了組件的屬性和方法, 我們就可以在父組件里面來進行使用了

具體代碼

MyForm.vue

<script setup>
//表單組件提供的校驗方法
const validate = () => {return Math.random() > 0.5 ? true : false
}
//需要對外暴露.類似于導出
defineExpose({ccc: 100,validate
})
</script><template><div class="form-box">賬號: <input type="text"><br /><br />密碼: <input type="password"><br /><br /></div>
</template><style scoped></style>

App.vue

<script setup>
import MyForm from './component/MyForm.vue';
import { onMounted, ref } from 'vue';
const formRef = ref(null)
onMounted(() => {console.log(formRef.value)//獲取 MyForm 組件實例//調用默認導出的方法console.log(formRef.value.validate())console.log(formRef.value.ccc)
})
//登錄
const onLogin = () => {//做表單校驗if (formRef.value.validate()) {console.log('ok')} else {console.log('不 ok')}
}
</script>
<template><div class="login-box"><!-- 組件上使用 ref,通過子組件使用defineExpose暴露屬性/方法從而進行使用 --><MyForm ref="formRef" /><button @click="onLogin">登錄</button></div>
</template><style scoped></style>

三、nextTick()

1. 什么是 nextTick(): 是 vue3 給我們提供的一個方法

2. nextTick()的作用: 當數據變了, 想獲取更新后的 DOM, 需要把代碼寫在這個方法的回調中

需求:

編輯標題, 編輯框自動聚焦

1> 點擊編輯, 顯示編輯框

2> 讓編輯框, 立刻獲取焦點

點擊編輯顯示編輯框和確認框

讓編輯框, 立刻獲取焦點, 此時出現一個問題

? ? 問題: 當數據變了, 發現獲取 DOM 拿不到

? ? 原因: vue3中, 當數據變了, DOM 的更新是異步的;

? ? 也就是數據變了, 想立即獲取最新的 DOM 是拿不到的, 此時DOM并沒有更新

解決方案: 利用 nextTick()這個方法,因為在nextTick()函數的回調中DOM會進行更新

3. 什么時候用這個方法(用的很少)

當數據變了, 想DOM操作, 如果直接拿不到, 就可以在nextTick回調中獲取.

具體代碼:
App.vue

<script setup>
import { ref, nextTick } from 'vue';
const inputRef = ref(null)
//控制是否顯示輸入框
const isShowEdit = ref(false)
//點擊編輯按鈕
const onEdit = () => {isShowEdit.value = true;// 問題: 當數據變了, 發現獲取 DOM 拿不到// 原因: vue3中, 當數據變了, DOM 的更新是異步的; // 數據變了, 想立即獲取最新的 DOM 是拿不到的, 此時DOM并沒有更新console.log(inputRef.value)//null//解決: 利用 nextTick()這個方法,因為在nextTick()函數的回調中DOM會進行更新nextTick(() => {console.log(inputRef.value)inputRef.value.focus()})
}
</script>
<template><div class="box"><h3>大標題</h3><button @click="onEdit">編輯</button></div><!-- 使用v-if,默認是不顯示 --><div v-if="isShowEdit"><input type="text" ref="inputRef"><button>確認</button></div>
</template>
<style scoped>
.box {display: flex;align-items: center;width: 200px;height: 40px;justify-content: space-between;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76117.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76117.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76117.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Sentinel源碼—4.FlowSlot實現流控的原理二

大綱 1.FlowSlot根據流控規則對請求進行限流 2.FlowSlot實現流控規則的快速失敗效果的原理 3.FlowSlot實現流控規則中排隊等待效果的原理 4.FlowSlot實現流控規則中Warm Up效果的原理 3.FlowSlot實現流控規則中排隊等待效果的原理 (1)實現排隊等待流控效果的普通漏桶算法介…

2025華中杯數學建模B題完整分析論文(共42頁)(含模型、數據、可運行代碼)

2025華中杯大學生數學建模B題完整分析論文 目錄 一、問題重述 二、問題分析 三、模型假設 四、 模型建立與求解 4.1問題1 4.1.1問題1解析 4.1.2問題1模型建立 4.1.3問題1樣例代碼&#xff08;僅供參考&#xff09; 4.1.4問題1求解結果&#xff08;僅供參考&am…

Project ERROR: liblightdm-qt5-3 development package not found問題的解決方法

問題描述&#xff1a;使用make命令進行ukui-greeter-Debian構建時出現Project ERROR: liblightdm-qt5-3 development package not found錯誤&#xff0c;具體如圖&#xff1a; 問題原因&#xff1a;缺乏liblightdm-qt5-3 development軟件包 解決方法&#xff1a;安裝liblightd…

【C++面向對象】封裝(下):探索C++運算符重載設計精髓

&#x1f525;個人主頁 &#x1f525; &#x1f608;所屬專欄&#x1f608; 每文一詩 &#x1f4aa;&#x1f3fc; 年年歲歲花相似&#xff0c;歲歲年年人不同 —— 唐/劉希夷《代悲白頭翁》 譯文&#xff1a;年年歲歲繁花依舊&#xff0c;歲歲年年看花之人卻不相同 目錄 C運…

從代碼學習深度學習 - Transformer PyTorch 版

文章目錄 前言1. 位置編碼(Positional Encoding)2. 多頭注意力機制(Multi-Head Attention)3. 前饋網絡與殘差連接(Position-Wise FFN & AddNorm)3.1 基于位置的前饋網絡(PositionWiseFFN)3.2 殘差連接和層規范化(AddNorm)4. 編碼器(Encoder)4.1 編碼器塊(Enco…

閱讀分析Linux0.11 /boot/head.s

目錄 初始化IDT、IDTR和GDT、GDTR檢查協處理器并設置CR0寄存器初始化頁表和CR3寄存器&#xff0c;開啟分頁 初始化IDT、IDTR和GDT、GDTR startup_32:movl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fsmov %ax,%gslss _stack_start,%espcall setup_idtcall setup_gdtmovl $0x1…

33、單元測試實戰練習題

以下是三個練習題的具體實現方案&#xff0c;包含完整代碼示例和詳細說明&#xff1a; 練習題1&#xff1a;TDD實現博客評論功能 步驟1&#xff1a;編寫失敗測試 # tests/test_blog.py import unittest from blog import BlogPost, Comment, InvalidCommentErrorclass TestBl…

16-算法打卡-哈希表-兩個數組的交集-leetcode(349)-第十六天

1 題目地址 349. 兩個數組的交集 - 力扣&#xff08;LeetCode&#xff09;349. 兩個數組的交集 - 給定兩個數組 nums1 和 nums2 &#xff0c;返回 它們的 交集 。輸出結果中的每個元素一定是 唯一 的。我們可以 不考慮輸出結果的順序 。 示例 1&#xff1a;輸入&#xff1a;nu…

SciPy庫詳解

SciPy 是一個用于數學、科學和工程計算的 Python 庫&#xff0c;它建立在 NumPy 之上&#xff0c;提供了許多高效的算法和工具&#xff0c;用于解決各種科學計算問題。 CONTENT 1. 數值積分功能代碼 2. 優化問題求解功能代碼3. 線性代數運算功能代碼 4. 信號處理功能代碼 5. 插…

杰弗里·辛頓:深度學習教父

名人說&#xff1a;路漫漫其修遠兮&#xff0c;吾將上下而求索。—— 屈原《離騷》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 杰弗里辛頓&#xff1a;當堅持遇見突破&#xff0c;AI迎來新紀元 一、人物簡介 杰弗…

BladeX單點登錄與若依框架集成實現

1. 概述 本文檔詳細介紹了將BladeX認證系統與若依(RuoYi)框架集成的完整實現過程。集成采用OAuth2.0授權碼流程&#xff0c;使用戶能夠通過BladeX賬號直接登錄若依系統&#xff0c;實現無縫單點登錄體驗。 2. 系統架構 2.1 總體架構 #mermaid-svg-YxdmBwBtzGqZHMme {font-fa…

初識Redis · set和zset

目錄 前言&#xff1a; set 基本命令 交集并集差集 內部編碼和應用場景 zset 基本命令 交集并集差集 內部編碼和應用場景 應用場景&#xff08;AI生成&#xff09; 排行榜系統 應用背景 設計思路 熱榜系統 應用背景 設計思路 熱度計算方式 總結對比表 前言&a…

playwright 教程高級篇:掌握網頁自動化與驗證碼處理等關鍵技術詳解

Playwright 教程高級篇:掌握網頁自動化與驗證碼處理等關鍵技術詳解 本教程將帶您一步步學習如何使用 Playwright——一個強大的瀏覽器自動化工具,來完成網頁任務,例如提交鏈接并處理旋轉驗證碼。我們將按照典型的自動化流程順序,從啟動瀏覽器到關閉瀏覽器,詳細講解每個步驟…

數據結構(完)

樹 二叉樹 構建二叉樹 int value;Node left;Node right;public Node(int val) {valueval;} 節點的添加 Node rootnull;public void insert(int num) {Node nodenew Node(num);if(rootnull) {rootnode;return;}Node index root;while(true) {//插入的節點值小if(index.value&g…

FastAPI與SQLAlchemy數據庫集成與CRUD操作

title: FastAPI與SQLAlchemy數據庫集成與CRUD操作 date: 2025/04/16 09:50:57 updated: 2025/04/16 09:50:57 author: cmdragon excerpt: FastAPI與SQLAlchemy集成基礎包括環境準備、數據庫連接配置和模型定義。CRUD操作通過數據訪問層封裝和路由層實現,確保線程安全和事務…

一個基于Django的寫字樓管理系統實現方案

一個基于Django的寫字樓管理系統實現方案 用戶現在需要我用Django來編寫一個寫字樓管理系統的Web版本&#xff0c;要求包括增刪改查寫字樓的HTML頁面&#xff0c;視頻管理功能&#xff0c;本地化部署&#xff0c;以及人員權限管理&#xff0c;包含完整的代碼結構和功能實現&am…

mongodb在window10中創建副本集的方法,以及node.js連接副本集的方法

創建Mongodb的副本集最好是新建一個文件夾&#xff0c;如D:/data&#xff0c;不要在mongodb安裝文件夾里面創建副本集&#xff0c;雖然這樣也可以&#xff0c;但是容易造成誤操作或路徑混亂&#xff1b;在新建文件夾里與現有 MongoDB 數據隔離&#xff0c;避免誤操作影響原有數…

Maven 多倉庫與鏡像配置全攻略:從原理到企業級實踐

Maven 多倉庫與鏡像配置全攻略&#xff1a;從原理到企業級實踐 一、核心概念&#xff1a;Repository 與 Mirror 的本質差異 在 Maven 依賴管理體系中&#xff0c;repository與mirror是構建可靠依賴解析鏈的兩大核心組件&#xff0c;其核心區別如下&#xff1a; 1. Repositor…

STM32 四足機器人常見問題匯總

文章不介紹具體參數&#xff0c;有需求可去網上搜索。 特別聲明&#xff1a;不論年齡&#xff0c;不看學歷。既然你對這個領域的東西感興趣&#xff0c;就應該不斷培養自己提出問題、思考問題、探索答案的能力。 提出問題&#xff1a;提出問題時&#xff0c;應說明是哪款產品&a…

MySQL 中 `${}` 和 `#{}` 占位符詳解及面試高頻考點

文章目錄 一、概述二、#{} 和 ${} 的核心區別1. 底層機制代碼示例 2. 核心區別總結 三、為什么表名只能用 ${}&#xff1f;1. 預編譯機制的限制2. 動態表名的實現 四、安全性注意事項1. ${} 的風險場景2. 安全實踐 五、面試高頻考點1. 基礎原理類問題**問題 1**&#xff1a;**問…