Vue 实现双向绑定的四种方法


Posted in Javascript onMarch 16, 2018

1. v-model 指令

<input v-model="text" />

上例不过是一个语法糖,展开来是:

<input
 :value="text"
 @input="e => text = e.target.value"
/>

2. .sync 修饰符

<my-dialog :visible.sync="dialogVisible" />

这也是一个语法糖,剥开来是:

<my-dialog
 :visible="dialogVisible"
 @update:visible="newVisible => dialogVisible = newVisible"
/>

my-dialog 组件在 visible 变化时 this.$emit('update:visible', newVisible) 即可。

3. model 属性 (JSX/渲染函数中)

Vue 在 2.2.0 版本以后,允许自定义组件的 v-model ,这就导致在 JSX / 渲染函数中实现 v-model 时得考虑组件的不同配置,不能一律如此(假使 my-dialog 组件的 model 为 { prop: 'visible', event: 'change' } ):

{
 render(h) {
  return h('my-dialog', {
   props: { value: this.dialogVisible },
   on: { input: newVisible => this.dialogVisible = newVisible }
  })
 }
}

而应如此:

{
 render(h) {
  return h('my-dialog', {
   props: { visible: this.dialogVisible },
   on: { change: newVisible => this.dialogVisible = newVisible }
  })
 }
}

然而,利用 model 属性,完全可以做到不用管它 prop 、 event 的目的:

{
 render(h) {
  return h('my-dialog', {
   model: {
    value: this.dialogVisible,
    callback: newVisible => this.dialogVisible = newVisible
   }
  })
 }
}

JSX 中这样使用:

{
 render() {
  return (
   <my-dialog
    {...{
     model: {
      value: this.dialogVisible,
      callback: newVisible => this.dialogVisible = newVisible
     }
    }}
   />
  )
 }
}

4. vue-better-sync 插件

有需求如此:开发一个 Prompt 组件,要求同步用户的输入,点击按钮可关闭弹窗。

Vue 实现双向绑定的四种方法

一般我们会这样做:

<template>
 <div v-show="_visible">
  <div>完善个人信息</div>
  <div>
   <div>尊姓大名?</div>
   <input v-model="_answer" />
  </div>
  <div>
   <button @click="_visible = !_visible">确认</button>
   <button @click="_visible = !_visible">取消</button>
  </div>
 </div>
</template>
<script>
export default {
 name: 'prompt',
 props: {
  answer: String,
  visible: Boolean
 },
 computed: {
  _answer: {
   get() {
    return this.answer
   },
   set(value) {
    this.$emit('input', value)
   }
  },
  _visible: {
   get() {
    return this.visible
   },
   set(value) {
    this.$emit('update:visible', value)
   }
  }
 }
}
</script>

写一两个组件还好,组件规模一旦扩大,写双向绑定真能写出毛病来。于是,为了解放生产力,有了 vue-better-sync 这个轮子,且看用它如何改造我们的 Prompt 组件:

<template>
 <div v-show="actualVisible">
  <div>完善个人信息</div>
  <div>
   <div>尊姓大名?</div>
   <input v-model="actualAnswer" />
  </div>
  <div>
   <button @click="syncVisible(!actualVisible)">确认</button>
   <button @click="syncVisible(!actualVisible)">取消</button>
  </div>
 </div>
</template>
<script>
import VueBetterSync from 'vue-better-sync'
export default {
 name: 'prompt',
 mixins: [
  VueBetterSync({
   prop: 'answer', // 设置 v-model 的 prop
   event: 'input' // 设置 v-model 的 event
  })
 ],
 props: {
  answer: String,
  visible: {
   type: Boolean,
   sync: true // visible 属性可用 .sync 双向绑定
  }
 }
}
</script>

vue-better-sync 统一了 v-model 和 .sync 传递数据的方式,你只需 this.actual${PropName} = newValue 或者 this.sync${PropName}(newValue) 即可将新数据传递给父组件。

GitHub: fjc0k/vue-better-sync

总结

以上所述是小编给大家介绍的Vue 实现双向绑定的四种方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JQuery 学习笔记 选择器之四
Jul 23 Javascript
JS 日期比较大小的简单实例
Jan 13 Javascript
javascript实现倒计时(精确到秒)
Jun 26 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
简单理解vue中Props属性
Oct 27 Javascript
JS简单实现数组去重的方法示例
Mar 27 Javascript
vue.js移动端app之上拉加载以及下拉刷新实战
Sep 11 Javascript
EasyUI实现下拉框多选功能
Nov 07 Javascript
从零开始搭建webpack+react开发环境的详细步骤
May 18 Javascript
使用easyui从servlet传递json数据到前端页面的两种方法
Sep 05 Javascript
vue 验证两次输入的密码是否一致的方法示例
Sep 29 Javascript
JavaScript实现瀑布流布局的3种方式
Dec 27 Javascript
p5.js入门教程之鼠标交互的示例
Mar 16 #Javascript
JS匿名函数和匿名自执行函数概念与用法分析
Mar 16 #Javascript
解决npm管理员身份install时出现权限的问题
Mar 16 #Javascript
vue-router相关基础知识及工作原理
Mar 16 #Javascript
axios post提交formdata的实例
Mar 16 #Javascript
在vue组件中使用axios的方法
Mar 16 #Javascript
axios发送post请求,提交图片类型表单数据方法
Mar 16 #Javascript
You might like
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
JSON PHP中,Json字符串反序列化成对象/数组的方法
2018/05/31 PHP
PHP创建对象的六种方式实例总结
2019/06/27 PHP
js编码之encodeURIComponent使用介绍(asp,php)
2012/03/01 Javascript
使用jquery局部刷新(jquery.load)从数据库取出数据
2014/01/22 Javascript
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
js中用window.open()打开多个窗口的name问题
2014/03/13 Javascript
使用ngView配合AngularJS应用实现动画效果的方法
2015/06/19 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
微信开发 消息推送实现代码
2016/10/21 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
2018/09/14 Javascript
利用jsonp解决js读取本地json跨域的问题
2018/12/11 Javascript
浅谈编码,解码,乱码的问题
2016/12/30 Python
Django卸载之后重新安装的方法
2017/03/15 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
python线程信号量semaphore使用解析
2019/11/30 Python
Python如何把多个PDF文件合并代码实例
2020/02/13 Python
python 线程的五个状态
2020/09/22 Python
conda安装tensorflow和conda常用命令小结
2021/02/20 Python
html5 application cache遇到的严重问题
2012/12/26 HTML / CSS
努比亚手机官网:nubia
2016/10/06 全球购物
俄罗斯美容和健康网上商店:Созвездие Красоты
2019/07/23 全球购物
一套带答案的C++笔试题
2014/01/10 面试题
大专毕业生简历的自我评价
2013/10/20 职场文书
新闻学专业大学生职业生涯规划范文
2014/03/02 职场文书
项目备案申请报告
2015/05/15 职场文书
2015年社区宣传工作总结
2015/05/20 职场文书
消防安全培训工作总结
2015/10/23 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书
检讨书格式
2019/04/25 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
CSS使用Flex和Grid布局实现3D骰子
2022/08/05 HTML / CSS