全局组件 & 局部组件
[ 组件作用 ]
- 可以复用,提高开发效率
- 方便后期维护和修改
- 减少渲染
全局组件
<body>
<div id="app">
<!-- 在 dom 中只支持 - 连接 -->
<my-button></my-button>
</div>
<!-- 组件内容 -->
<template id="button">
<div> 111 </div>
</template>
</body>
</html>
<script src="vue.min.js"></script>
<script>
// 全局组件
Vue.component('my-button', {
// template: '<div> 1111 </div', // 所有组件
template: '#button', // 查找相应组件内容
data() { // 组件中的data 是一个函数 返回一个对象
return {
msg: 'aaa',
}
}
})
let vm = new Vue({
// template: '<div> 111 </div',
el: '#app',
data: {},
})
</script>
局部组件
<body>
<div id="app">
<!--3. 使用组件; 在 dom 中只支持 - 连接 -->
<my-button>
<hello></hello>
</my-button>
<!-- <hello></hello> -->
</div>
<!-- 组件内容 -->
<template id="button">
<div> {{ msg }}</div>
</template>
<template id="hello">
<div> {{ hel }} </div>
</template>
</body>
</html>
<script src="vue.min.js"></script>
<script>
/**
* 1. 定义组件
* 2. 注册组件
* 3. 使用组件
*
*/
let hello = {
template: '#hello',
data() {
return {
hel: 'hello'
}
}
}
// 1. 定义组件
let myButton = {
// template: '<div> 1111 </div', // 所有组件
template: '#button', // 查找相应组件内容
data() { // 组件中的data 是一个函数 返回一个对象
return {
msg: 'aaa',
}
},
// myButton 的子组件 hello
components: {
// 在 myButton 中注册子组件 hello
hello
}
}
let vm = new Vue({
// template: '<div> 111 </div',
el: '#app',
data: {},
components: {
// 2. 注册组件
myButton, // myButton:myButton
// hello
}
})
</script>
组件间通信
[ 安装 ]
- 项目开发: npm install -g @vue/cli
- 快速原型开发(对单个 *.vue 文件开发): npm install -g @vue/cli-service-global
[ 运行 ]
- 开发环境: vue serve App.vue
- 生产环境: vue build App.vue
父组件传数据到子组件 : 子组件通过 props 接收
<template>
<div>
Parent
<!-- 父组件穿数据到子组件 -->
<Son :money='money'></Son>
</div>
</template>
<script>
import Son from './Son';
export default {
data() {
return {
money: '400',
}
},
components: {
Son
}
}
</script>
<template>
<div>
Son
{{ money }}
</div>
</template>
<script>
export default {
// props:['money']
// computed: { //计算属性
// changeM() {
// // 对传过来的值进行更改,变为小写
// return this.money.thim().toLowerCase();
// }
// },
// 对传过来的值进行验证
props: {
money: {
type:[String, Number],
// default: 100, 默认值
required: true, // 必须传
// 自定义验证规则
validator:(value)=> {
return value > 400 && value < 1000;
}
},
// 数组或对象 默认值得是函数
arr: {
type: Array ,
default: ()=> [1] //默认值 函数 返回一个数组
},
obj: {
type:Object,
default: ()=> ({}) //默认值 函数 返回一个对象
},
},
}
</script>
子组件传数据到父组件 : $emit(通过事件的方式,观察者模式)
<template>
<div>
Parent
<!-- 父组件监视子组件的事件(子组件传数据到父组件)并且给事件绑定函数 -->
<!-- <Son @change="fn"></Son> -->
<!-- 语法糖写法 -->
<!-- <Son :money.sync="money"></Son> -->
<!-- 对应子组件 语法糖 写法 -->
<!-- this.$emit('update:money',1000) -->
<!-- 相当于 money 绑定在属性 value 并且绑定的事件名 @input -->
<Son v-model="money"></Son>
<!-- <Son
:value="money"
@input="(data)=>money=data"
></Son> -->
<!-- 对应子组件写法 -->
<!-- 接受到的属性 :{{ value }} -->
<!-- this.$emit('input', 1000) -->
</div>
</template>
<script>
import Son from './Son';
export default {
data() {
return {
money: '400',
}
},
components: {
Son
},
methods: {
fn(data){ // data 子组件传回来的数据
this.money = data;
}
},
}
</script>
<template>
<div>
Son
<button @click="give">传数据到父组件</button>
</div>
</template>
<script>
// import grandSon from './grandSon';
export default {
methods: {
// 子组件传数据到父组件
give() {
// 子组件执行父组件监听的事件
// this.$emit('change', 1000)
// 语法糖 写法
// this.$emit('update:money',1000)
this.$emit('input', 1000)
}
},
}
</script>
批量把属性传给后代组件(子组件或孙组件): $attrs(v-bind=”$attrs”往下传)
<Son :name ="1" :age= "2" @click="fn"></Son>
<!-- 直接一次性拿到父组件传的所有属性 -->
{{$attrs}}
<!-- 只传一个数据,此时 数据里面只剩下 age -->
<GrandSon v-bind="$attrs" :name="$attrs.name"></GrandSon>
<script>
// GrandSon 组件中接收
export default {
props: ['name'],
}
</script>
批量把方法传给后代组件: $listeners(v-on=”$listeners”往下传)
<!-- 父组件中绑定事件 -->
<Son :name ="1" :age= "2" @click="fn"></Son>
<!-- 子组件拿到父组件的事件 -->
<!-- {{ $listeners.click() }} -->
<GrandSon v-on="$listeners" ></GrandSon>
<!-- GrandSon 组件中直接调用 -->
{{ $listeners.click() }}
跨组件 provide inject
<!-- 跨组件 -->
<script>
import Son from './Son'
export default {
// 全局定义
provide() {
return {
parentMsg: 'parent'
}
},
}
</script>
<!-- grandSon 中通过 inject 注入, {{ parentMsg }}使用 -->
<script>
export default {
inject:['parentMsg']
}
</script>
$parent & $children & ref
- 拿到父组件: $parent ;
- 拿到所有子组件: $children (返回一个所有子组件的数组) ;
- 通过 ref 获取
<!-- $parent 拿到父组件; $children 拿到所有子组件 -->
<GrandSon ref="GrandSon" ></GrandSon>
<script>
mounted() { // dom 加载完成的钩子函数
this.$parent // 拿到父组件
this.$children // 拿到所有的子组件,拿到的是一个数组
// 执行
this.$parent.fn();
this.$$children[0].fn2(); // 通过索引拿到第一个子组件
// 通过 ref
this.$refs.GrandSon.fn2()
}
</script>
- 兄弟间的通信 : eventBus; 通过 $on 和 $emit
Vue.prototype.$bus = new Vue(); // 必须拥有公共的 vue 实例
this.$bus.$on('test',function(data){
console.log(data)
})
// 另一个兄弟组件传递数据
this.$bus.$emit('test',1000)