Vue组件之props,$emit与$on以及slot分发
组件实例之间的作用域是孤立存在,要让它们之间的信息互通,就必须采用组件的通信方式
props用于父组件向子组件传达信息
1.静态方式
eg:
<body>
<div id="app">
<my-component message="hello"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<h1>{{message}}</h1>",
props:['message']
});
new Vue({
el: "#app",
});
</script>
</body>
props以数组的形式发出自己所需要的信息(至于父亲给不给,就由父亲说了算),父作用域给予回应,将message=‘hello’回应回去,儿子得到自己想要的,然后展现在html结构中;
2.动态获取数据
子组件要得到父亲口袋里面的东西(实例里面的数据),必须通过v-bind类似于绑定结构属性的方式发送给子组件;
eg:
<body>
<div id="app">
<my-component v-bind:message="message"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<div><h1 v-for='(val,key,index) in message'>{{val}}---{{key}}---{{index}}</h1></div>",
props:['message']
});
new Vue({
el: "#app",
data:{
message:{name:"zhangsan",sex:"man",job:"science"}
}
});
</script>
</body>
渲染结果为:
<div id="app">
<div>
<h1>zhangsan---name---0</h1>
<h1>man---sex---1</h1>
<h1>science---job---2</h1>
</div>
</div>
注意:在组件里面用v-for一定要写个外层标签包着v-for,因为大哥只能有一个,不能写并行标签
当然也可以传递方法给子组件
<body>
<div id="app">
<my-component v-bind:test="test"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<button @click='test'>{{btn}}</button>",
props:['test'],
data:function(){
return {
btn:"按钮"
}
}
});
new Vue({
el: "#app",
methods:{
test:function(){
alert(1)
}
}
});
</script>
</body>
如果传递过来的方法中带有父组件里面的属性,也可以用
eg:
<body>
<div id="app">
<my-component v-bind:test="test"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<button @click='test'>{{btn}}</button>",
props:['test'],
data:function(){
return {
btn:"按钮"
}
}
});
new Vue({
el: "#app",
data:{
message:"hello,world"
},
methods:{
test:function(){
alert(this.message)
}
}
});
</script>
</body>
弹出框显示hello, world
由此我们可以得出:父组件传递给子组件的是一个引用地址,但是这个引用是单向的,只能父组件改变的时候子组件获得的信息也会发生变化,但是子组件不可以去更改父组件传递过来的值,但是可以去加工
eg:
<body>
<div id="app">
<my-component v-bind:message="message"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<button @click='f'>{{btn}}</button>",
props:['message'],
data:function(){
return {
btn:"按钮"
}
},
methods:{
f:function(){
alert(this.message+" "+"i am god")
}
}
});
new Vue({
el: "#app",
data:{
message:"hello,world"
}
});
</script>
</body>
弹出框显示:hello,world i am god
eg:
<body>
<div id="app">
<input type="text" v-model="message">
<my-component v-bind:message="message"></my-component>
</div>
<script>
Vue.component('my-component', {
template: "<div><button @click='reverse'>{{btn}}</button><h1>{{message1}}</h1></div>",
props: ['message'],
data: function () {
return {
message1: "",
btn: "反转"
}
},
methods: {
reverse: function () {
this.message1 = this.message.split('').reverse().join('')
}
}
});
new Vue({
el: "#app",
data: {
message: "我爱北京"
}
});
</script>
</body>
显示结果:
props可以用来规定自己需要的数据类型,此时props将需求以对象的形式呈现,儿子开始挑剔了,但是父亲给他的不符合要求时候,它便会报错,但是毕竟是父亲给的,所以还是会渲染出来
eg:
<body>
<div id="app">
<my-component v-bind:message="message"></my-component>
</div>
<script>
Vue.component('my-component',{
template:"<h1>{{message}}</h1>",
props:{message:Number}, });
new Vue({
el: "#app",
data:{
message:"hello,world"
}
});
</script>
</body>
显示结果:
关于儿子组件的具体挑剔要求,我直接引个官网文档,就不做过多说明了
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
$emit与$on,关于这一对兄弟,接触过angular.js和react的应该都很熟悉,$emit是发射的意思,$on 为监听,主要用于子组件向父组件传递信号,当然,儿子广播出去,父亲听不听就是父亲的事情了
eg:
<body>
<div id="app">
<h1>{{a}}</h1>
<my-component v-on:ok="add"></my-component>
</div>
<script>
Vue.component('my-component', {
template: "<button @click='add1'>{{btn}}</button>",
data:function(){
return {
i:10,
btn:"点击"
}
},
methods:{
add1:function(){
this.i++;
this.$emit("ok")
}
} });
new Vue({
el: "#app",
data: {
a:0
},
methods:{
add:function(){
this.a++
}
}
});
</script>
</body>
显示如下:
父亲在监控ok,每当听到儿子通过$emit发送过来ok时候,父亲就开始执行自己的add方法
当然儿子也可以向父亲传递信息过去
eg:
<body>
<div id="app">
<h1>{{a}}</h1>
<my-component v-on:ok="add"></my-component>
</div>
<script>
Vue.component('my-component', {
template: "<button @click='add1'>{{btn}}</button>",
data:function(){
return {
i:10,
btn:"点击"
}
},
methods:{
add1:function(){
this.i++;
this.$emit("ok",this.i)
}
}
});
new Vue({
el: "#app",
data: {
a:0
},
methods:{
add:function(e){
this.a=e
}
}
});
</script>
</body>
显示效果:
儿子将自己的i值传递给父亲,父亲通过接收到的i值将自己的a值更改
监听原生事件的时候,父亲只需要在自己的监听器上加一个炫酷特效.native,儿子不需要去发广播,父亲就会知道,也就是说有些事情只要老爸愿意了解,不需要儿子去告诉,他自己也可以选择知道
eg:
<body>
<div id="app">
<h1>{{a}}</h1>
<my-component v-on:click.native="add"></my-component>
</div>
<script>
Vue.component('my-component', {
template: "<div><button @click='add1'>{{btn1}}</button><button @click='add2'>{{btn2}}</button></div>",
data:function(){
return {
i:10,
btn1:"点击1",
btn2:"点击2"
}
},
methods:{
add1:function(){
this.i++; },
add2:function(){
this.i--
}
} });
new Vue({
el: "#app",
data: {
a:0
},
methods:{
add:function(){
this.a++
}
}
});
</script>
</body>
显示结果:
除了父子直接可以互相通信外,子组件直接互相通信,需要一个子组件先将信息传递给父组件,父组件再交给另一个子组件
eg:
<body>
<div id="app">
<h1>我是父亲且a为:{{a}}</h1>
<child1 v-on:ok="add"></child1>
<child2 v-bind:m="a"></child2>
</div>
<script>
Vue.component('child1', {
template: "<div><h1>我是儿子1号且i为:{{i}}</h1><button @click='go'>点击传值</button></div>",
data:function(){
return {
i:100
}
},
methods:{
go:function(){
this.i+=100;
this.$emit("ok",this.i)
}
}
});
Vue.component('child2',{
template:"<h2>我是儿子2号且m:{{m}}</h2>",
props:['m']
});
new Vue({
el: "#app",
data: {
a:0
},
methods:{
add:function(e){
this.a=e
}
}
});
</script>
</body>
显示结果为:
slot分发模式主要用于在组件中间插入标签或者组件之间的相互嵌套
单个内容插入,可以选择用slot标签事先占个位置
eg:
<body>
<div id="app">
<child><span>slot分发</span></child>
</div>
<script>
Vue.component('child', {
template: "<h3>{{message}}<slot></slot></h3>",
data:function(){
return {
message:"我就是:"
}
}
});
new Vue({
el: "#app",
});
</script>
</body>
渲染结果为:
<div id="app">
<h3>我就是:<span>slot分发</span></h3>
</div>
也就是说slot类似于一个插槽,提前站好一个位置,要插入组件中的标签类似于卡,插入提前站好位置的插槽中
多个标签插入,就需要按照名字一一对号入座
eg:
<body>
<div id="app">
<child>
<h1 slot="card1">我是1号卡片</h1>
<h1 slot="card2">我是2号卡片</h1>
<h1 slot="card3">我是3号卡片</h1>
</child>
</div>
<script>
Vue.component('child', {
template: "<div>{{message}}" +
"<p>hello world</p>"+
"<slot name='card1'></slot>" +
"<slot name='card2'></slot>" +
"<slot name='card3'></slot>" +
"</div>",
data:function(){
return {
message:"多个卡片插入:"
}
}
});
new Vue({
el: "#app",
});
</script>
</body>
渲染结果为:
作用域插槽还是有点抽象的,也就是子组件充当插槽,父组件将内容插在子组件上面,并且子组件将值传递给父组件,父组件用scope="props"来接收子组件传过来的值
<body>
<div id="app">
<parent></parent>
</div>
<script>
Vue.component("son",{
template:"<ul><slot name='ww' v-for='item in items' v-bind:text='item.name'></slot></ul>",
data:function(){
return{items:[{name:'张三'},{name:'李四'},{name:"王五"}]
}
}
});
Vue.component("parent",{
template:"<son>" +
"<template scope='props' slot='ww'>" +
"<li>{{props.text}}</li>" +
"</template>" +
"</son>"
});
new Vue({
el:"#app",
})
</script>
</body>
渲染结果为:
eg:
<body>
<div id="app">
<dad></dad>
</div>
<script>
Vue.component('child', {
template:"<h3><slot :content='m' name='son'></slot></h3>",
data:function(){
return{
m:"我是子组件传过去的"
}
}
});
Vue.component("dad",{
template:"<child><template scope='props' slot='son'><p>{{props.content}}</p></template></child>"
});
new Vue({
el: "#app",
});
</script>
</body>
渲染结果:
动态组件通过component来动态切换组件的内容
eg:
<body>
<div id="app">
<button @click="add1">样式1</button>
<button @click="add2">样式2</button>
<button @click="add3">样式3</button><br>
<component :is="m"></component>
</div>
<script>
Vue.component("child",{
template:"<div><button v-for='(val,key) in item' @click='key'>{{val}}</button></div>",
data:function(){
return{
item:{add1:"样式1",add2:"样式2",add3:"样式3"}
}
}
});
var a1={template:"<h1><i style='color:red'>我是a1</i></h1>"};
var a2={template:"<h1><b style='color:green'>我是a2</b></h1>"};
var a3={template:"<h1><del style='color:blue'>我是a3</del></h1>"};
new Vue({
el: "#app",
data:{
m:"a1"
},
components:{
a1:a1,
a2:a2,
a3:a3
},
methods:{
add1:function(){
this.m='a1'
},
add2:function(){
this.m='a2'
},
add3:function(){
this.m='a3'
}
}
});
</script>
</body>
渲染结果为:
Vue组件之props,$emit与$on以及slot分发的更多相关文章
- vue组件详解(四)——使用slot分发内容
一.什么是slot 在使用组件时,我们常常要像这样组合它们: <app> <app-header></app-header> <app-footer>& ...
- Vue组件选项props
前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props ...
- 【转存】Vue组件选项props
原帖地址 前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 ...
- vue组件的props
刚开始学习vue组件的时候经常被 props这个传值搞晕,做个笔记 Vue.component('item', { template: '#item-template', props: { model ...
- 第七十二篇:Vue组件的props
好家伙, 1.组件的props props是组件的自定义属性,在封装通用组件的时候,合理的使用props可以极大的提高组件的复用性 来假设一下,如果我们需要两个组件分别显示不同的值 目录结构如下: H ...
- Vue 组件通信的多种方式(props、$ref、$emit、$attr、 $listeners)
prop和$ref之间的区别: prop 着重于数据的传递,它并不能调用子组件里的属性和方法.像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用prop. $ref 着重于索引,主要用来调用 ...
- vue组件之属性Props
组件的属性和事件 父子组件之间的通信 父子组件之间的通信就是 props down,events up,父组件通过 属性props向下传递数据给子组件,子组件通过 事件events 给父组件发送消息. ...
- vue组件通信(props,$emit,$attrs,$listeners)
朝颜陌 vue基础----组件通信(props,$emit,$attrs,$listeners) 一.父传子,子传孙 1. props 1>在父组件中通过子组件自定义的标签属性来传递数据. ...
- vue组件
分享出来让思路更成熟. 首先组件是 Vue.js 最强大的功能之一. 可以减少很多的工作量,提高工作效率. 编写一个可复用性的组件,虽然官网上也有.... 编写可复用性的vue组件 具备一下的几个要求 ...
随机推荐
- ACM.hdu1025
to get the ans of how many roads at most that can be built between two line without intersection of ...
- 深入探析 Rational AppScan Standard Edition 多步骤操作
序言 IBM Rational AppScan Standard(下文简称 AppScan)作为面向 Web 应用安全黑盒检测的自动化工具,得到业界的广泛认可和应用.很多人使用 AppScan 时都采 ...
- 配置静态服务器和配置nfs
一.配置Nginx 1.安装Nginx yum -y install nginx 2.编写配置文件 [root@ngix nginx]# cd /etc/nginx [root@ngix nginx] ...
- 51Nod 1087 1 10 100 1000 | 数学
Input示例 3 1 2 3 Output示例 1 1 0 #include "bits/stdc++.h" using namespace std; #define LL lo ...
- Doc常用命令
1. 获取目录: dir 2. 清屏: cls
- WordPress在nginx服务器伪静态
server { listen 80; root /var/www/xxx; server_name www.xxx.com; access_log /var/log/www/xxx.log main ...
- 【设计模式】享元模式(Flyweight)
摘要: 1.本文将详细介绍享元模式的原理和实际代码中特别是Android系统代码中的应用. 纲要: 1. 引入享元模式 2. 享元模式的概念及优缺点介绍 3. 享元模式在Android源码中的应用 1 ...
- rdpClient
https://github.com/jean343/RPI-GPU-rdpClient https://github.com/Nullstr1ng/MultiRDPClient.NET https: ...
- 剑指offer-高质量的代码
小结: 规范性:书写清晰.布局清晰.命名合理 完整性:完成基本功能.考虑边界条件.做好错误处理 鲁棒性:采取防御性编程.处理无效输入 面试这需要关注 输入参数的检查 错误处理和异常的方式(3种) 命名 ...
- BZOJ 3771 生成函数,FFT
Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看:“是啊是啊!” 水神把斧头扔在一 ...