父组件向子组件传值:
父组件
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" :msg2="msg2" /> <!-- 3.在template写上子组件,msg就是向子组件传的值,也可以用v-bind动态绑定 -->
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue"; // 1.引入子组件
export default {
name: "App",
components: {
HelloWorld, // 2.注册子组件
},
data() {
return {
msg2: '动态的值'
}
},
};
</script>
子组件
<template>
<div class="hello">
msg的值=>{{msg}}
<p>msg2的值=>{{msg2}}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: ['msg', 'msg2'] // 4.在子组件中写上porps接收父组件的传过来的参数,可以直接写到template使用,或做其他操作
}
</script>
效果
子组件向父组件传值:
子组件
<template>
<div class="hello">
<button @click="doSend">点击</button>
<!-- 1.绑定一个事件触发向父组件传值,也可以是其他事件或其他操作 -->
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
sonData: '子组件中定义的值'
}
},
methods: {
doSend() {
const that = this;
// 2.在点击触发的时候使用emit发布,第一个参数自定义一个名称,后面的参数是向父组件传的值
// 可以是一个值,也可以是多个值,例如{name: zhangsan, id: 1}
that.$emit('sonFun', that.sonData)
}
}
}
</script>
父组件
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld @sonFun="sonFun" /> <!-- 3.在父组件中的子组件上写上子组件传过来的事件,并用一个方法(方法名字随便定义)接收 -->
子组件向父组件传过来的值=>{{faData}}
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
faData: null
}
},
methods: {
sonFun(e) {
// 4.在方法中用一个实参e接收, 参数名字随便定义
const that = this;
that.faData = e
}
}
};
</script>
效果
兄弟组件传值(非父子组件,也是无任何关系的组件,可以说是全局组件相互传值):
在main.js中创建一个公共的vue实例
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 1.全局组件传值,需要创建一个公共的vue实例,在Vue的原型上创建一个属性bus,该属性的值为new Vue(),即bus也是一个vue实例
// 也可以新建一个js文件,兄弟两个组件分别引入这个js,
Vue.prototype.bus = new Vue()
new Vue({
render: h => h(App),
}).$mount('#app')
举个栗子,两个组件在一个父组件中注册,也可以是任何没有关系的两个组件显示在同一个页面内
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld />
<HiWorld />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import HiWorld from "./components/HiWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
HiWorld
},
};
</script>
A组件
<template>
<div class="hello">
<button @click="doSend">点击</button>
<!-- 2.绑定一个事件或者是其他逻辑触发向其他组件发送值 -->
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
broData: '向其他组件传递的值'
}
},
methods: {
doSend() {
const that = this;
// 3.这里使用vue原型绑定的bus实例进行emit发布,全局组件传值就是一个是发布者emit,另一个是订阅者on
that.bus.$emit('sendData', that.broData)
}
}
}
</script>
B组件
<template>
<div>A组件发送过来的值=> {{overData}}</div>
</template>
<script>
export default {
data() {
return {
overData: null
}
},
created() {
const that = this;
// 注意:在进行事件监听接收一方,需要先关闭当前事件,防止不断进入此页面触发多次组件,监听事件也会再次触发,点击一次会执行多次$on
that.bus.$off('sendData');
// 4.on可以写到created中或者mounted,第一个参数是其他组件传递过来的参数(事件名),后面跟一个回调函数,定一个参数来接收
that.bus.$on('sendData', res=> {
that.overData = res
})
}
}
</script>
效果仅供参考,与代码中描述页面中的内容不太一致,最终还是根据需求而定
组件传值也可以用vuex状态管理,这里就不做讲解了
以上是vue2组件传值方式,vue3的pinia也在努力编写中