vue组件中,props双向绑定的实现

1、vue2.x中的使用

总所周知, vue2.x 中,在组件上使用 v-model 相当于绑定 value prop 和 input 事件:

<Component v-model="pageTitle" />
<!-- 等同于: -->
<Component :value="pageTitle" @input="pageTitle = $event" />

在组件内部,可通过model接收,将默认的属性名value或默认绑定的input事件进行更改:

// Component.vue
export default {
  model: {
    prop: 'title', // 将默认的value更改为title
    event: 'change' // 将默认的input事件更改为change
  },
  props: {
    // 这将允许 `value` 属性用于其他用途
    value: String,
    // 使用 `title` 代替 `value` 作为 model 的 prop
    title: {
      type: String,
      default: ''
    }
  },
  methods: {
  	// 子组件中,可通过调用changeTitle方法,传入value去更改父组件中的pageTitle
  	changeTitle(value) {
  		this.$emit('change', value)
  	}
  }
}

比较局限的是,在vue2.x的版本中,通过v-model这种方式,只能使一组prop达到双向绑定的目的,若要绑定多个prop,我们可以使用.sync修饰符,来设置多个prop的绑定:

<Component :page.sync ="homePage"/>
<!-- 等同于: -->
<Component :page= "homePage" @update:page="homePage =$event" />

多个prop

<Component :page.sync ="homePage" :page-size.sync ="pageSize"/>
<!-- 等同于: -->
<Component :page= "homePage" @update:page="homePage =$event" :page-size= "pageSize" @update:pageSize="pageSize =$event" />

组件内部,则可通过$emit去更改父组件中的值

// Component.vue
export default {
  props: {
    page: {
      type: String,
      default: ''
    },
    pageSize: {
      type: String,
      default: ''
    }
  },
  methods: {
  	changePage(value) {
  		this.$emit('update:page', value)
  	},
  	changePageSize(value) {
  		this.$emit('update:pageSize', value)
  	}
  }
}
2、vue3.x中的使用

以上是vue2.x中运用的方法,在 3.x 中,v-model语法糖将二者进行了结合,在自定义组件上的 v-model 相当于传递了 modelValue prop 并接收抛出的 update:modelValue 事件:

<Component v-model:page="homePage" />
<!-- 等同于 -->
<Component :page="homePage" @update:page="homePage = $event" />
3、完整实现

写法上,类似于vue2.x中的.sync修饰符,在官方文档说明中,3.x也推荐使用通过v-model这种方式,去替换.sync修饰符这种写法,若结合组件内的computed,会达到更多意想不到的效果:

<!-- home.vue-->
<Component v-model:page="homePage" v-model:page-size="pageSize" />
// Component.vue
export default {
  props: {
    page: {
      type: String,
      default: ''
    },
    pageSize: {
      type: String,
      default: ''
    }
  },
  computed: {
  	// 通过get与set方法,可是page这个prop在子组件中,通过sonPage去监听更改
  	// 子组件也可以随意更改和使用sonPage这个属性
  	sonPage: {
  		get() {
  			return this.page
  		},
  		set(value) {
  			this.$emit('update:page', value)
  		}
  	},
  	sonSize: {
  		get() {
  			return this.pageSize
  		},
  		set(value) {
  			this.$emit('update:pageSize', value)
  		}
  	}
  }
}
Logo

前往低代码交流专区

更多推荐