自定义组件、组件之间传值
说到自定义组件,我们先来了解下什么是组件。组件组件传值组件组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。使用组件想要使用组件,就需要先注册一个组件。而组件又分为全局组件和局部组...
说到自定义组件,我们先来了解下什么是组件。
组件
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
使用组件
想要使用组件,就需要先注册一个组件。而组件又分为全局组件和局部组件。
全局注册
到目前为止,我们只用过 Vue.component
来创建组件:
Vue.component('my-component-name', {
// ... 选项 ...
})
这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:
Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })
new Vue({ el: '#app' })
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。
局部注册
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 components 选项中定义你想要使用的组件:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。
注意局部注册的组件在其子组件中不可用。
data必须是一个函数
当我们定义这个 <button-counter>
组件时,你可能会发现它的 data
并不是像这样直接提供一个对象:
data: {
count: 0
}
取而代之的是,一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
如果 Vue 没有这条规则,点击一个按钮就可能会影响到其它所有实例,即点击一个按钮,其它按钮出现同样的效果。
Prop
Prop类型
到这里,我们只看到了以字符串数组形式列出的 prop:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
这不仅为你的组件提供了文档,还会在它们遇到错误的类型时从浏览器的 JavaScript 控制台提示用户。
Prop验证
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
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 ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
template
template属性
template组件的模板html,属性值拼接字符串
template中可以调用简单的可以直接返回的一元运算符,并且能直接返回数据的,也可以调用js的全局方法比如,Date.now(),但是不能调用自己在全局定义的变量
template标签
template标签,HTML5提供的新标签,更加规范和语义化 ;
可以把列表项放入template标签中,然后进行批量渲染;
在vue中template节点在html生成的时候不会显示出来 ;
可以使用v-for把想要多次出现的内容重复出现,却不会出现<template></template>
标签。
<template v-for="i in 5">
<h5>我是一个h5标签</h5>
<p>我是一个p标签</p>
</template>
组件传值
对于组件传值,有父组件向子组件传值、子组件向父组件传值、非相关组件之间传值。
1. 父组件向子组件传值
父组件向子组件传值 ,使用props
父组件部分:Parent.vue
<template>
<div>
<ul>
<li v-for="(item,index) in nameList" :key="index">{{item.name}}</li>
</ul>
</div>
</template>
<script>
export default {
props: ["nameList"]
};
</script>
2. 子组件向父组件传值
子组件向父组件传值 ,使用事件派发
($emit)
父组件部分:Parent.vue
<template>
<div>
<div>这是父组件</div>
<child :name-list='names' @emitData='getData'></child>
</div>
</template>
<script>
import child from './child.vue'
export default {
components:{
child
},
data(){
return{
names:[
{name:'柯南'},
{name:'小兰'},
{name:'工藤新一'}
]
}
},
methods:{
getData(data){
console.log(data); //123
}
}
}
</script>
子组件部分:Child.vue
<template>
<div>
<ul>
<li v-for='(item,index) in nameList' :key='index'>{{item.name}}</li>
</ul>
<Button @click='toParent'>点击我</Button>
</div>
</template>
<script>
export default {
props:['nameList'],
methods:{
toParent(){
this.$emit('emitData',123)
}
}
}
</script>
3. 非相关组件之间传值
非相关组件之间传值,使用事件总线
(Bus)
如何实现非父子组件间的通信,可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,之后通过分别调用Bus事件触发和监听来实现组件之间的通信和参数传递。
首先需要在任意地方添加一个bus.js
import Vue from 'vue'
export default new Vue;
在需要通信的组件都引入Bus.js
如果你的bus.js是自定义一个bus的文件那from后面就改成你的所放的位置
import Bus from './bus.js'
接下来就是要组件通信了
添加一个 触发 #emit的事件按钮
<template>
<div id="emit">
<button @click="bus">按钮</button>
</div>
</template>
import Bus from './bus.js'
export default {
data() {
return {
message: ''"
}
},
methods: {
bus () {
Bus.$emit('msg', '我要传给兄弟们组件,你收到没有')
}
}
}
打开要和$emit
通信的另外一个组件 添加
import Bus from './bus.js'
在钩子函数中监听msg
事件
<template>
<div id="on">
<p>{{message}}</p>
</div>
</template>
import Bus from './bus.js'
export default {
data() {
return {
message: ''
}
},
mounted() {
let self = this
Bus.$on('msg', (e) => {
self.message = e
console.log(`传来的数据是:${e}`)
})
}
}
最后p
会显示来自$emit
传来的信息
更多推荐
所有评论(0)