定义全局组件
方式一:
var com1 = Vue.extend({
template: '<h3>定义组件h3</h3>'
})
Vue.component('myCom1', com1)
方式二:
Vue.component('myCom1',Vue.extend({
template:'<h3>定义组件h3</h3>>'
}))
如果使用
Vue.component
定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接;
方式二简写(可省略 Vue.extend
):
Vue.component('mycom2', {
template:'<div><h3>定义组件h3</h3><span>123</span>
</div>'
})
组件必须有且只有一个根元素
方式三:
//template 是 vue 提供的,在 被控制的 #app 外面,使用 template
元素,定义组件的HTML模板结构
<template id="tmpl">
<div>
<h1>这是h1</h1>
<h4>这是h4</h4>
</div>
</template>
//script 标签中定义
Vue.component('mycom3', {
template: '#tmpl'
})
定义私有组件
<div>
<template id="tmpl2">
<h1>私有组件</h1>
</template>
</div>
<script>
var vm2 = new Vue({
el: '#app',
components: { // 定义实例内部私有组件的
login: {
template: '#tmpl2'
}
},
})
</script>
组件中的 data 和 methods
组件中的 data 和 实例中的 data 不一样,实例中的 data 可以是对象,但组件中的 data必须是一个方法,且方法必须返回一个对象,而使用方式二者一样。
Vue.component('mycom1', {
template: '<h1>h1组件--{{msg}}</h1>',
data: function () {
return {
msg: '这是组件的中data定义的数据'
}
}
})
为什么组件中的 data 属性必须定义为一个方法并返回一个对象?
因为组件可能被用来创建多个实例,如果 data 是一个纯粹的对象,则所有实例将共享引用同一个数据对象,而通过将 data 属性定义为一个方法并返回一个对象,可以实现每创建一个实例,调用 data 函数,从而返回一个初始数据的全新副本数据对象
组件切换
方式一:flag 标识符结合 v-if 和 v-else
<div id="app">
<a href="" @click.prevent="flag=true">登录</a>
<a href="" @click.prevent="flag=false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
flag: false
},
});
</script>
利用以上方式进行组件切换的缺点:只能进行两个组件间的切换
方式二:is 属性
<div id="app">
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册
</a>
//component 是 vue 提供的,一个占位符
//:is 可以用来指定要展示的组件名称
<component :is="comName"></component>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
// 当前 component 中的 :is 绑定的组件的名称
comName: 'login'
},
});
</script>
组件切换动画
<transition mode="out-in">
<component :is="comName"></component>
</transition>
mode 属性设置切换模式,避免一个组件还未完全消失,另一个组件就进来的情况
父组件向子组件传值
子组件默认无法访问父组件的 data 和 methods,那么父组件如何向子组件传值?
传递 data
父组件在引用子组件的时候,通过属性绑定(v-bind:)的形式,进行父组件向子组件的数据传递,父组件传递的属性,需要在子组件的 props 数组中定义一下,才可使用
<div id="app">
<com1 :parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123 啊-父组件中的数据'
},
methods: {},
components: {
//子组件
com1: {
data() {
return {
title: '123',
content: 'qqq'
}
},
template: '<h3>子组件{{ parentmsg }</h3>',
props: ['parentmsg'],
}
}
});
</script>
组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的,props 中的数据,都是只读的,无法重新赋值
传递 methods
父组件向子组件传递方法,使用事件绑定机制(v-on) ,自定义一个事件属性后,子组件就可以调用父组件的这个方法了,并且可以通过参数传递的方法,向父组件传递子组件的私有数据 data
<div id="app">
<com2 @fun="show"></com2>
</div>
<template id="tmpl">
<div>
<h1>这是 子组件</h1>
<input type="button" value="子组件按钮,点击,触发父
组件 fun 方法" @click="myclick">
</div>
</template>
<script>
// 定义组件模板对象
var com2 = {
template: '#tmpl',
data() {
return {
sonmsg: { name: '小头儿子', age: 6 }
}
},
methods: {
myclick() {
//emit 原意:触发,调用,发射
this.$emit('fun', this.sonmsg)
}
}
}
var vm = new Vue({
el: '#app',
data: {
datamsgFormSon: null
},
methods: {
show(data) {
this.datamsgFormSon = data
}
},
components: {
com2
}
});
</script>
子组件向父组件传值
在父组件向子组件传递 methods时,子组件调用父组件方法,向父组件传递其私有数据 data,实现了子组件向父组件传值,案例如上