组件化
为什么要使用组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在vue里,所有的vue实例都是组件
全局组件
在多个vue实例中都可以使用
案例:
<body>
<div id="app">
<test></test>
<test></test>
<test></test>
</div>
</body>
<script src="js/vue.js"></script>
<script>
//创建组件
const cpnc=Vue.extend({
template: `
<div>
<p>hello 组件</p>
</div>
`
});
//注册组件
Vue.component('test',cpnc)
var app=new Vue({
el: "#app",
data:{
},
});
</script>
简写
<body>
<div id="app">
<test></test>
<test></test>
<test></test>
</div>
</body>
<script src="js/vue.js"></script>
<script>
Vue.component("test",{
template: `
<div>
<p>hello 组件你好</p>
</div>
`
});
var app=new Vue({
el: "#app",
data:{
},
});
</script>
局部组件
只能在当前vue实例中使用,常用
实例:
<body>
<div id="app">
<test></test>
<test></test>
<test></test>
</div>
</body>
<script src="js/vue.js"></script>
<script>
const cpn=Vue.extend({
template: `
<div>
<p>hello vue局部组件</p>
</div>
`
});
var app=new Vue({
el: "#app",
data:{
},
//局部组件注册
components:{
test: cpn
}
});
</script>
模板分离写法
2.
组件内部不可以访问vue实例里面的数据
组件内部也可以有data属性,供给组件使用
为什么组件里的data要使用函数,当每次调用的时候,因为return返回的是新的对象的实例,对象之间互不干扰,组件复用时互不干扰
模板分离写法
<body>
<div id="app">
<test></test>
</div>
<template id="tem">
<p>{{title}}</p>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app=new Vue({
el: "#app",
components: {
test: {
template: `#tem`,
data() {
return {
title: "hello 组件"
}
}
}
}
});
</script>
父子组件通信
props数据验证
验证都支持哪些数据类型呢?
String
Number
Boolean
Array
Object
Date
Function
Symbol
父传子
<body>
<div id="app">
<test :meg="message"></test>
</div>
<template id="tem">
<div>
<p>{{meg}}</p>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app=new Vue({
el: "#app",
data:{
message:"你好啊"
},
components: {
test: {
template: `#tem`,
//定义在子类
props:{
// meg:String
meg:{
//如果是对象
/*type:Object
default:{
return {}
}*/
type:String,
default:"这是我的默认值",
//必传,不传报错
required:true
}
},
}
}
});
</script>
子传父
<body>
<div id="app">
<!-- 传给父类事件-->
<test @cbtn="pbtn"></test>
</div>
<template id="cpn">
<div>
<button v-for="item in category" @click="btnclick(item)">{{item}}</button>
</div>
</template>
<script src="js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
category: [
{id:'1',name:'张三',age:18},
{id:'2',name:'李四',age:19},
{id:'3',name:'王二',age:20},
{id:'4',name:'麻子',age:21}
]
}
},
methods: {
//发射事件
btnclick(item){
this.$emit('cbtn',item)
}
}
}
const app = new Vue({
el: '#app',
data: {
},
components:{
test:cpn
},
methods: {
pbtn(item){
alert(item.id+item.name+item.age);
}
}
})
</script>
</body>
父访问子组件
$refs
<body>
<div id="app">
//ref标记
<test ref="aaa"></test>
<button @click="getname">按钮</button>
</div>
<template id="tem">
<div>
<p>子组件</p>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
methods: {
getname() {
//取出对应的组件对象
alert(this.$refs.aaa.name)
}
},
components: {
test: {
template: `#tem`,
props: {},
data() {
return {
name: '张三'
}
}
}
}
});
</script>
插槽slot
预留空间,方便扩展
<body>
<div id="app">
<test>
<button>按钮</button>
</test>
<test><input placeholder="我是输入框"></test>
<test></test>
</div>
<template id="tem">
<div>
<p>我是子组件</p>
<!--预留插槽,插槽也可以有默认值-->
<!-- 带默认值的插槽 <slot><button>按钮</button></slot>-->
<slot></slot>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
components: {
test: {
template: `#tem`,
}
}
});
</script>
具名插槽(修改具体的插槽)
<body>
<div id="app">
<test><h1 slot="left">啊哈哈</h1></test>
<test></test>
</div>
<template id="tem">
<div>
<slot name="left"><p>左插槽</p></slot>
<slot name="center"><p>中插槽</p></slot>
<slot name="right"><p>右插槽</p></slot>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
components: {
test: {
template: `#tem`,
}
}
});
</script>
展示:
父组件替换插槽的标签,内容由子组件提供
<body>
<div id="app">
<test></test>
<test>
<template v-slot="slot">
<p>{{slot.data.join(',')}}</p>
</template>
</test>
<test></test>
</div>
<template id="tem">
<div>
<slot :data="meg">
<p v-for="item in meg">{{item}}</p>
</slot>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
components: {
test: {
template: `#tem`,
data() {
return {
meg: ['java', 'js', 'c++']
}
}
}
}
});
</script>
模块化
解决引入命名变量冲突
ES6:
type模块化
import 导入
export导出
思考