目录
组件化开发
组件模块的分离
<div id="app">
<cpn></cpn>
</div>
<!-- 第1个方法.script标签类型必须是type="text/x-template" -->
<!-- <script type="text/x-template" id="cpn"> -->
<!-- 组件写这里更方便 -->
<!-- <div>
<h2>标题</h2>
<p>内容</p>
</div>
</script> -->
<!-- 第2个方法.template标签 -->
<template id="cpn">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</template>
<script>
// 注册一个component全局组件的语法糖更方便,不用创建组件构造器
Vue.component('cpn', {
template: '#cpn'
})
const app = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
组件中的data为什么是函数
<script>
// 1.注册组件
Vue.component('cpn',{
template:'#cpn',
// data()必须是个函数,不是函数也会报错,
//data:{}这样多个调用都指向一个内存地址一个变一起变,
// data()这样每次调用就会有一个新的内存地址,自己改自己的内存东西
// 每一个组件实例都有自己的状态,他都需要一个对象来保存属于自己的状态
data(){
return {
counter:0
}
},
methods:{
increment(){
this.counter++
},
decrement(){
this.counter--
}
}
})
</script>
组件通信父传子props
<div id="app">
<!-- <cpn v-bind:cmovies="movies" :cmessage="message"></cpn> -->
<!-- 这里只负责赋值了,没有输出 -->
<cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
</div>
<!-- 组件模板 -->
<template id="cpn">
<!-- 内部代码多必须有个根标签包裹,比如这个div -->
<div>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<script>
//父传子props
const cpn = {
template: '#cpn',
// 一。数组方式
// props:['cmovies','cmessage'],
// 二。对象方式
props: {
// 1.类型限制
// cmovies:Array,
// cmessage:String,
// 2.给字符串提供一些默认值
cmessage: {
// 类型
type: String,
// default当别人没传值的默认值
default: 'aaaaa',
// required必须传值
required:true
},
// 给数组设置
// 类型是对象或数组时,默认值default必须是一个函数
cmovies:{
type:Array,
default(){
return []
}
}
},
data() {
return {}
},
methods: {
}
}
// 父组件,实例
const app = new Vue({
el: '#app',
data: {
message: '你好吖',
movies: ['海王', '海贼王', '海尔兄弟']
},
// components注册组件
components: {
// 相当于cpn:cpn ,是es6的增强写法
cpn
}
});
</script>
组件通信子传父$emit(发射事件)
<!-- 父组件模板 -->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<!-- 子组件模板 -->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script>
// 1.子组件
const cpn = {
template:'#cpn',
data(){
return {
categories:[
{id:'aaa',name:'热门推荐'},
{id:'bbb',name:'手机数码'},
{id:'ccc',name:'家用家电'},
{id:'ddd',name:'电脑办公'}
]
}
},
methods:{
btnClick(item){
//$emit 发射事件:自定义事件
// 子传父就是通过自定义事件传递的
// item-click自定义事件的名字,item自定义事件的参数
this.$emit('item-click',item)
}
}
}
// 2.父组件
const app = new Vue({
el: '#app',
data: {},
methods: {
cpnClick(item){
// 获取到了子组件cpn里的对象属性
console.log(item);
}
},
components:{
cpn
}
});
</script>
组件访问父访问子
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>
我是子组件
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {},
// methods装函数
methods: {
btnClick(){
// 2.$refs是对象类型,默认是一个空的对象,必须在组件上加 ref='bbb'
,一般用这个 直接锁定元素
console.log(this.$refs.aaa.name);
}
},
// components注册组件
components:{
cpn:{
template:'#cpn',
data(){
return {
name:'我是子组件的name'
}
},
methods:{
showMessage(){
console.log('showMessage');
}
}
}
}
});
组件访问子访问父
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是cpn组件</h2>
<ccpn></ccpn>
</div>
</template>
<template id="ccpn">
<div>
<h2>我是子组件</h2>
<button @click="btnClick">按钮</button>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {},
// methods装函数
methods: {
},
// components注册组件
// 父
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '我是cpn组件的name'
}
},
// 子
components: {
ccpn: {
template: '#ccpn',
methods: {
btnClick() {
// 1.访问父组件$parent ,用的非常少
// console.log(this.$parent);
// console.log(this.$parent.name)
// 2.访问根组件$root
console.log(this.$root);
}
}
}
},
}
}
});
</script>
组件化高级
slot插槽的基本使用
<!-- 1.插槽的基本使用 写个空的啥也不加<slot></slot>
2.可以加默认值,<slot>内容</slot>
3.多个值可以同时放到组件一起替换 -->
<div id="app">
<cpn></cpn>
<cpn><span>我是span</span></cpn>
<cpn>
<i>我i是</i>
<p>我是p</p>
</cpn>
</div>
<template id="cpn">
<div>
<h2>我是组件</h2>
<p>我是组件的p</p>
<slot><button>按钮</button></slot>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {},
methods: {},
components:{
cpn:{
template:'#cpn'
}
}
});
</script>
具名插槽的作用
<div id="app">
<cpn><span slot="center">换的中间</span></cpn>
<cpn><button slot="left">换的左边</button></cpn>
</div>
<template id="cpn">
<div>
<!-- 加上name可以指定换那个 -->
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {},
methods: {},
components:{
cpn:{
template:'#cpn',
}
}
});
</script>
博主公_号:前端老实人,期待各位小伙伴加入我们一起学习的队伍哦❤