• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

四、vue3的v-model、组件传值、异步组件、teleport组件

武飞扬头像
默默229
帮助1

1.v-model

Vue3可以通过v-model指令实现对多个数据的双向绑定

  1.  
    <!-- 父级 -->
  2.  
    <template>
  3.  
    <Five v-model:bg="bg" v-model:mb="mb" v-model:nn="nn" @click="appClick"></Five>
  4.  
    </template>
  5.  
    <script>
  6.  
    import { ref } from 'vue'
  7.  
    import Five from './components/Five.vue'
  8.  
    export default {
  9.  
    name: 'App',
  10.  
    components: {
  11.  
    Five
  12.  
    },
  13.  
    setup() {
  14.  
    //饼干
  15.  
    let bg = ref(5)
  16.  
    //面包
  17.  
    let mb = ref(8)
  18.  
    //牛奶
  19.  
    let nn = ref(3)
  20.  
    let appClick = (e)=>{
  21.  
    alert(e)
  22.  
    }
  23.  
    return{
  24.  
    bg,
  25.  
    mb,
  26.  
    nn,
  27.  
    appClick
  28.  
    }
  29.  
    }
  30.  
    }
  31.  
    </script>
学新通
  1.  
    <!-- 子级 -->
  2.  
    <template>
  3.  
    <div class="five">
  4.  
    <h3>Five</h3>
  5.  
    <div class="item">
  6.  
    饼干:<button @click="bg--">-</button><input readonly type="text" :value="bg"><button @click="bg "> </button>
  7.  
    </div>
  8.  
    <div class="item">
  9.  
    面包:<button @click="mb--">-</button><input readonly type="text" :value="mb"><button @click="mb "> </button>
  10.  
    </div>
  11.  
    <div class="item">
  12.  
    牛奶:<button @click="nn--">-</button><input readonly type="text" :value="nn"><button @click="nn "> </button>
  13.  
    </div>
  14.  
    <button @click="fiveClick">点击</button>
  15.  
    </div>
  16.  
    </template>
  17.  
    <script>import { ref, watch } from "vue";
  18.  
    export default {
  19.  
    // 接收属性
  20.  
    props:['bg','mb','nn'],
  21.  
    // 放在自定义事件名称跟原生事件名称同名
  22.  
    // 这里统一注册自定义事件的名称,
  23.  
    // 这样父组件只会触发子组件自定义的事件,不会触发原生事件
  24.  
    emits:['click','update:bg','update:mb','update:nn'],
  25.  
    setup(props,{emit}) {
  26.  
    //获取父组件的传值
  27.  
    let bg = ref(props.bg)
  28.  
    let mb = ref(props.mb)
  29.  
    let nn = ref(props.nn)
  30.  
    watch(bg,(val)=>{
  31.  
    // 注意:事件名称是update:属性名称
  32.  
    emit('update:bg',val)
  33.  
    })
  34.  
    watch(mb,(val)=>{
  35.  
    emit('update:mb',val)
  36.  
    })
  37.  
    watch(nn,(val)=>{
  38.  
    emit('update:nn',val)
  39.  
    })
  40.  
    let fiveClick = ()=>{
  41.  
    // 当我们的自定义事件,跟原生事件重名时,会执行两次
  42.  
    emit('click','哈哈!我被点击了!')
  43.  
    }
  44.  
    return {
  45.  
    bg,
  46.  
    mb,
  47.  
    nn,
  48.  
    fiveClick
  49.  
    }
  50.  
    }
  51.  
    };
学新通

2.组件传值

1.父子组件传值

