props跟$emit(只能用于父子组件)
- props:父组件向子组件传递信息
父组件中:引用子组件。然后在其引用的子组件中绑定传递信息
<template>
<div>
<Son :myprop="mypropdata"></Son>
</div>
</template>
<script>
import Son from '@/components/Son.vue';
export default {
data(){
return {
mypropdata:"父级里的数据"
}
},
components: {
Son
}
};
</script>
子组件中:用props:["绑定信息"] 直接获取
<template>
<div>
子组件数据:{{myprop}}
</div>
</template>
<script>
export default {
props: ["myprop"],
};
</script>
最终浏览器显示内容: 子组件数据:父级里的数据
- $emit:子组件触发父组件的自定义事件,来向父组件传递信息
子组件中:触发父级自定义事件,并传入数据
<template>
<div>
<button @click="toparent">点击改变父组件</button>
</div>
</template>
<script>
export default {
methods: {
toparent() {
this.$emit("changeparent","子组件的数据") //“子组件的数据“作为值传递到父组件的自定义方法中
},
},
};
父组件中:通过定义的自定义事件,获取子组件传递的数据
<template>
<div>
<Son @changeparent="daddatashow"></Son>
获取的子组件数据:{{getdata}}
</div>
</template>
<script>
import Son from '@/components/Son.vue';
export default {
data(){
return {
getdata:""
}
},
components: {
Son
},
methods:{
daddatashow(data) {
this.getdata = data;
}
}
};
</script>
最终浏览器显示: 获取的子组件数据:子组件的数据
- 注意:props接收父组件参数,父组件的值发生变化,在created或mounted阶段都是初始值。只有利用watch监听数据变化(如果发现没打印,那么肯定是watch写重了,检查一下)
watch:{
good_id: {
handler(newval) {
if (newval) {
console.log("newgood_id---", newval)
}
},
immediate: true
}
}
provide 跟 inject(祖先等有层级组件)
provide/inject 绑定默认并不是响应式的,但是如果provide传入可监听的对象,也可以是响应式的。
可以理解为react的context上下文,目的就是provide向后续组件传值,inject接受数据
这种写死的,他就不是响应式的。只能接受一个固定的值
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
}
以下就是响应式的。可用于接口数据获取后的子组件处理
祖先组件
data(){
return {
natureObj:{nature:""}
}
},
provide() {
return {
//provide实现响应式。这里必须是响应式对象
natureSon: this.natureObj,
}
},
methods:{
//如果调用此自定义方法,那么子组件会响应式的改变(场景:请求接口后返回的)
getinfo(){
this.natureObj.nature= "111111"
}
}
子组件
inject: ["natureSon"],
created(){
console.log(this.natureSon) //111111
}
$emit 跟 $on(非父子任意组件)
- 先在main.js中把eventBus设置为全局变量(这样各个层级就没有限制了)
Vue.prototype.$bus = new Vue(); //这个$bus随意命名,反正意思是添加到vue原型中。因为$emit跟$on的this指向需要是同一个vue实例
- $emit:通过触发事件,发送数据
<template>
<div>
<button @click="toothers">点击向其他组件传递信息</button>
</div>
</template>
<script>
export default {
methods:{
toothers(){
//这个事件名随意定义,只要统一就行。 “发送的数据”作为值传递到接收方法中
this.$bus.$emit("sendandget","发送的数据")
}
}
}
</script>
- $on:通过接收事件,接收数据
<template>
<div>
接收到的数据:{{getdata}}
</div>
</template>
<script>
export default {
data() {
return {
getdata:""
};
created() {
this.$bus.$on("sendandget",res=>{
this.getdata = res;
})
},
}
</script>
最终浏览器显示: 接收到的数据:发送的数据
ref 和 $refs
- 标签通过ref来命名
- 使用通过this.$refs.命名 获取ref对应标签及内部内容
<template>
<div>
<div ref="mydiv">我是div</div>
<Son ref="sonCom"></Son>
<button @click="getSon">点击获取children</button>
</div>
</template>
<script>
import Son from "@/components/Son.vue";
export default {
methods: {
getSon(){
console.log(this.$refs.mydiv); //打印:<div ref="mydiv">我是div</div>
console.log(this.$refs.sonCom); //打印:Son这个组件的全部
console.log(this.$refs.sonCom.myname); //打印:子组件我的名字 。
}
}
}
</script>
子组件Son.vue
<template>
<div>我是子组件 </div>
</template>
<script>
export default {
data () {
return {
myname:"子组件我的名字"
}
},
}
</script>
其他方式
- 个人水平有限,感觉上面几个就可以了。复杂的用vuex处理
- $children 和 $parent
- $attrs 和 $listeners