| 全局、局部组件
| 数据传递(props、组件通信、slot)
| props、sync双向绑定、once单次绑定
| 组件之间通信,$dispatch() 派发事件、 $broadcast() 广播事件,事件向下传导给所有后代
| slot 内容分发
| 组件是Vue的最强大功能之一,组件可以扩展html元素,封装可复用代码
全局组件
全局组件在任何组件内都可以调用,无需引用或通过component加载
main.js
// 定义一个全局的组件
var myComponent = Vue.extend({
template: '<div> 组件已经渲染出来 </div>'
})
// 全局注册
Vue.component('crm-component', myComponent);
let vm = new Vue({
...
}}
main.vue 子组件
<templte>
<div class="welcome">
<h1>视图列表页面</h1>
<crm-component></crm-component> <!-- 调用 -->
</div>
</template>
局部组件
必须使用components对象来引用组件
<div id="appA">
<User></User>
</div>
<script>
import User import './user';
var vmA = new Vue({
el: "#appA",
components: { // 局部的写法
User
}
})
</script>
————— 父与子组件之间的数据传递 —————
props
父组件将数据传给子组件通过props,子组件通过自定义事件$on、$emit来挂参数传递给父组件
一、props
<div id="app">
<!-- 这里的两个属性值通过props传到组件中 -->
<component-parent my-name="siguang" my-age='33'></component-parent>
</div>
<script>
var componentCrm = Vue.extend({
props: ['myName', 'myAge'],
template: '<h2>{{ myName }} {{ myAge }}</h2>'
})
var vm = new Vue({
el: '#app',
components: {
'component-parent': componentCrm
}
})
</script>
注意: my-name="siguang" 自定义属性以“-”分割
props: ['myName', 'myAge'] // props 定义的必须以驼峰形势
二、props动态值
parent.vue:
<div id="app">
<child-component :user-name="uname"></child-component>
</div>
<script>
import childComponent from 'childComponent.vue';
export default{
data(): {
return{
uname: 'siguang'
}
},
components:{
childComponent
}
}
</script>
childComponent.vue:
<div>
{{ userName }} <!-- siguang -->
</div>
<script>
export default{
propos: ['userName'],
}
</script>
三、once 将渲染的结果缓存
不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来
<div id="app">
<component-parent></component-parent>
</div>
<script>
var childrenComponent = Vue.extend({
template: '<div v-once>'+
'<h3>这里是子组件的内容: {{ myMsg }}</3>'+
'<p>这里输入不会影响父组件: <input type="text" v-model="myMsg" /></p>'+
'</div>',
data: function(){
return {
myMsg: ''
}
},
props: ['myMsg']
})
var parentComponent = Vue.extend({
template: '<div v-once>'+
'<p><input text="text" v-model="msg"></p>'+
'<p>父组件的值 {{ msg }}</p>'+
'</div>'+
'<childen-component v-bind:my-msg.once="msg"></childen-component>',
data: function(){
return {
msg: '这里值只传给子组件一次'
}
},
components: {
'childen-component': childrenComponent
}
})
var vm = new Vue({
el: '#app',
components: {
'component-parent': parentComponent
}
})
</script>
组件之间通信
props是单向数据流父向子组件传递数据,子向父组件传递可以通过自定义事件来处理
$on(eventName) 监听事件 、$emit(eventName) 触发事件
一、子向父组件发消息
parent.vue:
<template>
<div class="login">
<div class="parent-box">
<p>显示子组件数据: {{ childrenText }}</p>
</div>
<children-component ref="childrenRef" v-on:showChildrenVal="childrenVal"></children-component>
</div>
</template>
<script>
import ChildrenComponent from './children.vue'
export default{
data(){
return {
childrenText: ''
}
},
methods:{
childrenVal(val){
this.childrenText = val;
}
},
components:{
ChildrenComponent
}
}
</script>
children.vue:
<template>
<div class="children" style="padding-top: 50px; border-top: 1px #ccc solid">
<p><input type="text" v-model="childrenInp" id=""></p>
<p><input type="button" @click="toParentData" value="提交到父组件中"></p>
</div>
</template>
<script>
export default{
data(){
return {
childrenInp: ''
}
},
methods:{
toParentData(){
this.$emit("showChildrenVal", this.childrenInp);
}
}
}
</script>
二、父向子发消息
parent.vue:
<template>
<div class="login">
<div class="parent-box">
<p><input type="text" name="" v-model="inputParent" ><br></p>
<p><input type="button" value="值传给父组件" @click="sendChildren"><br></p>
<p>显示子组件数据: {{ childrenText }}</p>
</div>
<children-component ref="childrenRef"></children-component>
</div>
</template>
<script>
import ChildrenComponent from './children.vue'
export default{
data(){
return {
inputParent: '',
childrenText: ''
}
},
methods:{
sendChildren(){
this.$refs.childrenRef.$emit('showText', this.inputParent); // 也可以用props
}
},
components:{
ChildrenComponent
}
}
</script>
children.vue:
<template>
<div class="children" style="padding-top: 50px; border-top: 1px #ccc solid">
这里是父组件传递的值: {{transmitVal}}
</div>
</template>
<script>
export default{
created(){
this.$on('showText', function(val){
this.transmitVal = val;
})
},
data(){
return {
transmitVal: ''
}
}
}
</script>
三、v-ref 直接访问到组件
<div id="app">
<span ref="msg"> hello </span>
<span ref="other-msg"> world </span>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
someProp: 'idName',
otherProp: 'prop'
}
})
console.log(vm.$refs.msg.textContent); // hello
console.log(vm.$refs.otherMsg.textContent); // world
</script>
slot 分发内容
parent.vue:
<template>
<div class="login">
<children-component>
<h1 slot="header">这里可能是一个页面标题</h1>
<div class="tag">
这里是没有定义slot名称走的默认的slot
<div class="tag-til">标题</div>
<div class="tag-content">内容部分</div>
</div>
</children-component>
</div>
</template>
children.vue:
<template>
<div class="children">
<slot name="header"></slot>
<slot></slot>
</div>
</template>
组件化的css
可以通过scoped属性来控制样式是否是只在当前组件下使用
<style>
/* 全局下的样式 */
</style>
<style scoped>
/* 当前组件下使用的样式 */
</style>
国内查看评论需要代理~