父级

  1.  
    <template>
  2.  
    <div class="app">
  3.  
    <div class="box">
  4.  
    <div>汽车名称:{{carName}}</div>
  5.  
    <div>汽车价格:{{carPrice}}</div>
  6.  
    <div>汽车颜色:{{carColor}}</div>
  7.  
    <div>汽车产地:{{carAddress}}</div>
  8.  
    <!-- 通过props给子组件传值 -->
  9.  
    <Three :car-name="carName" :car-price="carPrice"
  10.  
    :car-color="carColor" :car-address="carAddress"
  11.  
    @change-name="changeName" @change-price="changePrice"
  12.  
    @change-color="changeColor" @change-address="changeAddress"></Three>
  13.  
    </div>
  14.  
    </div>
  15.  
    </template>
  16.  
    <script>
  17.  
    import Three from './components/Three.vue'
  18.  
    import { ref } from 'vue'
  19.  
    export default {
  20.  
    name: 'App',
  21.  
    components: {
  22.  
    Three
  23.  
    },
  24.  
    setup() {
  25.  
    let carName = ref('奔驰')
  26.  
    let carPrice = ref(20)
  27.  
    let carColor = ref('红色')
  28.  
    let carAddress = ref('德国')
  29.  
     
  30.  
    let changeName = (e)=>{
  31.  
    carName.value = e
  32.  
    }
  33.  
    let changePrice = (e)=>{
  34.  
    carPrice.value = e
  35.  
    }
  36.  
    let changeColor = (e)=>{
  37.  
    carColor.value = e
  38.  
    }
  39.  
    let changeAddress = (e)=>{
  40.  
    carAddress.value = e
  41.  
    }
  42.  
    return{
  43.  
    carName,
  44.  
    carPrice,
  45.  
    carColor,
  46.  
    carAddress,
  47.  
    changeName,
  48.  
    changePrice,
  49.  
    changeColor,
  50.  
    changeAddress
  51.  
    }
  52.  
    }
  53.  
    }
  54.  
    </script>
学新通

子级

  1.  
    <template>
  2.  
    <div class="three">
  3.  
    <h3>子组件</h3>
  4.  
    <!-- 注意:props接过来的属性,在模板中可以直接修改 -->
  5.  
    <div>汽车名称:{{ myCarName }}<button @click="setCarName">修改车名</button></div>
  6.  
    <div>汽车价格:{{ myCarPrice }}<button @click="setCarPrice">修改价格</button></div>
  7.  
    <div>汽车颜色:{{ myCarColor }}<button @click="setCarColor">修改颜色</button></div>
  8.  
    <div>汽车产地:{{ myCarAddress }}<button @click="setCarAddress">修改地址</button></div>
  9.  
    </div>
  10.  
    </template>
  11.  
    <script>
  12.  
    import { toRef } from "vue";
  13.  
    export default {
  14.  
    // props接过来的属性在方法里面是只读的
  15.  
    props: ["carName", "carPrice", "carColor"],
  16.  
    // 使用vue3中的组合式API写法
  17.  
    setup(props,context) {
  18.  
    // props返回的是一个Proxy对象,里面保存的是props选项接的属性
  19.  
    // context对象里面保存了三个重要属性:attrs,emit,slots
  20.  
    // attrs 相当于 this.$arrts
  21.  
    // emit 相当于 this.$emit
  22.  
    // slots 是插槽信息
  23.  
    let myCarName = toRef(props,'carName') //ref(props.carName)
  24.  
    let myCarPrice = toRef(props,'carPrice')
  25.  
    let myCarColor = toRef(props,'carColor')
  26.  
    let myCarAddress = toRef(context.attrs,'car-address')
  27.  
     
  28.  
    let setCarName = ()=>{
  29.  
    myCarName = '宝马'
  30.  
    context.emit('change-name',myCarName)
  31.  
    }
  32.  
    let setCarPrice = ()=>{
  33.  
    myCarPrice = 30
  34.  
    context.emit('change-price',myCarPrice)
  35.  
    }
  36.  
    let setCarColor = ()=>{
  37.  
    myCarColor = '蓝色'
  38.  
    context.emit('change-color',myCarColor)
  39.  
    }
  40.  
    let setCarAddress = ()=>{
  41.  
    myCarAddress = '美国'
  42.  
    context.emit('change-address',myCarAddress)
  43.  
    }
  44.  
     
  45.  
    return{
  46.  
    myCarName,
  47.  
    myCarPrice,
  48.  
    myCarColor,
  49.  
    myCarAddress,
  50.  
    setCarName,
  51.  
    setCarPrice,
  52.  
    setCarColor,
  53.  
    setCarAddress
  54.  
    }
  55.  
    }
  56.  
    };
  57.  
    </script>
