一、基本概念
-
组件(Component)的概念:组件即自定义控件(标签)
-
组件的用途:组件能够封装可重用代码,扩展HTML标签功能
-
组件的本质:是带有名称的可复用实例,可以接受相同的选项对象(除了一些根级特有的选项),提供相同的生命周期钩子
-
vue组件的功能
-
能够把页面抽象成多个相对独立的模块
-
实现代码重用,提高开发效率和代码质量,使得代码易于维护
-
-
组件的分类:
-
全局组件:不同作用域内均可使用
-
局部组件:只在定义该组件的作用域内可以使用
-
二、Vue组件封装过程
-
创建一个组件(示例具体说明)
-
注册组件
-
使用组件
三、注册组件
常用的全局及局部组件的注册代码
<script src="js/vue.js"></script>
<body>
<div id="app">
<global-button></global-button>
<local-button></local-button>
</div>
<template id="test1">
<button>我是一个全局按钮组件</button>
</template>
<template id="test2">
<button>我是一个局部按钮组件</button>
</template>
<script>
Vue.component("GlobalButton", {
template: "#test1"
})
var vm = new Vue({
el: "#app",
data: {},
components: {
"LocalButton": {
template: "#test2"
}
},
})
</script>
</body>
</html>
四、组件中使用数据
1、数据使用
<body>
<script src="js/vue.js"></script>
<div id="app">
<global-div></global-div>
<local-div></local-div>
</div>
<template id="t1">
<div>{{msg}}</div>
</template>
<template id="t2">
<div>{{msg}}</div>
</template>
<script>
//全局组件
Vue.component("GlobalDiv", {
template: "#t1",
data() {
return {
msg: "tom"
}
},
})
var vm = new Vue({
el: "#app",
data: {},
// 局部组件
components: {
"LocalDiv": {
template: "#t2",
data() {
return {
msg: "tom2"
}
},
}
}
})
</script>
</body>
</html>
2、组件定义
直接使用标签
<body>
<script src="js/vue.js"></script>
<div id="app">
<table>
<row></row>
</table>
</div>
<template id="t1">
<tr>
<td>{{name}}</td>
<td>{{age}}</td>
</tr>
</template>
<script>
Vue.component("row", {
template: "#t1",
data() {
return {
name: "tom",
age: 20
}
},
})
var vm = new Vue({
el: "#app",
data: {},
})
</script>
</body>
</html>
ol、ul、select的子标签、表格tr中使用is属性来引用
<body>
<script src="js/vue.js"></script>
<div id="app">
<table>
<tr is="row"></tr>
</table>
</div>
<template id="t1">
<tr>
<td>{{name}}</td>
<td>{{age}}</td>
</tr>
</template>
<script>
Vue.component("row", {
template: "#t1",
data() {
return {
name: "tom",
age: 20
}
},
})
var vm = new Vue({
el: "#app",
data: {},
})
</script>
</body>
</html>
五、父子组件
1、父子组件的创建
创建单个子组件
<body>
<script src="js/vue.js"></script>
<div id="app">
<lesson-item></lesson-item>
</div>
<!-- 子组件内容 -->
<template id="lessonItemTemplate">
<div style="float: left; margin-left: 20px;">
<img :src="src" />
<h3>{{course}}</h3>
<div>
<a href="#">{{desc}}</a>
</div>
</div>
</template>
<script>
var vm = new Vue({
el: "#app",
data: {},
components: {
"LessonItem": {
template: "#lessonItemTemplate",
data() {
return {
course: "java",
src: "vue.png",
desc:"java 很好学"
}
},
}
}
})
</script>
</body>
</html>
创建父组件
<script src="js/vue.js"></script>
<body>
<div id="app">
<lession-list></lession-list>
</div>
<!-- 父组件对应的代码,注意只能template只能有一个根元素,所以要加上div -->
<template id="LessionListTemplate">
<div>
<!-- 对应的子组件 -->
<lesstion-item></lesstion-item>
<lesstion-item></lesstion-item>
<lesstion-item></lesstion-item>
</div>
</template>
<!-- 子组件内容 -->
<template id="lessonItemTemplate">
<div style="float: left; margin-left: 20px;">
<img :src="src" />
<h3>{{course}}</h3>
<div>
<a href="#">{{desc}}</a>
</div>
</div>
</template>
<script>
var vm = new Vue({
el: "#app",
data: {},
components: {
"lessionList": {
template: "#LessionListTemplate",
components: {
"lesstionItem": {
template: "#lessonItemTemplate",
data() {
return {
course: 'vue',
src:"vue.png",
desc:"java 很好学"
}
},
}
}
}
},
})
</script>
</body>
</html>
2、父组件给子组件传值(使用props传递数据(父组件向子组件传值-正向传值)子组件用props接收值 )
第一步:在父组件中使用属性传递值
<组件 属性名称1=‘属性值1’ 属性名称2=‘属性值2’></组件>
第二步:在子组件中使用属性名称进行值的接收
components: {
'组件名称': {
template: '#模板ID',
props: ['属性名称1', '属性名称2', ...]
}
}
eg:
<script src="js/vue.js"></script>
<body>
<div id="app">
<lession-list></lession-list>
</div>
<!-- 父组件对应的代码,注意只能template只能有一个根元素,所以要加上div -->
<template id="LessionListTemplate">
<div>
<!-- 对应的子组件 -->
<lesstion-item course="java基础" desc="java" src="java.png"></lesstion-item>
<lesstion-item course="MySql入门" desc="mysql" src="mysql.png"></lesstion-item>
<lesstion-item course="Vue入门" desc="vue" src="vue.png"></lesstion-item>
</div>
</template>
<!-- 子组件内容 -->
<template id="lessonItemTemplate">
<div style="float: left; margin-left: 20px;">
<img :src="src" />
<h3>{{course}}</h3>
<div>
<a href="#">{{desc}}</a>
</div>
</div>
</template>
<script>
var vm = new Vue({
el: "#app",
data: { },
components: {
"lessionList": {
template: "#LessionListTemplate",
components: {
"lesstionItem": {
template: "#lessonItemTemplate",
props: ["course", "desc", "src"]
}
}
}
},
})
</script>
</body>
</html>
改造:
<script src="js/vue.js"></script>
<body>
<!-- 根组件 -->
<div id="app">
<!-- 子组件 -->
<lession-list :info="info"></lession-list>
</div>
<!-- 父组件对应的代码,注意只能template只能有一个根元素,所以要加上div -->
<template id="LessionListTemplate">
<div>
<!-- 对应的子组件 -->
<lesstion-item :course="item.course" :desc="item.desc" :src="item.src" v-for="(item, index) in courseList" :key="index"></lesstion-item>
<p>{{info}}</p>
</div>
</template>
<!-- 子组件内容 -->
<template id="lessonItemTemplate">
<div style="float: left; margin-left: 20px;">
<img :src="src" />
<h3>{{course}}</h3>
<div>
<a href="#">{{desc}}</a>
</div>
</div>
</template>
<script>
var vm = new Vue({
el: "#app",
data: {
info:"hello1"
},
components: {
"lessionList": {
template: "#LessionListTemplate",
props:["info"],
data() {
return {
courseList:[
{course:"java基础",desc:"java",src:"java.png"},
{course:"MySql入门",desc:"mysql",src:"mysql.png"},
{course:"Vue基础",desc:"vue",src:"vue.png"},
]
}
},
components: {
"lesstionItem": {
template: "#lessonItemTemplate",
props: ["course", "desc", "src"]
}
}
}
},
})
</script>
</body>
</html>
props特性和非props特性
props特性:父组件借助于属性给子组件传递值,子组件使用props属性进行接收,接收到之后可以在子组件中使用,并且属性不会在dom结构中出现
非props特性:父组件借助于属性给子组件传递值,子组件不进行接收,在子组件中也不能使用,但是属性会出现在dom结构中,父组件传了,子组件没有接收
3、子组件给父组件传值
this.$emit('event',val)
eg:
<body>
<script src="js/vue.js"></script>
<div id="app">
<!-- 3、第二步触发的自定义事件需要绑定一个函数,这个函数是父组件中定义的函数-->
<my-button @change1="handlerChange"></my-button>
<my-button @change1="handlerChange"></my-button>
<div>一共点了{{total}}</div>
</div>
<template id="ch1">
<!-- 1、考虑清楚什么时候传值,比如再单击子组件的某个标记的时候 -->
<button @click="handlerClick">你点击了{{num}}</button>
</template>
<script>
var vm = new Vue({
el: "#app",
data: {
total: 0
},
methods: {
// 4、在该函数中就可以接收子组件传递的数据num
handlerChange(num) {
this.total = this.total + num;
}
},
components: {
"myButton": {
template: "#ch1",
data() {
return {
num: 0
}
},
methods: {
handlerClick() {
this.num = this.num + 1;
// 2、在事件处理函数中使用emit触发自定义事件,在emit中可以传递数据(参数的形式)
//注意事件名称不能使用驼峰式命名,不然找不到事件
// $代表挂载在this上的vue内部属性
this.$emit('change1', 1)
}
},
}
}
})
</script>
</body>
</html>
4、组件的原生事件的绑定(事件.native)