vue组件相关props,$parents , $children, $refs , provide / inject 使用
程序员文章站
2024-03-15 10:53:05
...
组件基本需要这三部分组成
props(属性)
event(事件)
slot(插槽)
父子组件通信
# App.vue (父组件)
<template>
<div id="app">
<Child :msg="messsage" :model="obj" :myArr="arr"/>
</div>
</template>
<script>
import Child from './components/Child'
export default {
name: 'app',
components: {
Child
},
data(){
return{
messsage:'我是父组件的数据',
obj:{
name: "hello",
age:15,
},
arr:[1,2,3,4],
}
}
}
</script>
# Child.vue (子组件)
<template>
<div>
<h1>{{ msg }}</h1>
<h2>{{ model.name }} - {{model.age}}</h2>
<ul>
<li v-for="(item,index) in myArr" :key="index">
{{item}}
</li>
</ul>
</div>
</template>
<script>
export default {
// props 里 推荐使用对象写法,用于组件的数据结构校验
/** 父子组件传值 */
props: {
// 父组件传入的属性是一个基本数据类型
msg: {
type: String,
default: '',
},
// 父组件传入的属性是一个对象
model: {
type: Object,
default: () => {},
required:true,
},
// 父组件 传入 一个数组
myArr:{
type:Array,
default:() => [],
}
}
}
</script>
<style scoped>
</style>
子向父组件通信 ( $on, $emit)
# 子组件 Child.vue
<template>
<div>
<h1>{{ msg }}</h1>
<button @click="changeHandle">change父组件的值</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: '',
},
},
methods:{
changeHandle(){
this.$emit("changeParent","我是子组件的值")
}
}
}
</script>
# 父组件 App.vue
<template>
<div id="app">
<Child @changeParent="getChildData" :msg="messsage"/>
</div>
</template>
<script>
import Child from './components/Child'
export default {
name: 'app',
components: {
Child
},
data(){
return{
messsage:'我是父组件的数据',
}
},
methods:{
getChildData(params){
this.messsage = params;
}
}
}
</script>
子组件通过 $parent 获取父组件的数据
# Child.vue (子组件)
<template>
<div>
<!-- this.$parent.messsage -->
<h1>{{ this.$parent.messsage }}</h1>
<button @click="changeHandle">change父组件的值</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: '',
},
},
methods:{
changeHandle(){
this.$emit("changeParent","我是子组件的值")
}
}
}
</script>
# App.vue (父组件)
<template>
<div id="app">
<Child @changeParent="getChildData" :msg="messsage"/>
</div>
</template>
<script>
import Child from './components/Child'
export default {
name: 'app',
components: {
Child
},
data(){
return{
messsage:'我是父组件的数据',
}
},
methods:{
getChildData(params){
this.messsage = params;
}
}
}
</script>
父组件通过($children) 获取子组件的值
# App.vue (父组件)
<template>
<div id="app">
<h1>{{messsage}}</h1>
<Child :msg="messsage"/>
<!-- <Other :msg="messsage"/> -->
<p>{{leader}}</p>
</div>
</template>
<script>
import Child from './components/Child'
// import Other from './components/Other'
export default {
name: 'app',
components: {
Child,
// Other,
},
data(){
return{
messsage:'我是父组件的数据',
leader:'',
}
},
mounted(){
this.$children.map(res=>{
console.log(res)
this.leader = res.miss
})
}
}
</script>
# Child.vue(子组件1)
<template>
<div>
<Other/>
<button @click="changeHandle">change父组件的值</button>
</div>
</template>
<script>
import Other from './Other'
export default {
components:{
Other,
},
props: {
msg: {
type: String,
default: '',
},
},
data(){
return{
message:"我是子组件的值",
miss:'我是Child'
}
},
methods:{
changeHandle(){
this.message = "hello"
}
}
}
</script>
# Other.vue(子组件2)
<template>
<div>
<h3>我是other</h3>
</div>
</template>
<script>
export default {
data(){
return{
miss:'我是other组件'
}
}
}
</script>
响应动态数据的变化
# App.vue (父组件)
<template>
<div id="app">
<Child :msg="Arr" />
<button @click="changeHandle">点击改变子组件中渲染的值 </button>
</div>
</template>
<script>
import Child from './components/Child'
export default {
name: 'app',
components: {
Child,
},
data() {
return {
messsage: '我是父组件的数据',
num: 1,
Arr:[1,2,3,4],
}
},
methods: {
changeHandle() {
this.$set(this.Arr,2,{a:1})
}
}
}
</script>
# Child.vue (子组件)
<template>
<div>
<ul>
<li v-for="(item,index) in msg" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
props: {
msg: {
type: Array,
default: ()=>[],
},
},
// 这个版本现在不需要作监听也能响应父组件动态数据的变化了(以前是不行的)
watch:{
msg(oldValue,newValue){
console.log(newValue);
}
},
data(){
return{
message:"我是子组件的值",
}
},
methods:{
changeHandle(){
}
}
}
</script>
一种无依赖的组件通信:provide / inject 接口
# App.vue
<template>
<div>
app
<Brother />
<Child />
</div>
</template>
<script>
import Brother from './components/Brother'
import Child from './components/Child'
export default {
components: {
Brother,
Child,
},
provide: {
name: 'App父组件的值'
},
data() {
return {
}
}
}
</script>
<style scoped>
</style>
# Child.vue
<template>
<div>
Child组件
{{name}}
</div>
</template>
<script>
export default {
inject: ['name'],
data(){
return{
}
}
}
</script>
<style scoped>
</style>
# Brother.vue
<template>
<div>
兄弟组件
{{this.name}}
<Child/>
</div>
</template>
<script>
import Child from "./Child";
export default {
components:{
Child
},
data() {
return {
msg:'',
}
},
inject: ['name'],
}
</script>
<style scoped>
</style>
Vue 官方提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的
通过 $refs 获取子组件的值
此方法只能获取值,不能响应数据变化
# App.vue
<template>
<div>
<Brother ref="brother"/>
{{myda}}
</div>
</template>
<script>
import Brother from './components/Brother'
export default {
components: {
Brother,
},
data(){
return{
myda:"",
}
},
mounted(){
this.myda = this.$refs.brother.msg
},
}
</script>
# Brother.vue
<template>
<div>
兄弟组件
</div>
</template>
<script>
export default {
data() {
return {
msg:'我是Brother组件',
}
}
}
</script>
兄弟组件通信(同样适用于跨级组件通信)
//*事件总线
var bus=new Vue();
// 还是利用 $on 和 $emit 的监听和发射
var app=new Vue({
el:'#app',
template:`
<div>
<A1></A1>
<A2></A2>
</div>
`
})
// 在组件 A1 的 methods 方法中触发事件
bus.$emit('say-hello', 'world')
// 在组件 A2 的 created 钩子函数中监听事件
bus.$on('say-hello', function (arg) {
console.log('hello ' + arg); // hello world
})
插槽 .... 略过,已经写过如何使用!
上一篇: 泛型数组堆栈
下一篇: vue2.0父子组件间通信