学新通

2.隔代组件传值

父级

  1.  
    setup() {
  2.  
    //定义数据
  3.  
    let name = ref('张三')
  4.  
    let age = ref(20)
  5.  
    //汽车数据
  6.  
    let car = reactive({
  7.  
    name:'大众',
  8.  
    color:'黑色'
  9.  
    })
  10.  
    //修改汽车的名称
  11.  
    let updateCarName = (val)=>{
  12.  
    car.name = val
  13.  
    }
  14.  
    //修改汽车的价格
  15.  
    let updateCarColor = (val)=>{
  16.  
    car.color = val
  17.  
    }
  18.  
    // 定义依赖数据
  19.  
    // provide方法的第一个参数是key,第二个参数是value
  20.  
    provide('name',name)
  21.  
    provide('age',age)
  22.  
    // 将两个修汽车信息的方法,作为依赖数据传出去
  23.  
    provide('updateCarName',updateCarName)
  24.  
    provide('updateCarColor',updateCarColor)
  25.  
    return{
  26.  
    name,
  27.  
    age,
  28.  
    car,
  29.  
    }
  30.  
    }
学新通

子级

  1.  
    <template>
  2.  
    <div class="two">
  3.  
    <h3>Two</h3>
  4.  
    <div>姓名:{{ myName }}</div>
  5.  
    <div>年龄:{{ myAge }}</div>
  6.  
    <button @click="updateName">修改姓名</button>
  7.  
    <button @click="updateAge">修改年龄</button>
  8.  
    <button @click="updateCarName('比亚迪')">修改汽车名称</button>
  9.  
    <button @click="updateCarColor('黄色')">修改汽车颜色</button>
  10.  
    </div>
  11.  
    </template>
  12.  
    <script>
  13.  
    import { inject } from "vue";
  14.  
    export default {
  15.  
    setup() {
  16.  
    // 通过inject注入父级的依赖数据集
  17.  
    let myName = inject("name");
  18.  
    let myAge = inject("age");
  19.  
    let updateName = () => {
  20.  
    myName.value = "李四";
  21.  
    };
  22.  
    let updateAge = () => {
  23.  
    myAge.value = "王五";
  24.  
    };
  25.  
     
  26.  
    // 通过inject注入两个方法
  27.  
    let updateCarName = inject("updateCarName");
  28.  
    let updateCarColor = inject("updateCarColor");
  29.  
     
  30.  
    return {
  31.  
    myName,
  32.  
    myAge,
  33.  
    updateName,
  34.  
    updateAge,
  35.  
    updateCarName,
  36.  
    updateCarColor,
  37.  
    };
  38.  
    },
  39.  
    };
  40.  
    </script>
学新通

3.兄弟组件传值

1.下载mitt :npm i mitt

2.main.js中导入mitt

  1.  
    import { createApp } from 'vue'
  2.  
    import App from './App.vue'
  3.  
     
  4.  
    //导入插件mitt(第三方中央事件中线库)
  5.  
    import mitt from "mitt"
  6.  
     
  7.  
    //创建一个Vue实例
  8.  
    let app = createApp(App)
  9.  
     
  10.  
    //挂载事务总线为全局属性
  11.  
    // config.globalProperties 就相当于返回Vue的原型对象
  12.  
    app.config.globalProperties.$bus = new mitt()
  13.  
     
  14.  
    //将Vue实例挂载到#app容器中
  15.  
    app.mount('#app')
学新通

3. 监听事件

  1.  
    <script>
  2.  
    // getCurrentInstance方法,用于在setup函数中获取当前组件实例
  3.  
    import {ref,getCurrentInstance} from 'vue'
  4.  
    export default {
  5.  
    // vue3推崇的写法
  6.  
    setup() {
  7.  
    // 获取当前组件实例 不等同于this
  8.  
    let $this = getCurrentInstance()
  9.  
    // $this.appContext 获取当前项目中的Vue实例
  10.  
    let dogName = ref('琪琪')
  11.  
    let dogSex = ref('女生')
  12.  
     
  13.  
    //监听事件
  14.  
    $this.appContext.config.globalProperties.$bus.on('update-dog-name',(e)=>{
  15.  
    dogName.value = e
  16.  
    })
  17.  
    $this.appContext.config.globalProperties.$bus.on('update-dog-sex',(e)=>{
  18.  
    dogSex.value = e
  19.  
    })
  20.  
    return {
  21.  
    dogName,
  22.  
    dogSex
  23.  
    }
  24.  
    }
  25.  
    }
  26.  
    </script>
