이 글은 vue2의 v-model을 이해하고, v-model이 양방향 바인딩인지 단방향 데이터 흐름인지 확인하고, 개발한 구성 요소가 v-model을 지원하도록 만드는 방법을 안내합니다. 모두에게.
당신은:
v-model
의 구문 설탕은 무엇입니까? vue2
는 네이티브 구성 요소에 대해 어떤 특별한 처리를 합니까? v-model
是什么的语法糖? vue2
对原生组件究竟做了什么特殊处理?v-model
到底是单向数据流还是数据双向绑定?v-model
在语法糖之外的『副作用』?v-model
语法。v-model
的本质是语法糖。『
v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。』 -- 官方文档。【相关推荐:vue.js教程】
什么是语法糖?
语法糖,简单来说就是『便捷写法』。
在大部分情况下, v-model="foo"
等价于 :value="foo"
加上 @input="foo = $event"
;
<!-- 在大部分情况下,以下两种写法是等价的 --> <el-input v-model="foo" /> <el-input :value="foo" @input="foo = $event" />
没错,在大部分情况下如此。
但也有例外:
vue2
给组件提供了 model
属性,可以让用户自定义传值的prop名和更新值的事件名。这个暂且略过,第四节会细说。
对于原生 html
原生元素,vue
干了大量『脏活儿』,目的是为了能让我们忽视 html
在api上的差异性。以下元素的左右两种写法是等价的:
textarea
元素:select
下拉框:input type='radio'
单选框:input type='checkbox'
多选框:在编程思想上,这种帮助使用者『隐藏细节』的方式叫封装。
v-model
不仅仅是语法糖,它还有副作用。
副作用如下:如果 v-model
绑定的是响应式对象上某个不存在的属性,那么 vue
会悄悄地增加这个属性,并让它响应式。
举个例子,看下面的代码:
// template中: <el-input v-model="user.tel"></el-input> // script中: export default { data() { return { user: { name: '公众号: 前端要摸鱼', } } } }
响应式数据中没有定义 user.tel
属性,但是 template
里却用 v-model
绑定了 user.tel
,猜一猜当你输入时会发生什么?
看效果:
揭晓答案吧:user
上会新增 tel
属性,并且 tel
这个属性还是响应式的。
这就是『副作用』带来的效果,你学会了吗?
v-model
是双向绑定还是单向数据流?v-model
是双向绑定吗?是,官方说是。
『你可以用 v-model 指令在表单 <input>
、<textarea></textarea>
及 <select></select>
元素上创建双向数据绑定。』 —— vue2官方文档
v-model
是单向数据流吗?是的,它甚至是单向数据流的典型范式。
虽然官方没有明确表示这点,但我们可以捋一捋两者的关系。
子组件不能改变父组件传递给它的 prop
属性,推荐的做法是它抛出事件,通知父组件自行改变绑定的值。
v-model
的做法是怎样的?v-model
알아보세요: v-model
이 단방향 데이터 흐름인가요, 아니면 양방향 데이터 바인딩인가요?
v-model
의 "부작용"은 무엇입니까? 🎜구성 요소가 v-model
구문도 지원하도록 만드는 방법을 알아보세요. v-model
의 핵심은 구문 설탕입니다. 🎜🎜 『v-model
은 본질적으로 단지 구문 설탕입니다. 사용자 입력 이벤트를 수신하여 데이터를 업데이트하고 일부 극단적인 시나리오에 대한 특수 처리를 수행하는 역할을 담당합니다. 』 --공식 문서. [관련 권장 사항: vue.js 튜토리얼]🎜
🎜Syntactic Sugar란 무엇인가요? 🎜🎜Syntactic sugar는 간단히 말해서 "편리한 글쓰기"입니다. 🎜🎜대부분의 경우
v-model="foo"
는 :value="foo"
에 @input= "foo =를 더한 것과 동일합니다. $event"
; 🎜// 默认的 model 属性 export default { model: { prop: 'value', event: 'input' } }🎜예, 대부분의 경우입니다. 🎜🎜그러나 예외도 있습니다. 🎜
vue2
는 구성 요소에 대한 model
속성을 제공하여 사용자가 전달된 값의 소품 이름과 업데이트된 값의 이벤트 이름을 정의합니다. 지금은 이 내용을 건너뛰고 섹션 4에서 자세히 설명하겠습니다. 🎜🎜🎜기본 html
기본 요소의 경우 vue
는 html을 무시하도록 만들기 위해 많은 "더러운 작업"을 수행했습니다. 코드> API의 차이점. 다음 요소의 왼쪽 및 오른쪽 쓰기 방법은 동일합니다. 🎜🎜<code>textarea
요소:
선택
드롭다운 상자: 🎜 🎜🎜🎜input type='radio'
라디오 버튼: 🎜🎜🎜🎜input type='checkbox'
다중 체크박스: ul>🎜🎜🎜 프로그래밍 사고 측면에서 사용자가 "세부사항 숨기기"를 돕는 이러한 방식을 캡슐화라고 합니다. 🎜🎜v-model
은 문법적 설탕일 뿐만 아니라 부작용도 있습니다. 🎜
🎜부작용은 다음과 같습니다. v-model
이 반응형 개체의 존재하지 않는 속성에 바인딩된 경우 vue
는 조용히 이 속성을 추가하고 반응형으로 만드세요. 🎜🎜예를 들어 다음 코드를 살펴보세요. 🎜// 默认的 model 属性 export default { model: { prop: 'ame', event: 'zard' } }🎜
user.tel
속성은 반응형 데이터에 정의되어 있지 않지만 는 <code>템플릿 >v-model
은 user.tel
에 연결되어 있습니다. 입력하면 어떻게 될까요? 🎜🎜효과 보기:user
는 새로운 tel
속성을 갖게 되며 tel
속성은 여전히 반응형 공식. 🎜🎜이게 "부작용"의 효과인데, 혹시 배워보셨나요? 🎜v-model
은 양방향 바인딩인가요, 아니면 단방향 데이터 흐름인가요? 🎜v-model
은 양방향 바인딩인가요? 🎜네, 관계자가 그렇다고 하더군요. 🎜🎜 『
<input>
, <textarea></textarea>
및 <select> 요소에 대한 양방향 데이터 바인딩을 만듭니다. 』——vue2 공식 문서🎜<h3 data-id="heading-5">2.2 <code>v-model
은 단방향 데이터 흐름인가요?
🎜예, 이는 단방향 데이터 흐름의 일반적인 패러다임이기도 합니다. 🎜🎜공식적으로는 이를 명시적으로 언급하지는 않았지만, 두 사람의 관계를 짐작할 수 있습니다. 🎜🎜🎜단일 데이터 스트림이란 무엇인가요? 🎜하위 구성 요소는 상위 구성 요소가 전달한
prop
속성을 변경할 수 없습니다. 권장되는 접근 방식은 이벤트를 발생시키고 상위 구성 요소에 변경을 알리는 것입니다. 그 자체로 제한된 값. 🎜🎜🎜v-model
은 어떻게 작동하나요? 🎜v-model
이 접근 방식은 단일 데이터 흐름과 완전히 일치합니다. 게다가 이름 지정 및 이벤트 정의에 대한 사양도 제공합니다. 🎜众所周知 .sync
修饰符是单向数据流的另一个典型范式。
『单向数据流』总结起来其实也就8个字:『数据向下,事件向上』。
v-model
虽然不想说,但这确实是高频面试题。
在定义 vue
组件时,你可以提供一个 model
属性,用来定义该组件以何种方式支持 v-model
。
model
属性本身是有默认值的,如下:
// 默认的 model 属性 export default { model: { prop: 'value', event: 'input' } }
也就是说,如果你不定义 model
属性,或者你按照当面方法定义属性,当其他人使用你的自定义组件时,v-model="foo"
就完全等价于 :value="foo"
加上 @input="foo = $event"
。
如果把 model
属性进行一些改装,如下:
// 默认的 model 属性 export default { model: { prop: 'ame', event: 'zard' } }
那么,v-model="foo"
就等价于 :ame="foo"
加上 @zard="foo = $event"
。
没错,就是这么容易,让我们看个例子。
先定义一个自定义组件:
<template> <div> 我们是TI{{ ame }}冠军 <el-button @click="playDota2(1)">加</el-button> <el-button @click="playDota2(-1)">减</el-button> </div> </template> <script> export default { props: { ame: { type: Number, default: 8 } }, model: { // 自定义v-model的格式 prop: 'ame', // 代表 v-model 绑定的prop名 event: 'zard' // 代码 v-model 通知父组件更新属性的事件名 }, methods: { playDota2(step) { const newYear = this.ame + step this.$emit('zard', newYear) } } } </script>
然后我们在父组件中使用该组件:
// template中 <dota v-model="ti"></dota> // script中 export default { data() { return { ti: 8 } } }
看看效果:
让你的组件支持 v-model
就这么容易。
获取源码请访问github
https://github.com/zhangshichun/blog-vue2-demos/tree/master/src/views/about-v-model
更多编程相关知识,请访问:编程视频!!
위 내용은 vue2의 v-model에 대해 심층적으로 이해하고 구성 요소가 이 구문을 지원하도록 만드는 방법을 알아보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!