Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day101:Vue v-model 是如何实现的,语法糖实际是什么 #914

Open
Genzhen opened this issue Jul 21, 2020 · 2 comments
Open

Day101:Vue v-model 是如何实现的,语法糖实际是什么 #914

Genzhen opened this issue Jul 21, 2020 · 2 comments
Labels
Vue teach_tag 脉脉 company

Comments

@Genzhen
Copy link
Collaborator

Genzhen commented Jul 21, 2020

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

@Genzhen Genzhen added the Vue teach_tag label Jul 21, 2020
@Genzhen
Copy link
Collaborator Author

Genzhen commented Jul 21, 2020

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

一、语法糖

指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。糖在不改变其所在位置的语法结构的前提下,实现了运行时的等价。可以简单理解为,加糖后的代码编译后跟加糖前一样,代码更简洁流畅,代码更语义自然.

二、实现原理

1.作用在普通表单元素上

动态绑定了 input 的 value 指向了 messgae 变量,并且在触发 input 事件的时候去动态把 message 设置为目标值

<input v-model="sth" />
//  等同于
<input 
    v-bind:value="message" 
    v-on:input="message=$event.target.value"
>
//$event 指代当前触发的事件对象;
//$event.target 指代当前触发的事件对象的dom;
//$event.target.value 就是当前dom的value值;
//在@input方法中,value => sth;
//在:value中,sth => value;

2.作用在组件上

在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件

本质是一个父子组件通信的语法糖,通过prop和$.emit实现

因此父组件v-model语法糖本质上可以修改为 '<child :value="message" @input="function(e){message = e}"></child>'

在组件的实现中,我们是可以通过 v-model属性 来配置子组件接收的prop名称,以及派发的事件名称。

例子

// 父组件
<aa-input v-model="aa"></aa-input>
// 等价于
<aa-input v-bind:value="aa" v-on:input="aa=$event.target.value"></aa-input>

// 子组件:
<input v-bind:value="aa" v-on:input="onmessage"></aa-input>

props:{value:aa,}
methods:{
    onmessage(e){
        $emit('input',e.target.value)
    }
}

默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event

但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

js 监听input 输入框输入数据改变,用oninput ,数据改变以后就会立刻出发这个事件。

通过input事件把数据$emit 出去,在父组件接受。

父组件设置v-model的值为input$emit过来的值。

@Genzhen Genzhen added the 脉脉 company label Aug 26, 2020
@xiehaitao0229
Copy link

xiehaitao0229 commented Sep 11, 2020

v-model指令在表单input,textarea,select等元素上创建双向数据绑定,本质上是语法糖
v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件

text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。

<input v-model='something'>
相当于
<input :value="something" @input="something = $event.target.value">

v-model的缺点和解决方法
    缺点:
        v-model应用到组件上,它会默认把value作为组件的属性,把input作为给组件绑定的事件时的事件名
        有时候我们不想用value当做默认的属性名和不想input作为给组件绑定的时间时的事件名
    
    解决方法:
        在vue2.2版本之后,可以在定义组件时通过model选项方式定制prop/event
        export default{
              model: {
                 prop: 'num', // 自定义属性名
                 event: 'addNum' // 自定义事件名
              },
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Vue teach_tag 脉脉 company
Projects
None yet
Development

No branches or pull requests

2 participants