一、全局组件
html:
<div id="app"><mytemplace></mytemplace>
</div>
javascript:
<script>const { createApp } = Vueconst app = createApp({})app.component('mytemplace', {template: '<div><button>返回</button></div>'}).mount('#app')
</script>
结果展示:
二、局部组件
- 局部组件只能在父组件中使用,其他组件无法使用该局部组件
- 父组件与子组件属性和方法不能共享
html:
<div id="app"><mytemplate></mytemplate>
</div>
javascript:
<script>const { createApp, ref } = Vueconst app = createApp({})app.component('mytemplate', {template:'<div> <input type="text" v-model="inputText" /><childTemplate @click="buttonClk"></childTemplate><ul><li v-for="item in myDataList">{{ item }}</li></ul></div>',data() {return {myDataList: ['123', '123qwe', 'aaa'],inputText: ''}},methods: {buttonClk() {console.log('自定义组件-父组件点击事件')}},components: {childTemplate: {template: '<button @click="childButtonClk">点击</button>',methods: {childButtonClk() {console.log('自定义组件-子组件点击事件')}}}}}).mount('#app')
</script>
1.结果展示:
2.点击按钮输出结果:
三、父组件与子组件之间的传参
1、父传子
父传子通过属性向下传递:在子组件中自定义属性名,并传递相应的参数过去。子组件通过 props 接受传过来的参数
<body><div id="app"><mytemplace mypros="传递固定参数"></mytemplace><mytemplace :mypros="parentProps"></mytemplace><mytemplace :mypros="parentProps" :mypros1="parentProps1"></mytemplace></div><script src="./lib/vue.global.js"></script><script>const { createApp } = Vueconst app = createApp({data() {return {parentProps: '传递动态参数属性前加冒号',parentProps1: true}}})app.component('mytemplace', {template: '<div><button>{{mypros+"-"+mypros1}}</button></div>',//属性校验,指定参数类型props: {mypros: String,mypros1: Boolean}// props: ['mypros', 'mypros1']}).mount('#app')</script>
</body>
2、子传父
子传父通过事件传递参数:子组件的点击事件通过 this.$emit(父组件中自定义的事件名称, 传递的参数) 传递参数到父组件;父组件通过自定义事件接收参数
<body><div id="app"><mytemplace @myevent="parentClick($event)"></mytemplace></div><script src="./lib/vue.global.js"></script><script>const { createApp } = Vueconst app = createApp({methods: {parentClick(e) {console.log('父组件点击:' + e)}}})app.component('mytemplace', {data() {return { childProp: '子组件属性' }},template: '<div><button @click="childClick()">返回</button></div>',methods: {childClick() {this.$emit('myevent', this.childProp)}}}).mount('#app')</script>
</body>
四、slot 插槽
当需要在子组件标签中插入一个或多个父组件的标签时,需要在子组件中定义一个 slot 标签
1、具名插槽: 在子组件中通过 name 属性为插槽取名,在 template 标签中通过 v-slot:插槽名(或者:#插槽名) 选择对应的插槽
html :
<div id="app"><myslot><template v-slot:slot1>插槽1</template><template v-slot:slot2>插槽2</template><template #slot3>插槽3</template></myslot>
</div>
js :
<script>
const app = Vue.createApp({data () {return { chooseValue: 'component1' }},components: {myslot: {template:'<div><button>组件</button><input type="text"/><slot name="slot1"></slot><slot name="slot2"></slot><slot name="slot3"></slot></div>'}}
}).mount('#app')
</script>
2、默认内容: 当父组件没有内容替换插槽时,在 < slot > 标签中的内容回被视为默认内容显示出来
html :
<defaultslot> </defaultslot>
js :
const app = Vue.createApp({data () {return { chooseValue: 'component1' }},components: {defaultslot: {template:'<div><button>组件</button><input type="text"/><slot>默认内容</slot></div>'}}
}).mount('#app')
结果展示 :
3、动态插槽名: 通过 #[动态插槽名] (或者 v-slot:[动态插槽名]) 动态选择插槽(动态插槽名必须为小写)
<myslot><template #[slotname]>插槽1</template>
</myslot><select v-model="slotname">
<option value="slot1">插槽1</option>
<option value="slot2">插槽2</option>
<option value="slot2">插槽3</option>
</select>
const app = Vue.createApp({data () {return { slotname: 'slot1' }},components: {myslot: {template:'<div><button>组件</button><input type="text"/><slot name="slot1">插槽11</slot><slot name="slot2">插槽22</slot><slot name="slot3">插槽33</slot></div>'}}
}).mount('#app')
A、结果展示:初始下拉框默认为插槽1,所以第一个插槽被替换,其他2个插槽使用默认内容
--------------------------------------------------------------------------------------------------------------------------
B、结果展示:选择插槽2后,第二个插槽被替换,其他2个插槽使用默认内容
--------------------------------------------------------------------------------------------------------------------------
4、默认插槽传参
<scopeslot v-slot="slotvalue">{{ slotvalue.text }} {{ slotvalue.count }}
</scopeslot>
<script>
scopeslot: {data () {return { greetingMessage: 'hello' }},template: '<div><slot :text="greetingMessage" :count="1"></slot></div>'
}
</script>
结果展示:
5、具名插槽传参:
html :
<scopeslot1><template v-slot="info">{{ info.message }} {{ info.age }}</template><template #scope1="{message,age}">{{ message }} {{ age }}</template>
</scopeslot1>
js:
<script>
scopeslot1: {template:'<div><slot message="无名插槽" age="18"></slot>--<slot name="scope1" message="具名插槽" age="20"></slot></div>'
}
</script>
五、ref 通信
子组件(标签)中定义 ref 属性后,可以通过 this.$refs.ref属性名 获得子组件(标签)对象,从而获取子组件(标签)的控制权
<body><div id="app"><!-- 通过ref获取输入框的内容 --><input type="text" ref="myInputText" /><mytemplace ref="myRef"></mytemplace><button @click="parentClick">父组件点击事件</button></div><script src="./lib/vue.global.js"></script><script>const { createApp } = Vueconst app = createApp({data() {return { parentPro: 'refTest' }},methods: {parentClick() {this.$refs.myRef.childClick(this.parentPro)}}})app.component('mytemplace', {data() {return { childProp: '子组件属性' }},template: '<div><button @click="childClick()">返回</button></div>',methods: {childClick(e) {console.log('子组件点击事件', e)}}}).mount('#app')</script>
</body>