父子、非父子间的传参方式
1 // 父组件向子组件传参: 2 // 在项目中 可能有好几个地方都用到这个功能(例如:表格 列表啊),写成一个组件就不用重复的粘贴复制了, 3 // 这个功能需要的数据参数可能根据当前页面会变动,这时候父组件就可以向子组件传参(可以是字符串 数组等),然后在父组件的页面上显示的就是 得到数据或参数 展示的内容 4 // 父组件: 5 // html: 6 <div class="home"> 7 <HelloWorld :newMsg="msg" /> 8 //绑定子组件newMsg(props值) = 父组件msg(data值) 9 </div> 10 // js: 11 import HelloWorld from "@/components/HelloWorld.vue"; 12 export default { 13 name: "Home", 14 data(){ 15 return{msg:'Welcome to Vue.js'} //父组件数据msg 16 }, 17 components: {HelloWorld} 18 }; 19 20 // 子组件: 21 // html: 22 <div> 23 <h1>{{ newMsg }}</h1> //直接调用newMsg,显示“Welcome to Vue.js” 24 </div> 25 // js: 26 export default { 27 name: "HelloWorld", 28 props: {newMsg: String} //为子组件定义newMsg(props值)接收父组件msg 29 //或者props:['newMsg'] 30 }
1 // 子组件向父组件传参: 2 // 子组件被修改(可修改类型) 修改后的内容可传给父组件 父组件接收再走接口等 3 4 // 子组件: 5 export default { 6 name: "HelloWorld", 7 data() { 8 return {msg:"Welcome to Vue"} //data值,即将向上传递的值 9 }, 10 created(){ 11 this.$emit('change',this.msg) //向上传递自定义事件change和data值。这里我调用created生命周期函数触发$emit() 12 } 13 }; 14 // 父组件: 15 // html: 16 <div class="home"> 17 <HelloWorld @change="handle" /> //监听到子组件传递来的事件并响应handle方法 18 <span>{{newMsg}}</span> //直接调用newMsg,显示“Welcome to Vue” 19 </div> 20 // js: 21 import HelloWorld from "@/components/HelloWorld.vue"; 22 export default { 23 name: "Home", 24 data() { 25 return {newMsg:""} 26 }, 27 methods:{ 28 handle(msg){ //定义handle方法,将自动接收到的msg值给了自己的newMsg 29 this.newMsg = msg 30 } 31 }, 32 components: {HelloWorld} 33 };
1 // 非父子组件传参 2 3 // 第一种: 4 // 创建一个公共的js,美其名曰:bus.js作为中间仓库来传值。 5 // bus.js 6 import Vue from 'vue' 7 export default new Vue() 8 9 // A组件: 10 // '$emit' 官网解释: ---事件触发器 11 <span>{{elementValue}}</span> 12 <input type="button" value="点击触发" @click="elementByValue"> 13 14 // 引入公共的bus,来做为中间传达的工具 15 import Bus from './bus.js' 16 export default { 17 data () { 18 return { 19 elementValue: 4 20 } 21 }, 22 methods: { 23 elementByValue: function () { 24 // 通过事件中心去发射'Assembly'自己命名的,方法,this.elementValue为传的参数。 25 Bus.$emit('Assembly', this.elementValue) 26 } 27 } 28 } 29 30 // B组件: 31 // 通过$on方法来接受该方法以及传的参数 32 <input type="button" value="点击触发" @click="getData"> 33 <span>{{name}}</span> 34 35 import Bus from './bus.js' 36 export default { 37 data () { 38 return { 39 name: 0 40 } 41 }, 42 mounted: function () { 43 var vm = this 44 // 用$on事件来接收参数 并且调用了在a组件中出发的方法 45 Bus.$on('Assembly', (data) => { 46 console.log(data) 47 vm.name = data 48 }) 49 }, 50 methods: { 51 getData: function () { 52 this.name++ 53 } 54 } 55 }
1 // 遇到的问题: 2 // 如果A组件点击跳转B组件时传递值 bus.$emit() 3 setPath(){ 4 this.$router.push({ 5 path:'mine/collect', 6 }) 7 }, 8 // 1.显示不到页面上 9 // B组件created接受值 bus.$on() 10 // B组件接收值可打印 但显示不到页面上?? 11 // 当你从页面A到页面B跳转的时候,发生了什么?首先是B组件先created然后beforeMount接着A组件才被销毁,A组件才执行beforeDestory,以及destoryed.
12 // 也就是在A销毁之前,B组件的beforeCreate ,created,和beforeMount这三个钩子函数先触发,之后才是A组件的销毁钩子的触发,因为总线Bus要求要先有监听在触发, 13 // 才能成功监听,所以我们只能在A组件的beforeDestroy或者destroyed这两个生命周期钩子中触发函数emit, 14 // 同理也只能在B组中的beforeCreate,created,和beforeMount这三个钩子函数中监听on。 15 // 所以,我们可以把A页面组件中的emit事件写在beforeDestory中去。因为这个时候,B页面组件已经被created了,也就是我们写的$on事件已经触发了 16 17 // 所以可以在beforeDestory的时候,$emit事件。 18 19 // 2.this指向 20 // bus.$on()的时候,可以使用es6箭头函数,也可使用普通函数(注:使用普通回调函数需要重新定义this指向,否则内容接收到也显示不到页面上)
21 // 3.多次触发 不销毁 22 // 随着页面的切换 事件的触发还是会依次增加,控制台打印次数依次增加 23 24 // 解决:就是说,这个$on事件是不会自动清楚销毁的,需要我们手动来销毁。 25 // 所以在B组件页面中添加Bus.$off来关闭 26 // // 在B组件页面中添加以下语句,在组件beforeDestory的时候销毁。 27 // beforeDestroy () { 28 // bus.$off('get', this.myhandle) 29 // } 30 // 可以看此文章写的挺好的 https://www.jianshu.com/p/fde85549e3b0 31 32 // 非父子传参第二种写法: 33 // 可以不用新建bus.js,直接在main.js中添加创建一个bus, Vue.prototype.bus=new Vue(); 34 // 在非父子组件中用的时候 直接this.bus.$emit() this.bus.$on(),其余的都一样