父子组件:
1.props/emit
父组件中
<children :myName="name" @handleClick="childrenFn" />
export default {
components: {
children
},
methods:{
childrenFn(par){
console.log(par);//子组件调用父组件的方法传过来的值
}
}
......
}
子组件中:
// 子组件
export default {
props: ['myName'],
methods:{
getFn(){
this.$emit("handleClick","需要传的值,可以是字符串/对象/数组/数字等任意类型")
}
}
}
/*
获取父组件绑定的属性
props: { myName: String } //这样指定传入的类型,如果类型不对会警告
props: { myName: [String, Number] } // 多个可能的类型
prosp: { myName: { type: String, requires: true } } //必填的的字符串
props: {
childArry: {
type: Array,
default: () => []
},
} // default指定默认值
如果 props 验证失败,会在控制台发出一个警告。
*/
2. $parent / $children 或 $refs 访问组件:
// 父组件
<template>
<child ref="childRef" />
</template>
<script>
export default {
created () {
// 通过 $ref
console.log(this.$refs.childRef.title); // 子组件
this.$refs.childRef.sayHello(); // Hello
// 通过 $children
this.$children.sayHello(); // Hello
}
}
</script>
// 子组件
export default {
data () {
return {
title: '子组件'
}
},
methods: {
sayHello () {
console.log('Hello');
},
getParent(){
// 通过 $parent获取父组件
this.$parent.sayHello();
}
}
}
3.$attrs和 $listeners:
父组件代码
<template>
<div class="">
<!-- 自定义组件使用v-model,默认会利用名为 value 的 prop 和名为 input 的事件,绑定的将在子组件中使用 value 获得,
而且给myChild组件默认会添加 @input 事件 -->
<!-- 在myChild组件里的el-input,可以通过给input添加 :value="value" v-bind="$attrs" v-on="$listeners ,
将input事件传递进去el-input,实现改变输入框能够触发父组件事件效果" -->
<myChild
v-model="value"
:maxlength="2000"
dataSon = 'dataSon'
dataSonSon = 'dataSonSon'
@mySonSonChange="mySonSonChange"
@mySonChagne="mySonChagne"/>
</div>
</template>
<script>
import myChild from './attrsAndListenersChild'
export default {
name: '',
components:{
myChild
},
data() {
return {
value:''
}
},
methods: {
mySonSonChange(){
console.log('我是父组件的myChange,但是由我子组件的子组件调用')
},
mySonChagne(){
console.log('我是父组件的myChange,但是由我子组件调用')
}
},
}
</script>
myChild子组件代码
// 子组件
<template>
<div class="">
<el-input :value="value" v-bind="$attrs" v-on="$listeners"></el-input>
<div>{{value.length}}/{{maxlength}}</div>
<h1>我接收了父组件的dataSon:{{dataSon}},但是没接收父组件的dataSonSon,此时attrs={{$attrs}},将传递到下一层组件</h1>
<el-button type="primary" @click="sonClick">点击触发父组件的mySonChagne</el-button>
<hr />
<!--
这个组件里接收了 value maxlength dataSon,没接收 dataSonSon,所以通过 v-bind="$attrs" 将没接收的 dataSonSon继续往下层组件传递
-->
下边的子组件的子组件{{$listeners}}
<myChildSon v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import myChildSon from './attrsAndListenersChildSon'
export default {
name: '',
components:{
myChildSon
},
props:{
value:{
type:String
},
maxlength:{
type:Number
},
dataSon:{
type:String
}
},
data() {
return {
}
},
methods:{
sonClick(){
this.$emit('mySonChagne')
}
},
created () {
// 传入的所有v-on事件都可以在$listeners对象中找到
console.log(this.$listeners)//{mySonSonChange: ƒ, mySonChagne: ƒ, input: ƒ}
}
}
</script>
myChildSon子子组件代码
<template>
<div class="">
<h1>这是来源于父组件的父组件的dataSonSon:{{dataSonSon}}</h1>
<el-button type="primary" @click="sonSonCilck">点我触发父组件的父组件的mySonSonChange</el-button>
</div>
</template>
<script>
export default {
name: '',
props:{
dataSonSon:{
type:String
}
},
data() {
return {
}
},
methods:{
sonSonCilck(){
this.$emit('mySonSonChange')
}
},
created () {
// 传入的所有v-on事件都可以在$listeners对象中找到
console.log(this.$listeners)//{mySonSonChange: ƒ, mySonChagne: ƒ, input: ƒ}
}
}
</script>
4.bus:
创建一个 Bus.js 文件,并暴露一个 vue 实例
import Vue from 'Vue'
export default new Vue()
使用:
<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
})
}
}
5.provide/inject:
父组件
export default {
provide: { // 它的作用就是将 **name** 这个变量提供给它的所有子组件。
name: 'Jack'
}
}
子组件或孙子组件
export default {
inject: ['name'], // 注入了从父组件中提供的name变量
mounted () {
console.log(this.name); // Jack
}
}
6. .sync的传参:
父组件的代码
<Dialog :show.sync="showSafeDialog" title="安全防护措施和手段" width="50%">
<div v-html="means"></div>
</Dialog>
data() {
return {
showSafeDialog: false
}
}
子组件
<div class="dialog" v-if="show">
<div class="mainBox" :style="{width: width,left: ( 100 - parseInt(width)) / 2+'%',top: top}">
<div class="title">{{title}}</div>
<GeminiScrollbar style="max-height: 90%;">
<div class="content">
<slot></slot>
</div>
</GeminiScrollbar>
</div>
<div class="zhe" @click="close"></div>
</div>
<script>
export default {
name: "Dialog",
props: {
title: {
default: '',
type: String
},
width: {
default: '60%',
type: String
},
show: {
default: false,
type: Boolean
},
top: {
default: '20%',
type: String
}
},
methods: {
close() {
//This is 关键
this.$emit('update:show', false)
}
},
watch: {}
}
</script>
7.vuex:
这个看->这里