四、vue3的v-model、组件传值、异步组件、teleport组件
1.v-model
Vue3可以通过v-model指令实现对多个数据的双向绑定
-
<!-- 父级 -->
-
<template>
-
<Five v-model:bg="bg" v-model:mb="mb" v-model:nn="nn" @click="appClick"></Five>
-
</template>
-
<script>
-
import { ref } from 'vue'
-
import Five from './components/Five.vue'
-
export default {
-
name: 'App',
-
components: {
-
Five
-
},
-
setup() {
-
//饼干
-
let bg = ref(5)
-
//面包
-
let mb = ref(8)
-
//牛奶
-
let nn = ref(3)
-
let appClick = (e)=>{
-
alert(e)
-
}
-
return{
-
bg,
-
mb,
-
nn,
-
appClick
-
}
-
}
-
}
-
</script>
-
<!-- 子级 -->
-
<template>
-
<div class="five">
-
<h3>Five</h3>
-
<div class="item">
-
饼干:<button @click="bg--">-</button><input readonly type="text" :value="bg"><button @click="bg "> </button>
-
</div>
-
<div class="item">
-
面包:<button @click="mb--">-</button><input readonly type="text" :value="mb"><button @click="mb "> </button>
-
</div>
-
<div class="item">
-
牛奶:<button @click="nn--">-</button><input readonly type="text" :value="nn"><button @click="nn "> </button>
-
</div>
-
<button @click="fiveClick">点击</button>
-
</div>
-
</template>
-
<script>import { ref, watch } from "vue";
-
export default {
-
// 接收属性
-
props:['bg','mb','nn'],
-
// 放在自定义事件名称跟原生事件名称同名
-
// 这里统一注册自定义事件的名称,
-
// 这样父组件只会触发子组件自定义的事件,不会触发原生事件
-
emits:['click','update:bg','update:mb','update:nn'],
-
setup(props,{emit}) {
-
//获取父组件的传值
-
let bg = ref(props.bg)
-
let mb = ref(props.mb)
-
let nn = ref(props.nn)
-
watch(bg,(val)=>{
-
// 注意:事件名称是update:属性名称
-
emit('update:bg',val)
-
})
-
watch(mb,(val)=>{
-
emit('update:mb',val)
-
})
-
watch(nn,(val)=>{
-
emit('update:nn',val)
-
})
-
let fiveClick = ()=>{
-
// 当我们的自定义事件,跟原生事件重名时,会执行两次
-
emit('click','哈哈!我被点击了!')
-
}
-
return {
-
bg,
-
mb,
-
nn,
-
fiveClick
-
}
-
}
-
};
2.组件传值
1.父子组件传值
父级
-
<template>
-
<div class="app">
-
<div class="box">
-
<div>汽车名称:{{carName}}</div>
-
<div>汽车价格:{{carPrice}}</div>
-
<div>汽车颜色:{{carColor}}</div>
-
<div>汽车产地:{{carAddress}}</div>
-
<!-- 通过props给子组件传值 -->
-
<Three :car-name="carName" :car-price="carPrice"
-
:car-color="carColor" :car-address="carAddress"
-
@change-name="changeName" @change-price="changePrice"
-
@change-color="changeColor" @change-address="changeAddress"></Three>
-
</div>
-
</div>
-
</template>
-
<script>
-
import Three from './components/Three.vue'
-
import { ref } from 'vue'
-
export default {
-
name: 'App',
-
components: {
-
Three
-
},
-
setup() {
-
let carName = ref('奔驰')
-
let carPrice = ref(20)
-
let carColor = ref('红色')
-
let carAddress = ref('德国')
-
-
let changeName = (e)=>{
-
carName.value = e
-
}
-
let changePrice = (e)=>{
-
carPrice.value = e
-
}
-
let changeColor = (e)=>{
-
carColor.value = e
-
}
-
let changeAddress = (e)=>{
-
carAddress.value = e
-
}
-
return{
-
carName,
-
carPrice,
-
carColor,
-
carAddress,
-
changeName,
-
changePrice,
-
changeColor,
-
changeAddress
-
}
-
}
-
}
-
</script>
子级
-
<template>
-
<div class="three">
-
<h3>子组件</h3>
-
<!-- 注意:props接过来的属性,在模板中可以直接修改 -->
-
<div>汽车名称:{{ myCarName }}<button @click="setCarName">修改车名</button></div>
-
<div>汽车价格:{{ myCarPrice }}<button @click="setCarPrice">修改价格</button></div>
-
<div>汽车颜色:{{ myCarColor }}<button @click="setCarColor">修改颜色</button></div>
-
<div>汽车产地:{{ myCarAddress }}<button @click="setCarAddress">修改地址</button></div>
-
</div>
-
</template>
-
<script>
-
import { toRef } from "vue";
-
export default {
-
// props接过来的属性在方法里面是只读的
-
props: ["carName", "carPrice", "carColor"],
-
// 使用vue3中的组合式API写法
-
setup(props,context) {
-
// props返回的是一个Proxy对象,里面保存的是props选项接的属性
-
// context对象里面保存了三个重要属性:attrs,emit,slots
-
// attrs 相当于 this.$arrts
-
// emit 相当于 this.$emit
-
// slots 是插槽信息
-
let myCarName = toRef(props,'carName') //ref(props.carName)
-
let myCarPrice = toRef(props,'carPrice')
-
let myCarColor = toRef(props,'carColor')
-
let myCarAddress = toRef(context.attrs,'car-address')
-
-
let setCarName = ()=>{
-
myCarName = '宝马'
-
context.emit('change-name',myCarName)
-
}
-
let setCarPrice = ()=>{
-
myCarPrice = 30
-
context.emit('change-price',myCarPrice)
-
}
-
let setCarColor = ()=>{
-
myCarColor = '蓝色'
-
context.emit('change-color',myCarColor)
-
}
-
let setCarAddress = ()=>{
-
myCarAddress = '美国'
-
context.emit('change-address',myCarAddress)
-
}
-
-
return{
-
myCarName,
-
myCarPrice,
-
myCarColor,
-
myCarAddress,
-
setCarName,
-
setCarPrice,
-
setCarColor,
-
setCarAddress
-
}
-
}
-
};
-
</script>
2.隔代组件传值
父级
-
setup() {
-
//定义数据
-
let name = ref('张三')
-
let age = ref(20)
-
//汽车数据
-
let car = reactive({
-
name:'大众',
-
color:'黑色'
-
})
-
//修改汽车的名称
-
let updateCarName = (val)=>{
-
car.name = val
-
}
-
//修改汽车的价格
-
let updateCarColor = (val)=>{
-
car.color = val
-
}
-
// 定义依赖数据
-
// provide方法的第一个参数是key,第二个参数是value
-
provide('name',name)
-
provide('age',age)
-
// 将两个修汽车信息的方法,作为依赖数据传出去
-
provide('updateCarName',updateCarName)
-
provide('updateCarColor',updateCarColor)
-
return{
-
name,
-
age,
-
car,
-
}
-
}
子级
-
<template>
-
<div class="two">
-
<h3>Two</h3>
-
<div>姓名:{{ myName }}</div>
-
<div>年龄:{{ myAge }}</div>
-
<button @click="updateName">修改姓名</button>
-
<button @click="updateAge">修改年龄</button>
-
<button @click="updateCarName('比亚迪')">修改汽车名称</button>
-
<button @click="updateCarColor('黄色')">修改汽车颜色</button>
-
</div>
-
</template>
-
<script>
-
import { inject } from "vue";
-
export default {
-
setup() {
-
// 通过inject注入父级的依赖数据集
-
let myName = inject("name");
-
let myAge = inject("age");
-
let updateName = () => {
-
myName.value = "李四";
-
};
-
let updateAge = () => {
-
myAge.value = "王五";
-
};
-
-
// 通过inject注入两个方法
-
let updateCarName = inject("updateCarName");
-
let updateCarColor = inject("updateCarColor");
-
-
return {
-
myName,
-
myAge,
-
updateName,
-
updateAge,
-
updateCarName,
-
updateCarColor,
-
};
-
},
-
};
-
</script>
3.兄弟组件传值
1.下载mitt :npm i mitt
2.main.js中导入mitt
-
import { createApp } from 'vue'
-
import App from './App.vue'
-
-
//导入插件mitt(第三方中央事件中线库)
-
import mitt from "mitt"
-
-
//创建一个Vue实例
-
let app = createApp(App)
-
-
//挂载事务总线为全局属性
-
// config.globalProperties 就相当于返回Vue的原型对象
-
app.config.globalProperties.$bus = new mitt()
-
-
//将Vue实例挂载到#app容器中
-
app.mount('#app')
3. 监听事件
-
<script>
-
// getCurrentInstance方法,用于在setup函数中获取当前组件实例
-
import {ref,getCurrentInstance} from 'vue'
-
export default {
-
// vue3推崇的写法
-
setup() {
-
// 获取当前组件实例 不等同于this
-
let $this = getCurrentInstance()
-
// $this.appContext 获取当前项目中的Vue实例
-
let dogName = ref('琪琪')
-
let dogSex = ref('女生')
-
-
//监听事件
-
$this.appContext.config.globalProperties.$bus.on('update-dog-name',(e)=>{
-
dogName.value = e
-
})
-
$this.appContext.config.globalProperties.$bus.on('update-dog-sex',(e)=>{
-
dogSex.value = e
-
})
-
return {
-
dogName,
-
dogSex
-
}
-
}
-
}
-
</script>
4.触发事件
-
<template>
-
<div class="four">
-
<h3>Four</h3>
-
<button @click="updateDogName">修改狗狗昵称</button>
-
<button @click="updateDogSex">修改狗狗性别</button>
-
</div>
-
</template>
-
<script>
-
import {getCurrentInstance} from 'vue'
-
export default {
-
setup() {
-
//获取当前组件实例
-
let $this = getCurrentInstance()
-
let updateDogName = ()=>{
-
$this.appContext.config.globalProperties.$bus.emit('update-dog-name','天天')
-
}
-
let updateDogSex = ()=>{
-
$this.appContext.config.globalProperties.$bus.emit('update-dog-sex','男生')
-
}
-
return {
-
updateDogName,
-
updateDogSex
-
}
-
}
-
};
-
</script>
3.异步组件
-
<template>
-
<div class="home">
-
<h1>首页</h1>
-
<One></One>
-
<!-- suspense内置组件,用于加载异步组件,添加loading效果 -->
-
<suspense>
-
<!-- default插槽里面放置异步组件 -->
-
<template #default>
-
<Two></Two>
-
</template>
-
<!-- fallback插槽里面制作loading效果 -->
-
<template #fallback>
-
Loading...
-
</template>
-
</suspense>
-
<!-- 异步组件,可以不用suspense,
-
但是如果异步组件内部的setup函数返回的是一个Promise对象,
-
此时的异步组件就必须要使用suspense -->
-
<suspense>
-
<template #default>
-
<Three></Three>
-
</template>
-
<template #fallback>
-
Loading...
-
</template>
-
</suspense>
-
<!-- <Three></Three> -->
-
</div>
-
</template>
-
-
<script>
-
// defineAsyncComponent方法,用于异步加载组件
-
import {defineAsyncComponent} from 'vue'
-
import One from '../components/One.vue'
-
// import Two from './components/Two.vue'
-
// 异步导入Two组件和Three
-
let Two = defineAsyncComponent(()=>import('../components/Two.vue'))
-
// 注意:如果组件中setup方法返回的是Promise对象,那么组件必须要采用异步的方式加载
-
// import Three from './components/Three.vue'
-
let Three = defineAsyncComponent(()=>import('../components/Three.vue'))
-
export default {
-
name: 'App',
-
components: {
-
One,
-
Two,
-
Three
-
}
-
}
-
</script>
4.teleport组件
-
<button @click="show=true">显示</button>
-
<!-- teleport组件:官方起的名称:瞬移。通过to属性确定里面的元素移动到哪 -->
-
<teleport to="body">
-
<div v-show="show" class="box">
-
<button @click="show=false">关闭</button>
-
<div>{{dog}}</div>
-
</div>
-
</teleport>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbebbb
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01