Vue中v-model和sync的解析

19 篇文章 0 订阅
4 篇文章 0 订阅

前言

Vue中v-modelsync一样都是实现双向绑定的语法糖,可以让开发者少些一些代码,两者编译后都会产生一个属性和一个事件,不过两者规则不大一样。

sync

sync实现双向绑定主要用于子组件修改父组件的数据的一种便捷操作,常用于分页器等组件。要想使用sync,子组件需要有如下规则:

要想使用sync作为数据的双向绑定的修饰符,子组件必须向外抛出的时间满足规则:$emit(“update:{propName}”, {newValue}),其中propName是修改的prop名字,newValue是传递给父组件数据count的新数据
子组件:

<template>
  <div class="hello">
    <span>{{count}}</span>
    <button @click="$emit('update:count', count + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['count']
}
</script>

父组件:
父组件接收时可以使用传统的方式进行接收,也可以使用sync修饰符修饰绑定的数据count

<template>
  <div id="app">
    <HelloWorld :count="count" @update:count="count=$event"/>
    <HelloWorld :count.sync="count"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data() {
    return {
      count: 1
    }
  }
}
</script>

v-model

v-model实现和sync类似,其最终结果也会生成一个事件和一个属性,先看一下如下代码输出

<template>
  <div class="hello">
    <input type="text" v-model="data" />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      data: ''
    };
  },
  mounted() {
    console.log(this._vnode);
  }
};
</script>

输出如下:
在这里插入图片描述
我们可以清楚地看到,在HelloWorld组件中input输入框所绑定的数据中,on有一个input事件,domProps有一个value事件,所以上面的组件等效于如下代码:

<template>
  <div class="hello">
    <input type="text" :value="data" @input="data=$event.target.value" />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      data: ''
    };
  },
  mounted() {
    console.log(this._vnode);
  }
};
</script>
v-model作用于表单

Vue中v-model常用作用于表单元素,vue会根据所绑定的表单元素类型,合成合适的事件和属性,例如作用于文本框时生成一个value属性和一个input事件,而当其绑定单选框或多选框时,它会生成checked属性和change事件

v-mode作用于组件

v-model也可以作用于组件实例,例如:
父组件:

<template>
  <div id="app">
    <HelloWorld v-model="count"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data() {
    return {
      count: 1
    }
  }
}
</script>

子组件:

<template>
  <div class="hello">
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  mounted() {
    console.log(this.$vnode);
  }
};
</script>

我们先看一下console输出什么:
在这里插入图片描述
可以很明显地看到,在子组件形成的虚拟dom中,data有个model对象。接下来我们改造一下子组件。
我们将props中声明一个value

<template>
  <div class="hello">
    {{value}}
    <button @click="$emit('input', value + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["value"],
  mounted() {
    console.log(this.$vnode);
  }
};
</script>

我们可以很清楚地看到,count数据会改变,这是为啥呢???
v-model默认值是value属性和input事件,这从我们最开始的那个v-model截图和测试就可以看出来。
当然我们也可以改变其默认值。在组件中加入如下配置:
子组件

<template>
  <div class="hello">
    {{ count }}
    <button @click="$emit('update', count + 1)">+1</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  model: {
    prop: "count",
    event: "update",
  },
  props: ["count"],
  mounted() {
    console.log(this);
  },
};
</script>

我们也可以看到视图是能够正常进行更新的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值