学新通

4.触发事件 

  1.  
    <template>
  2.  
    <div class="four">
  3.  
    <h3>Four</h3>
  4.  
    <button @click="updateDogName">修改狗狗昵称</button>
  5.  
    <button @click="updateDogSex">修改狗狗性别</button>
  6.  
    </div>
  7.  
    </template>
  8.  
    <script>
  9.  
    import {getCurrentInstance} from 'vue'
  10.  
    export default {
  11.  
    setup() {
  12.  
    //获取当前组件实例
  13.  
    let $this = getCurrentInstance()
  14.  
    let updateDogName = ()=>{
  15.  
    $this.appContext.config.globalProperties.$bus.emit('update-dog-name','天天')
  16.  
    }
  17.  
    let updateDogSex = ()=>{
  18.  
    $this.appContext.config.globalProperties.$bus.emit('update-dog-sex','男生')
  19.  
    }
  20.  
    return {
  21.  
    updateDogName,
  22.  
    updateDogSex
  23.  
    }
  24.  
    }
  25.  
    };
  26.  
    </script>
学新通

3.异步组件

  1.  
    <template>
  2.  
    <div class="home">
  3.  
    <h1>首页</h1>
  4.  
    <One></One>
  5.  
    <!-- suspense内置组件,用于加载异步组件,添加loading效果 -->
  6.  
    <suspense>
  7.  
    <!-- default插槽里面放置异步组件 -->
  8.  
    <template #default>
  9.  
    <Two></Two>
  10.  
    </template>
  11.  
    <!-- fallback插槽里面制作loading效果 -->
  12.  
    <template #fallback>
  13.  
    Loading...
  14.  
    </template>
  15.  
    </suspense>
  16.  
    <!-- 异步组件,可以不用suspense,
  17.  
    但是如果异步组件内部的setup函数返回的是一个Promise对象,
  18.  
    此时的异步组件就必须要使用suspense -->
  19.  
    <suspense>
  20.  
    <template #default>
  21.  
    <Three></Three>
  22.  
    </template>
  23.  
    <template #fallback>
  24.  
    Loading...
  25.  
    </template>
  26.  
    </suspense>
  27.  
    <!-- <Three></Three> -->
  28.  
    </div>
  29.  
    </template>
  30.  
     
  31.  
    <script>
  32.  
    // defineAsyncComponent方法,用于异步加载组件
  33.  
    import {defineAsyncComponent} from 'vue'
  34.  
    import One from '../components/One.vue'
  35.  
    // import Two from './components/Two.vue'
  36.  
    // 异步导入Two组件和Three
  37.  
    let Two = defineAsyncComponent(()=>import('../components/Two.vue'))
  38.  
    // 注意:如果组件中setup方法返回的是Promise对象,那么组件必须要采用异步的方式加载
  39.  
    // import Three from './components/Three.vue'
  40.  
    let Three = defineAsyncComponent(()=>import('../components/Three.vue'))
  41.  
    export default {
  42.  
    name: 'App',
  43.  
    components: {
  44.  
    One,
  45.  
    Two,
  46.  
    Three
  47.  
    }
  48.  
    }
  49.  
    </script>
学新通

4.teleport组件

  1.  
    <button @click="show=true">显示</button>
  2.  
    <!-- teleport组件:官方起的名称:瞬移。通过to属性确定里面的元素移动到哪 -->
  3.  
    <teleport to="body">
  4.  
    <div v-show="show" class="box">
  5.  
    <button @click="show=false">关闭</button>
  6.  
    <div>{{dog}}</div>
  7.  
    </div>
  8.  
    </teleport>

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbebbb
系列文章
更多 icon
同类精品
更多 icon
继续加载