1. 文件目录结构
- 在views目录中放页面基础结构的组件
- 在components里放页面中各个功能模块的组件
2. 使用组件
(1)在页面中单独引用
<template>
<Nav></Nav>
</template>
<script>
import nav from '@/components/Nav.vue'
export default {
name: 'Home',
components: { Nav },
</script>
(2)在全局引用
注册单个组件
import Nav from '@/components/Nav.vue'
Vue.component('Nav', Nav)
注册所有组件
const components = require.context('./components', true, /\.vue$/);
components.keys().forEach(key => {
const name = key.match(/\/(\w+?)\.vue$/)[1];
Vue.component(name, components(key).default);
});
3. 组件传值
(1)父组件向子组件传值
- 父组件通过绑定自定义属性来实现,
v-bind (简写为: )绑定需要传递给子组件的值,子组件通过props 来接收父组件传递的值。
<Child :name="zhang"></Child>
export default {
props: {
name: {
type: String,
required: true,
default: "",
},
},
}
(2)子组件给父组件传值
<button @click="changeName">改变父组件的name</button>
export default {
methods: {
changeName() {
this.$emit('handleChange', 'zhang')
}
}
}
<child @handleChange="changeName"></child>
methods: {
changeName(name) {
this.name = name
}
}
(3)通过 $parent ,$children,$root 或 $refs 访问组件实例
export default {
data () {
return {
title: '子组件'
}
},
methods: {
sayHello () {
console.log('Hello');
}
}
}
<template>
<child ref="child" />
</template>
<script>
export default {
created () {
console.log(this.$refs.child.title);
this.$refs.child.sayHello();
this.$children.sayHello();
}
}
</script>
(4)$attrs和$listeners
$attrs
- $attrs在vue的2.40版本以上可使用
- $attrs,当一个组件没有声明任何 prop 时,$attrs里包含所有父作用域的绑定的自定义属性 (class 和 style 除外),并且可以通过
v-bind="$attrs" 传入内部组件 - 如果给组件传递的数据,组件不使用props接收,那么这些数据将作为组件的HTML元素的特性,这些特性绑定在组件的HTML根元素上(可使用
inheritAttrs: false 取消) inheritAttrs: false 的含义是不希望本组件的根元素继承父组件的attribute,同时父组件传过来的属性(没有被子组件的props接收的属性),也不会显示在子组件的dom元素上,但是在组件里可以通过其$attrs可以获取到没有使用的注册属性, ``inheritAttrs: false`是不会影响 style 和 class 的绑定
$listeners
$listeners 它是一个对象,里面包含了作用在这个组件上的所有监听器- 并且可以通过 v-=“$listeners” 传入内部组件
<template>
<div>
<HomeHeader
@toHome="logoCilck"
:value="22"
aa="aa"
></HomeHeader>
</div>
</template>
<template>
<Menu v-bind="$attrs" v-on="$listeners"></Menu>
</template>
export default {
name: "HomeHeader",
inheritAttrs: false,
mounted() {
console.log(this.$attrs);
console.log(this.$listeners)
},
};
export default {
name: 'Menu',
mounted() {
console.log(this.$attrs);
console.log(this.$listeners)
},
};
(5)子组件之间传值
- 将
props 和$emit 结合使用,子组件先传给父组件,再由父组件传给另一个子组件。 EventBus ,
创建一个 EventBus.js 文件,并暴露一个 vue 实例
import Vue from 'Vue'
export default new Vue()
在要传值的文件里导入这个空 vue 实例,绑定事件并通过 $emit 触发事件函数 (也可以在 main.js 中全局引入该 js 文件,我一般在需要使用到的组件中引入)
<template>
<div>
<p>姓名: {{ name }}</p>
<button @click="changeName">修改姓名</button>
</div>
</template>
<script>
import { EventBus } from "../EventBus.js"
export default {
data() {
return {
name: 'John',
}
},
methods: {
changeName() {
this.name = 'Lily'
EventBus.$emit("editName", this.name)
}
}
}
</script>
在接收传值的组件中也导入 vue 实例,通过 $on 监听回调,回调函数接收所有触发事件时传入的参数
import { EventBus } from "../EventBus.js"
export default {
data() {
return {
name: ''
}
},
created() {
EventBus.$on('editName', (name) => {
this.name = name
})
}
}
(6)provide,inject
它们需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
export default {
provide: {
name: 'zhang'
}
}
export default {
inject: ['name'],
mounted () {
console.log(this.name);
}
}
4. 插槽
- **
slot ** 默认插槽 插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码 具名插槽
<template>
<div class= 'button'>
<button> </button>
<slot name='one'> 这就是默认值1</slot>
<slot name='two'> 这就是默认值2 </slot>
<slot name='three'> 这就是默认值3 </slot>
</div>
</template>
<template>
<div class= 'app'>
<ebutton>
<template v-slot:one> 这是插入到one插槽的内容 </template>
<template v-slot:two> 这是插入到two插槽的内容 </template>
<template v-slot:three> 这是插入到three插槽的内容 </template>
</ebutton>
</div>
</template>
作用域插槽 ( 父组件 在子组件 处使用子组件 data)
<template>
<div class= 'button'>
<button> </button>
<slot name= 'one' :value1='child1'> 这就是默认值1</slot>
<slot :value2='child2'> 这就是默认值2 </slot>
</div>
</template>
new Vue({
el:'.button',
data:{
child1:'数据1',
child2:'数据2'
}
})
<template>
<div class= 'app'>
<ebutton>
<template v-slot:one = 'slotonevalue'>
{{ slotonevalue.value1 }}
</template>
<template v-slot:default = 'slottwovalue'>
{{ slottwovalue.value2 }}
</template>
</ebutton>
</div>
</template>
$slots vm.$slots是一个对象,键名是所有具名slot的名称,加上一个default,而键值则是一个存放VNode节点的数组。
|