文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue中不通过v-model怎么实现双向绑定

2023-06-29 01:45

关注

本文小编为大家详细介绍“Vue中不通过v-model怎么实现双向绑定”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue中不通过v-model怎么实现双向绑定”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

Vue中不通过v-model怎么实现双向绑定

先来看解答:

<template>  <div class="test-v-model">    <p>使用v-model</p>    <input v-model="msg" placeholder="edit me" />    <p>{{ msg }}</p>    <p>不使用v-model</p>    <input :value="msg1" @input="handleInput" placeholder="edit me" />    <p>{{ msg1 }}</p>  </div></template><script>export default {  name: 'test-v-model',  data() {    return {      msg: '',      msg1: ''    }  },  methods: {    handleInput(e) {      this.msg1 = e.target.value    }  }}</script>

不使用 v-model,就需要通过 value 属性绑定值和 input 事件改变绑定值来实现双向绑定。

换句话说,v-model只是一种简写形式而已

事实上,v-model 的本质就是语法糖,它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 -- 官方文档

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;

  • checkbox 和 radio 使用 checked property 和 change 事件;

  • select 字段将 value 作为 prop 并将 change 作为事件。

与本题相关联的知识延伸

问:什么是双向绑定?

双向绑定就是当数据变化之后,视图同步更新,当视图变化之后,数据也会更新。

问:什么是单向数据绑定?

单向数据绑定就是当数据变化之后,视图同步更新,当视图变化之后,数据不会更新。

在vue中是通过指令 v-model 来实现双向绑定,通过 v-bind 来实现单向数据绑定

看完下面这段代码和这段代码运行的gif演示,你就能明白他们的区别了。

<template>  <div>    <p>双向绑定</p>    <input v-model="msg" placeholder="edit me" />    <p>{{ msg }}</p>    <p>单向数据绑定</p>    <input v-bind:value="msg1" placeholder="edit me" />    <p>{{ msg1 }}</p>  </div></template><script>export default {  name: 'test-v-model',  data() {    return {      msg: '',      msg1: ''    }  }}</script>

Vue中不通过v-model怎么实现双向绑定

从gif图中可以看出,使用 v-model,当数据变化之后,视图同步更新,当视图变化之后,数据也会更新,这就是双向绑定。

使用 v-bind,当数据变化之后,视图同步更新,当视图变化之后,数据不会更新,这就是单向数据绑定。

问:什么是 vue 单向数据流?

子组件不能改变父组件传递给它的 prop 属性,推荐的做法是它抛出事件,通知父组件自行改变绑定的值。
总结起来就是数据向下,事件向上。

vue 文档在介绍 Prop 时就提出了单向数据流的概念,点击此处 查看 vue 文档对单向数据流的说明。

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

我们看下面这个例子:

子组件直接对 prop 值做双向绑定,会发生什么?

父组件代码:

<template>  <child-component :value="fatherValue" /></template><script>import ChildComponent from './child.vue'export default {  name: 'father-component',  components: {    ChildComponent  },  data() {    return {      fatherValue: ''    }  }}</script>

子组件代码:

<template>  <div class="child-component">    <input v-model="value" placeholder="edit me" />    <p>{{ value }}</p>  </div></template><script>export default {  name: 'child-component',  props: {    value: {      type: String,      default: ''    }  }}</script>

Vue中不通过v-model怎么实现双向绑定

Vue中不通过v-model怎么实现双向绑定

Vue中不通过v-model怎么实现双向绑定

可以看到,childComponent中的 prop 值可以实现双向绑定,但是 FatherComponent 中的 data 值并未发生改变,而且控制台抛出了警告:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"

翻译一下:避免直接改变 prop 值,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于 prop 值的 data 或 computed。

很显然,直接改变子组件的 prop 值的这种行为被 vue 禁止了。

如何操作传入子组件的 prop 值

但是很多时候,我们确实要操作传入子组件的 prop 值,该怎么办呢?

正如上面的警告所说,有两种办法:

props: {  initialCounter: {    type: Number,    default: 0  },},data() {  return {    counter: this.initialCounter  }}
props: {  size: {    type: String,    default: ''  }},computed: {  normalizedSize: function () {    return this.size.trim().toLowerCase()  }}

这样不管怎么操作数据都是操作的子组件数据了,不会影响到父组件数据。

所以,我们想用 prop 传入的数据实现双向绑定,可以这么写:

父组件代码不变

子组件里用 innerValue 来接收传入的 value :

<template>  <div class="child-component">    <input v-model="innerValue" placeholder="edit me" />    <p>{{ innerValue }}</p>  </div></template><script>export default {  name: 'child-component',  props: {    value: {      type: String,      default: ''    }  },  data() {    return {      innerValue: this.value    }  }}</script>

这里要注意一个问题

在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

还是上面的例子,我们将传入的值改为对象:

父组件代码:

<template>  <child-component :obj="fatherObj" /></template><script>import ChildComponent from './child.vue'export default {  name: 'father-component',  components: {    ChildComponent  },  data() {    return {      fatherObj: {        name: 'lin'      }    }  }}</script>

子组件代码:

<template>  <div class="child-component">    <input v-model="innerObj.name" placeholder="edit me" />    <p>{{ innerObj.name }}</p>  </div></template><script>export default {  name: 'child-component',  props: {    obj: {      type: Object,      default: () => {}    }  },  data() {    return {      innerObj: this.obj    }  }}</script>

Vue中不通过v-model怎么实现双向绑定

Vue中不通过v-model怎么实现双向绑定

这里的 this.obj 是引用类型,赋值给了 innerObj,所以 innerObj 实际上还是指向了父组件的数据,对 innerObj.name 的修改依然会影响到父组件

所以,处理这种引用类型数据的时候,需要深拷贝一下

import { clone } from 'xe-utils'export default {  name: 'child-component',  props: {    obj: {      type: Object,      default: () => {}    }  },  data() {    return {      innerObj: clone(this.obj, true)    }  }}

Vue中不通过v-model怎么实现双向绑定

如上图所示,这样子组件和父组件之间的数据就不会互相影响了。

读到这里,这篇“Vue中不通过v-model怎么实现双向绑定”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