1 组件化思想
组件的使用分成三个步骤:
-创建组件构造器
-注册组件
-使用组件。
调用Vue.extend0方法
-创建组件构造器
期电Vue.cOmponent0万法
-注册组件
在Vue实例的作用范围内
-使用 组件
1.1 组件基本使用
<body>
<div id="app">
<!--3.使用组件-->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js "></script>
<script>
//1.创建组件构造器对象
const cpnC = vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈哈</p>
<p>我是内容,呵呵呵呵</p>
</div>`
}
// 2.注册组件
vue.component( 'my-cpn' , cpnc)
</script>
//结果
我是标题
我是内容,
哈哈哈哈我是内容,
呵呵呵呵
我是标题
我是内容,
哈哈哈哈我是内容,
呵呵呵呵
……
1.2 全局和局部组件
vue.component( 'cpn', cpnc)
——该方法注册的组件是全局组件,意味着可以在多个Vue的实例下面使用
——在Vue实例的内部注册组件,是局部组件,只在(id=app内生效)
const app = new Vue({
el: '#app',
data: {
message:'你好啊"},
components: {
cpn:cpnc
}
})
1.3 组件的父子关系
父组件:cpnC2,子组件:CpnC1
Vue实例也是组件:root组件
<div id="app">
<cpn2></cpn2> --有效,调用cpn2-cpn1
<cpn1></cpn1> --无效
<script>
const cpnC1 = Vue.extent({
template:`<h1></h1>`
})
const cpnC2 = Vue.extent({
template:`<h2></h2><cpn1></cpn1>`,
components:{ -----在cpnC2中注册cpnC1
cpn1:cpnC1 ----在<cpn1>调用时会被直接替换成<h1></h1>
}
})
const app =new Vue({
el:'#app',
data:{
message:'...'
},
components:{
cpn2:cpnC2
}
})
</script>
2 组件的进阶
2.1 简化 省略extent(语法糖)
<script>
const cpnC = Vue.extent({
template:`<h1></h1>`
})
Vue.component('cpn',cpnC)
const app = new Vue({
el:'#app',
data:{]
component:{
'cpn':cpnC
}
})
--------上述注册方式等同于下面--------------
Vue.component('cpn',{
template:`<h1></h1>`
})
const app = new Vue({
el:'#app',
data:{}
component:{
'cpn':{
template:`<h1></h1>`
}}})
</script>
2.2 简化 外部组件模板(抽离)
两种写法
<script type="text/x-template" id="cpn"><h1><h1></script>
<template id="cpn"><h1><h1></template>
Vue.component('cpn',{
template:#cpn
})
const app = new Vue({
el:'#app',
data:{]
component:{
'cpn':{
template:#cpn
}}})
</script>
2.3 组件内的data(){},为啥是函数
<body>
<div id="app">
<!--3.使用组件-->
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2 @click="add">{{num}}</h2>
<p>我是内容,哈哈哈哈</p>
</div>
</template>
<script src="./vue.js"></script>
<script>
const mv = new Vue({
el:'#app',
data:{
message:'nihao'
},
components:{cpn}
})
const cpn ={
//1.组件内的data以函数的形式存在,使用return存储数据
//2.以函数存在,组件实例化时,多个实例对象调用的组内data互不影响,
// 若有需求,可在data外定义公共的数据,供该组件内共同使用
template:'#cpn',
data(){return {num:0}},
methods:{
add(){this.num++;}
}
}
</script>
</body>
3 组件通讯
3.1 父传子 props
<body>
<div id="app">
<!-- 3.传值(提供默认值的参数可以不传值) -->
<cpn :pfrute='frute' :pmsg='messages'></cpn>
</div>
<template id="cpn2">
<div>
<p v-for="item in pfrute" >{{item}} </p>
<p>{{pmsg}} </p>
</div>
</template>
<script src="./vue.js"></script>
<script>
// 2.子组件
const cpn ={
template:'#cpn2',
// 2.1默认传递方法
//props:["pfrute","pmsg"],
props:{ //2.2 简单类型限制
// pfrute:Array,
// pmsg:String
//2.3 提供默认值
pfrute:{
type:Array,
default:['a','b']
//此处默认值也可以是函数default(){return}
},
pmsg:{
type:String,
default:'ggggggggg'
//required:true 必须传值
}
},
data(){return{}}
}
// 1.父组件
const mv = new Vue({
el:'#app',
data:{
frute:['苹果','桃子'],
messages:'hai'
},
components:{cpn}
})
</script>
</body>
prope参数也可以自定义类型
3.2 子传父 自定义事件$emit
流程: 1.在子组件设置$emit触发事件 2.在父组件中绑定v-on监听子组件
<body>
<div id="app">
<!-- 3.绑定自定义事件,设置监听 (父) -->
<cpn @cpnClick='cpnclick'></cpn>
</div>
<template id="cpn">
<!-- 1.设置点击事件,向事件中传入item (子)-->
<div><button v-for="item in categories" @Click='send(item)'>{{item.name}} </button></div>
</template>
<script src="./vue.js"></script>
<script>
const cpn = {
template:'#cpn',
data(){
return{
categories:[
{id:'a',name:'手机'},
{id:'b',name:'电脑'},
{id:'c',name:'游戏机'},
]
}},
methods:{
send(item){
// 2.定义点击事件,设置$emit触发事件 (子)
this.$emit('cpnclick',item)
}}
}
new Vue({
el:'#app',
data:{
message:'hello',
},
components:{
cpn
},
methods:{
// 4.定义监听事件 (父)
cpnclick(item){console.log(item.name)}
}
})
</script>
</body>
父子组件访问 -parent和children/ref
https://www.bilibili.com/video/BV15741177Eh?p=59