Vue中v-model解析、sync修饰符解析
上善若水,水善利萬物而不爭。——《道德經》
简介 在平时开发是经常用到一些父子组件通信,经常用到props、vuex等等,这里面记录另外的三种方式v-model、sync是怎么使用,再说是怎么实现,其实v-model、sync都是语法糖。还有$attr、$listener实现父子组件通信。
使用方式
v-model 2.2.0+ 新增 v-mode1其实就是一个语法糖,默认会利用名为value的props和名为input的事件,但是像单选框、复选框等类型的输入龙剑可能会讲value特性用于不同的目的。 v-model的使用场景:当子组件需要改变父组件通过props传入的值 父组件 父组件通过v-model绑定值
如需根据v-model传入的值改变,而触发其他更新请通过watch传入的值 子组件 声明model对象 设置事件event和prop字段
通过porps接受父组件传送值
修改是通过this.$emit广播事件 代码示例: 父组件代码 <template>
<children v-model="message"></children>
</template>
<script>
import children from "./children.vue";
export default {
components: {
children
},
data() {
return {
message: "parent"
};
},
watch: {
// 监听message变化
message(newV, oldV) {
console.log(newV, oldV);
}
}
};
</script> 子组件代码 <template>
<h1>{{ message }}</h1>
</template>
<script>
export default {
model: {
prop: "message", //这个字段,是指父组件设置 v-model 时,将变量值传给子组件的 msg
event: "input" //这个字段,是指父组件监听 parent-event 事件
},
props: {
message: String //此处必须定义和model的prop相同的props,因为v-model会传值给子组件
},
mounted() {
//这里模拟异步将msg传到父组件v-model,实现双向控制
setTimeout(_ => {
this.$emit("input", "children");
//将这个值通过 emit 触发parent-event,将some传递给父组件的v-model绑定的变量
}, 1500);
}
};
</script> 上面这个示例是通过v-model实现的,下面不通过v-model实现同样效果。
不使用 v-model 实现 代码示例如下: 父组件代码修改 <template>
<Children :message="message" @input="(event) => { message = event }"/>
</template>
<script>
// 不变
</script> 子组件代码修改 <template>
// 不变
</template>
<script>
export default {
props: {
message: String
},
mounted() {
setTimeout(() => {
this.$emit("input", "children");
}, 1500);
}
};
</script> 只是把v-model拆分为props和@input事件,子组件不需要配置model,只需要接受props和通过this.$emit广播事件就可以。 当然这个相对于v-model方法比较简便,但是灵活度查很多,选择使用那种看个人喜好。 在线地址: 不能放iframe只能放一放一个链接了本篇代码实例
sync 2.3.0+ 新增 在有些情况下,我们可能需要对一个 prop 进行**“双向绑定”。不幸的是,真正的双向绑定**会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。 这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。同时也可以通过sync修饰符来实现。 在上面代码的基础上大致修改如下: 父组件 通过修改触发事件input为update:myPropName实现相同效果 子组件 通过修改this.$emit(update:myPropName) 代码如下: 父组件代码修改 // 修改如下
<Children :message="message" @update:input="(event) => { message = event }"/> 子组件代码修改 // 其他不变
this.$emit("update:input", "children"); sync实现 上面的代码可以通过sync简写为下面代码: 父组件代码修改 // 修改如下
<Children :messag.sync="message"/> 子组件代码修改 // 其他不变
this.$emit("update:messag", "children"); 同时sync也支持对象,要配合v-bind实现可以简写为:,但是要注意这个对象如下两条: 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的属性名,类似 v-model。 将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。 attrs、listeners
$attrs 2.4.0 新增 类型:{ [key: string]: string }
只读
详细: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。 $listeners 2.4.0 新增 类型:{ [key: string]: Function | Array<Function> }
只读
详细: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。 实现通信 实现父子组件通信 父组件代码 <template>
<div class="parent">
<Children
:message="message"
@upDate="upDate"
type="del"
@input="(event) => { message = event }"
/>
</div>
</template> <script>
import Children from "./Children";
export default {
components: {
Children
},
data() {
return {
message: "parent",
type: "del"
};
},
methods: {
upDate (event) {
console.log(event);
this.type = event;
}
},
watch: {
message: function() {
console.log("更新message值为" + this.message);
}
}
};
</script> 子组件代码 <template>
<div v-bind="$attrs" v-on="$listeners" class="children">{{message}} <span @click="$listeners.upDate('data')">{{$attrs.type}}</span></div>
</template> <script>
export default {
props: {
message: String
},
mounted() {
// console.log(this.$attrs);
// console.log(this.$listeners);
setTimeout(() => {
this.$emit("input", "children");
this.$emit('upDate', 'add')
}, 1500);
}
};
</script> 同时$attrs、$listeners都是可以跨域父子组件,可以父子子子组件传递,类似于react中的context,只是一部分设计理念相同。
总结 其实就是检测到.sync修饰符,在complier阶段会编译生成多个prop,生成多个事件。其实像这个指令、修饰符、自定义指令都是在vue编译是解析成为v8能执行的代码。 无论是vue、babel、react的complier编译阶段大致分为三个阶段: 通过词法解析parse生成抽象AST或抽象代码树
优化AST,比如vue标记静态节点,babal中抽取静态代码,这个阶段被称为optimize或者优化AST树
在AST代码的阶段上,生成可执行代码,这个过程可以叫做codegen v-model、sync都可以实现父子组件通信,并且可以在子组件中修改父组件传入的值。在平常看法的时候进场可以用到这两种方式,具体选择那种方式看个人喜好。在element-ui这个input组件也用到相关的属性。
Vue中v-model解析、sync修饰符解析的更多相关文章
- 043——VUE中组件之使用.sync修饰符与computed计算属性实现购物车原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- VUE组件3 数据流和.sync修饰符
单向数据流:数据通过prop从父组件传递到子组件中,当父级组件中的数据更新时,传子组件也会更新,但不能在子组件中修改.防止子组件在无意中修改,改变父级组件状态 然而,双向数据绑定在某些情况下有用.如果 ...
- Vue中v-model指令的常用修饰符
v-model指令有三个可以选用的修饰符:.lazy..number以及.trim.vue官方对此的描述为: .number-输入字符串转为有效的数字 .lazy-取代input监听change事件 ...
- 第六十二篇:Vue的双向绑定与按键修饰符
好家伙,依旧是vue的基础 1.按键修饰符 假设我们在一个<input>框中输入了12345,我们希望按一下"Esc" 然后删除所有前面输入的内容,这时候,我们会用到按 ...
- sync 修饰符在Vue中如何使用
在有些情况下,我们可能需要对一个 prop 进行"双向绑定".不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源. 这 ...
- vue中的.sync修饰符用法
在项目中接触到父组件传值给子组件的时候,想在子组件改变父组件传的值.(比如用于弹窗关闭) 但是正常来说,vue2是不允许子组件直接改父组件传进去的值的. 所以我们需要在子组件内定义自定义事件,通知父组 ...
- vue中.sync 修饰符
一直以来,都不太明白.sync的用法,归根结底原因在于,没有仔细阅读“.sync修饰符”. 正好,最近在拿一个项目练手,然后使用了elment-ui,然后在用到dialog的时候,属性visible是 ...
- vue 之 .sync 修饰符
在一些情况下,我们可能会需要对一个 prop (父子组件传递数据的属性) 进行“双向绑定”. 在vue 1.x 中的 .sync 修饰符所提供的功能.当一个子组件改变了一个带 .sync 的prop的 ...
- Vue sync修饰符的使用
父子组件传值,父组件可以给子组件传值,但是子组件是不能修改组件提供的值,这里vue提供了sync修饰符,以前父组件点击子组件显示,子组件关闭按钮,父组件再点击子组件就无法让子组件显示.因为子组件点击关 ...
随机推荐
- Nginx系列 | [转]Nginx 上传文件:client_max_body_size 、client_body_buffer_size
原文:http://php-note.com/article/detail/488 client_max_body_size client_max_body_size 默认 1M,表示 客户端请求服务 ...
- electron---项目打包
创建一个应用目录:app,里面需要有必要的三个文件: index.html <!DOCTYPE html> <html> <head> <meta chars ...
- Python分词工具——jieba
jieba简介 python在数据挖掘领域的使用越来越广泛.想要使用python做文本分析,分词是必不可少的一个环节在python的第三方包里,jieba应该算得上是分词领域的佼佼者. GitHub地 ...
- [译]使用BeautifulSoup和Python从网页中提取文本
如果您要花时间浏览网页,您可能遇到的一项任务就是从HTML中删除可见的文本内容. 如果您使用的是Python,我们可以使用BeautifulSoup来完成此任务. 设置提取 首先,我们需要获取一些HT ...
- IDEA 如何搭建maven 安装、下载、配置(图文)
1.下载 maven 压缩包 输入网址 www.apache.org 会看到以下界面 住下划看到以下界面 然后看到这个界面 选择下载这个版本 下载后 解压 maven 压缩包 (文件路径不建议用有中文 ...
- FromXml 支付回调 xml 转数组
public function xx(){ $xml = '<xml><appid><![CDATA[xxxxxxxxxxxxx]]></appid> ...
- 【miscellaneous】Winserver2012安装后无法进入桌面
原因分析: 自己操作卸载了.net framework,系统没有了图形界面(由完整模式Full变为了核心模式core),需要重新恢复.net framework4.5. 解决方法分析: 需要将核心模式 ...
- webpack打包完成,复制,打包,移动,删除已生成的文件插件
const FileManagerPlugin = require('filemanager-webpack-plugin'); 详情请到 https://www.npmjs.com/ 一看究竟 贴个 ...
- Influx Sql系列教程六:insert 修改数据
在influxdb中没有专门的修改数据的update语句,对于influxdb而言,如果想修改数据,还是得使用我们前面的说到的insert来实现,那么怎么判断一条insert语句是插入还是修改呢? 1 ...
- ATSC/DVB/ISDB三大标准比较
一.引言 众所周知,模拟电视有NTSC.PAL和SECAM三种标准.目前,数字电视也陷入这种局面,美国.欧洲和日本各自形成三种不同的数字电视标准.美国的标准是ATSC(Advanced Televi ...