(三)vue:自定义组件上使用v-model

一.v-model是如何工作的

input, select, textarea等是我们常用的在应用中传递数据的途径。在vue中我们可以通过v-model进行双向数据绑定,下面看一个例子:

<div id="app1">
   <input type="text" v-model="message">
   <span>{{message}}</span>
</div>
<script>
   var app1 = new Vue({
        el:'#app1',
         data:{
             message:"Hello Vue"
         }
   });
</script>

打开浏览器,查看渲染结果。
在这里插入图片描述
更改文本内容,可以看到中的内容会跟随变化。

其实vue在解释v-model的时候会做一个转化工作,实质是下面这样:

<div id="app2">
   <input type="text" :value="message" @input="message = $event.target.value">
   <span>{{message}}</span>
</div>
<script>
   var app2 = new Vue({
        el:'#app2',
         data:{
             message:"Hello Vue"
         }
   });
</script>

通过input元素的value属性,和input事件达到v-model的作用。

二.仿照v-model的实现方法,在自定义组件上实现v-model功能

了解了v-model的本质,我们可以在自定义组件上模拟v-model的功能。编辑代码如下:

<div id="app3">
        <custom-input2 :inputValue="message" @input-change="message=$event.target.value" :value="message"></custom-input2>
        <span>{{message}}</span>
</div>
<script type="text/javascript">
	Vue.component('custom-input2', {
        props:{
            inputValue:String
        },
        template:`<input type="text" :value="inputValue" @input="$emit('input-change', $event)"/>`
    });
    var app3 = new Vue({
         el:'#app3',
         data:{
             message:'Hello Vue'
         }
     });
</script>

打开浏览器,查看渲染结果,并修改文本框中的值,可以看到我们的目的达到了:
在这里插入图片描述
但是这样做法有点太麻烦,能不能利用v-model达到我们想要的结果呢,请继续往下面看。

三.自定义组件应用v-model

先直接在自定义组件上使用v-model:

<div id="app4">
  <custom-input v-model="message"></custom-input>
  <span>{{message}}</span>
</div>
<script>
Vue.component('custom-input3',{
   props:{
        value:String
    },
});
var app3 = new Vue({
	el:'#app3',
	   data:{
	       message:'Hello Vue'
	   }
});
</script>

当然这肯定无法达到我们想要的结果,那应该怎么实现呢,首先,要明确的是v-model接受一个value属性和一个input属性,先看下面一个例子:

    <div id="app">
        <basic-input :value="name" @input="name=$event"></basic-input>
        <p>
            <strong>Name:</strong> {{ name }}
        </p>
    </div>
     <script type="text/javascript">
	    const BasicInput = {
	        template: '<input v-model="content" @input="handleInput" />',
	        prop: ['value'],
	        data() {
	            return {
	                content: this.value
	            }
	        },
	        methods: {
	            handleInput(e) {
	                this.$emit('input', this.content)
	            }
	        }
	    }
	    new Vue({
	        el: '#app',
	        data: { name: '' },
	        components: { BasicInput }
	    })
    </script>

渲染结果:
在这里插入图片描述
上面代码功能是我们想要的,但是basic-input还是没有用到v-model,但是我们可以发现,它用到了value属性和input事件,那么我们只需要在使用组件的地方更改成如下代码就可以了:

<basic-input v-model="name"></basic-input>

好,至此我们已经实现了在自定义组件上使用v-model的目的,但真的结束了吗?通过上面的研究可以发现,v-model最终转化为value属性和input事件来实现,这就限制了使用的范围,怎么使用我们自定义的事件和属性呢,请继续往下看。

四.使用自定义事件和属性

vue组件为我们提供了一个model属性,这个属性可以帮助我们达到使用自定义事件和属性的目的,将代码修改如下:

    <div id="app">
        <basic-input v-model="name"></basic-input>
        <p>
            <strong>Name:</strong> {{ name }}
        </p>
    </div>
    <script type="text/javascript">
    const BasicInput = {
        template: '<input v-model="content" @input="handleInput" />',
        prop: ['new-value'],
        model:{
          event:'input-change',
          prop:'new-value'
        },
        data() {
            return {
                content: this.new-value
            }
        },
        methods: {
            handleInput(e) {
                this.$emit('input-change', this.content)
            }
        }
    }

    new Vue({
        el: '#app',
        data: { name: '' },
        components: { BasicInput }
    })
    </script>

vue在解析 <basic-input v-model="name"></basic-input>时,会将其转化为<basic-input :new-value=name @input-change="name=$event"></basic-input>.

以上就是我对v-model的理解,如有不对的地方,请在下方纠正。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值