祖孙组件间传值
Vue3中的祖孙组件间的传值:
①父组件通过使用provide()方法,定义依赖数据。
proviede(名称,传输的数据名)记得返回出去
②子组件通过inject接收:let xx=inject(名称)
③修改的话直接通过事件.value修改数据,比起Vue2修改值少了转换和发送自定义事件步骤
Vue2的祖孙组件间的传值
①父组件通过provide(){return{name:this.name}}函数定义依赖数据
②子组件通过inject:[]接收父组件传递参数
③修改值要写方法,只有父级变了它才会变。所以给父级定义个方法,再通过provide()依赖传递(不仅可以依赖数据,还可以依赖方法),在子孙组件方法中调用父级定义的方法并传实参过去。
父组件
<template>
<div class="son">
<h2>Son1</h2>
<ul>
<li>车名:{{carName}}</li>
<li>车价:{{carPrice}}</li>
</ul>
<SubSon/>
</div>
</template>
<script>
import {inject} from 'vue'
import SubSon from "./SubSon.vue";
export default {
name: "Son",
setup() {
let carName = inject('carName')
let carPrice = inject('carPrice')
return{
carName,
carPrice
}
},
components: {
SubSon,
},
data() {
return {
name:'张三',
age:20
}
},
Vue2中的祖孙组件传递数据并更改数据
// 定义依赖数据
provide(){
return{
name:this.name,
age:this.age,
updateData:this.updateData
}
},
methods: {
// 定义修改数据方法
updateDate(name,age){
this.name=name
this.age=age
}
},
};
子孙组件
<template>
<div class="subSon">
<h2>SubSon</h2>
<ul>
<li>姓名:{{name}}</li>
<li>年龄:{{age}}</li>
<li>
<button @click="update">修改信息</button>
</li>
</ul>
</div>
</template>
<script>
import {inject} from 'vue'
export default {
name: "SubSon",
setup() {
//inject()方法,用于注入父级中依赖的数据
let name = inject('name')
let age = inject('age')
let update = ()=>{
name.value = '李四'
age.value = 30
}
return {
name,
age,
update
}
}
Vue2中的祖孙组件传递数据并更改数据
inject:['name','age','updatedate'],
data() {
return {
myName:this.name,
myAge:this.age
}
},
methods: {
update(){
// 修改自己
this.myName='李四'
this.myAge='20'
// 修改父级
this.updateData('李四',30)
}
},
};
</script>
兄弟组件传值
Vue2中Vue是个构造函数,所以兄弟组件传值,用中央事件总线,给vue的实例添加数据。
而在Vue3中Vue是个对象,所以无法再使用给实例添加数据的方式。我们可以把数据都给父级再去修改。
注意:在Vue3中不使用的数据就不需要返回
Vue3的兄弟组件传值 数据提升的方式
①在共同的父级定义数据和方法。父级通过provide(子级接收名,传递的值)方法设置为依赖数据
②子级在inject(子级接收名)方法中接收数据,页面中直接使用,记得return
③另一个子组件在inject()方法中接收修改数据的方法,并绑定点击事件
父级
<template>
<div class="app">
<h2>App</h2>
<ul>
<li>姓名:{{name}}</li>
<li>年龄:{{age}}</li>
</ul>
<ul>
<li>飞机名称:{{planeName}}</li>
<li>飞机价格:{{planePrice}}</li>
<li>飞机产地:{{planeAddress}}</li>
</ul>
<!-- suspense内置组件,用于在渲染异步组件时,添加Loading效果 -->
<!-- 注意:
1.异步组件可以不使用suspense组件,但是会失去异步的作用
2.如果组件中setup的返回值是一个Promise对象,那么该组件在导入时,必须采用异步方式导入;
并且该组件必须要使用suspense组件-->
<suspense>
<!-- default插槽里面放置异步组件 -->
<template #default>
<Son4/>
</template>
<!-- fallback插槽里面放置组件没有加载完成时显示的内容 -->
<template #fallback>
Loading...
</template>
</suspense>
<Son/>
<Son2/>
<!-- 在vue3中子定义组件时,v-model可以使用多次,实现对多个数据的双向绑定,
注意:vue3取消了sync修饰符,它将v-model指令和sync修饰符进行了合并。 -->
<Son3 v-model:planeName="planeName"
v-model:planePrice="planePrice" v-model:planeAddress="planeAddress" />
</div>
</template>
<script>
import {ref,provide,defineAsyncComponent} from 'vue'
import Son from './components/Son.vue'
import Son2 from './components/Son2.vue'
import Son3 from './components/Son3.vue'
// defineAsyncComponent组合式API,用于定义异步组件
// 异步导入组件
const Son4 = defineAsyncComponent(()=>import('./components/Son4.vue'))
export default {
name: 'App',
setup() {
let name = ref('张三')
let age = ref(20)
let carName = ref('保时捷')
let carPrice = ref(100)
let updateCar = (name,price)=>{
carName.value = name
carPrice.value = price
}
//通过provide()方法,定义依赖数据,从此它的子组件,就可以获取这些数据了
provide('name',name)
provide('age',age)
provide('carName',carName)
provide('carPrice',carPrice)
provide('updateCar',updateCar)
//定义飞机的相关数据
let planeName = ref('波音747')
let planePrice = ref(100)
let planeAddress = ref('美国')
return {
name,
age,
//返回飞机相关信息
planeName,
planePrice,
planeAddress
}
},
components: {
Son,
Son2,
Son3,
Son4
}
/* data() {
return {
name:'张三',
age:20
}
},
methods: {
//修改数据的方法
updateData(name,age){
this.name = name
this.age = age
}
},
//定义依赖数据
provide(){
return {
name:this.name,
age:this.age,
updateData:this.updateData
}
}, */
}
</script>
子级
<template>
<div class="son2">
<h2>Son2</h2>
<button @click="updateCar">修改汽车信息</button>
</div>
</template>
<script>
import {inject} from 'vue'
export default {
name: "Son2",
setup() {
let updateCar = inject('updateCar')
let update=()=> {
updateCar('奔奔车',1000)
}
}
};
</script>
Vue2和Vue3中的自定义组件
Vue2中
①父级给子组件绑定属性为:value=xx,绑定事件为@input=xx,就可以使用语法糖sync:属性=xx,
②子级通过props接收的值,可直接在页面中使用
③子级修改父级数据自定义事件$emit('update:属性',修改的值)
Vue3中
①父级给子组件绑定属性为:value=xx,绑定事件为@input=xx,就可以使用语法糖v-model:属性=xx,
②子级通过props接收的值可直接在页面使用(父级必须把数据return出去,子级才可使用)。
③子级要修改接收的父级数据,直接通过setup()中第二个参数context的emit方法。emit('update:属性',修改的值)
<div class="son3">
<h2>Son3</h2>
<ul>
<li>飞机名称:{{planeName}}</li>
<li>飞机价格:{{planePrice}}</li>
<li>飞机地址:{{planeAddress}}</li>
<li><button @click="updatePlaneName">修改飞机名称</button></li>
<li><button @click="updatePlanePrice">修改飞机价格</button></li>
<li><button @click="updatePlaneAddress">修改飞机产地</button></li>
</ul>
</div>
</template>
<script>
export default {
name:'Son3',
props:['planeName',"planePrice","planeAddress"],
setup(props,{emit}) {
let updatePlaneName=()=>{
// planeName.value="长城1号" //改自己的名称
// console.log(planeName);
// 事件方法必须是uptate:prop(属性),如果父组件中采用的是v-model
// 此时父组件就可以实现对prop的双向数据绑定
emit('update:planeName','长城1号')
}
let updatePlaneAddress=()=>{
// planeAddress.value="中国" //改自己的名称
emit('update:planeAddress','中国')
}
let updatePlanePrice=()=>{
// planePrice.value=1000 //改自己的名称
emit('update:planePrice',1000)
}
return{
updatePlanePrice,
updatePlaneAddress,
updatePlaneName
}
}
}