我是靠谱客的博主 可耐彩虹,最近开发中收集的这篇文章主要介绍六、Vue基础之六一、兄弟组件传参和Bus二、Mitt三、TSX四、v-model五、自定义指令directive六、自定义Hooks,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一、兄弟组件传参和Bus
  • 二、Mitt
  • 三、TSX
  • 四、v-model
  • 五、自定义指令directive
  • 六、自定义Hooks


一、兄弟组件传参和Bus

有两个组件A,B和父组件P,A想传参到B必须先传到父组件P中,再通过父组件P传给B。
上面这种方式麻烦。

Bus:发布订阅模式

二、Mitt

vue3中 o n , on, on,off和$once实例方法已被移除,组件实例不再实现事件触发接口,因此大家熟悉的EventBus便无法使用了,我们可以使用Mitt库,其实就是发布订阅模式的设计。

安装

npm install mitt -S

在Main.ts中引入mitt

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'

const Mit = mitt()

const app = createApp(App)

// 让在TS中有提示
declare module 'vue' {
    export interface ComponentCustomProperties {
        $Bus: typeof Mit
    }
}

app.config.globalProperties.$Bus = Mit

app.mount('#app')

在A组件中发布事件

<template>
    <h2>A组件</h2>
    <button @click="emit">emit</button>
</template>

<script setup lang='ts'>
import { getCurrentInstance } from 'vue'

const instance = getCurrentInstance()
// 发布事件
const emit = () => {
    instance?.proxy?.$Bus.emit('on-click1', 'mitt1')
    instance?.proxy?.$Bus.emit('on-click2', 'mitt2')
}

</script>

<style lang='scss' scoped>

</style>

在B组件订阅发布的事件

<template>
    <h2>B组件</h2>
    {{str}}
</template>

<script setup lang='ts'>
import { ref, getCurrentInstance } from 'vue';
const instance = getCurrentInstance()
let str = ref('')

// 订阅事件
/*
instance?.proxy?.$Bus.on('on-click1', (strA)=>{
    console.log(strA, 'B组件')
    str.value = strA as string
})
*/

// type函数,str发布事件携带的数据
/*
instance?.proxy?.$Bus.on('*', (type, str) => {
    console.log(type, str, 'B组件')
})
*/

const Bus = (str: any) => {
    console.log(str, 'B组件')
}
instance?.proxy?.$Bus.on('on-click1', Bus)
instance?.proxy?.$Bus.off('on-click1', Bus)
instance?.proxy?.$Bus.all.clear()

</script>

<style lang='scss' scoped>
</style>

三、TSX

我们之前是用Template去写我们的模板,现在可以扩展一种TSX风格
安装插件

npm install @vitejs/plugin-vue-jsx -D

vite.config.ts中配置一下

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()]
})

tsconfig.json中配置一下

"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",

在src下建一个App.tsx

const renderDom = () => {
    return(
        <div>
            <h2>hello, tsx</h2>
        </div>
    )
}

export default renderDom

在App.vue中使用这个tsx模板

<template>
    <renderDom></renderDom>
</template>

<script setup lang="ts">
import renderDom from './App'
</script>

<style lang="scss" scoped>
</style>

在tsx中一些指令的用法和template中有些许的不一样。
app.tsx


import { ref } from 'vue'

let v = ref<string>('')

let arr = [1, 2, 3]

const renderDom = () => {
    return(
        <div>
            {/*
            <input v-model={v.value} type="text" />
            <h2>{v.value}</h2> 
            */}

            {/* v-for不支持,用js的思想来写 */}

            {/* {
                arr.map(v=>{
                    return (<span>{v},</span>)
                })
            } */}

            

        </div>
    )
}

export default renderDom

四、v-model

给自定义组件去绑定一个v-model
App.vue

<template>
    <div>
        <h1>我是app.vue父组件</h1>
        <p>isShow:{{isShow}}</p>
        <div><button @click="isShow=!isShow">开关</button></div>
        <p>{{text}}</p>
        <hr>
        <!-- v-model绑定的isShow会传到子组件中 -->
        <!-- 多个v-model -->
        <vModela v-model="isShow" v-model:textValue="text"></vModela>
    </div>
    
</template>

<script setup lang="ts">
import { ref } from 'vue'
import vModela from './components/v-model.vue'
const isShow = ref<boolean>(true)
const text = ref<string>('hello')

</script>

<style lang="scss" scoped>

</style>

v-model.vue

<template>

    <div class="model" v-if="modelValue">
        <!-- 子组件点击关闭,将窗口关闭,并且将父组件的isShow改成false -->
        <div class="close"><button @click="close">关闭</button></div>
        <h3>我是v-model子组件 dialog</h3>
        <!-- 你这里输入父组件和子组件数据双向同步 -->
        <div>内容: <input @input="change" :value="textValue" type="text"></div>
    </div>

</template>

<script setup lang='ts'>
import { ref, reactive } from 'vue'

// 使用modelValue来接受父组件传过来的v-model的值
defineProps<{
    modelValue: boolean,
    textValue: string
}>()

// 子组件点击关闭,将窗口关闭,并且将父组件的isShow改成false
const emit = defineEmits(['update:modelValue', 'update:textValue'])
const close = () => {
    emit('update:modelValue', false)
}
const change = (e:Event) => {
    const target = e.target as HTMLInputElement
    emit('update:textValue', target.value)
}

</script>

<style lang='scss' scoped>

</style>

五、自定义指令directive

通过给子组件绑定自定义指令去获取子组件的一些数据,在挂载完成之后获取得到子组件的一些数据。
App.vue

<template>
    <div>
        <!-- 在script中写的vMove,而模板中用的v-move -->
        <A v-move:aaa.kk="{ background: 'red' }"></A>
    </div>
    
</template>

<script setup lang="ts">
import { ref, Directive, DirectiveBinding } from 'vue'
import A from './components/A.vue'

type Dir = {
    background: string
}


const vMove:Directive = {
    created(){
        console.log('created')
    },
    beforeMount(){
        console.log('beforeMount')
    },
    // 可以通过这个指令拿到子组件的一些数据
    // mounted(...args: Array<any>){
    //     console.log('mounted')
    //     console.log(args)
    // },
    mounted(el:HTMLElement, dir:DirectiveBinding<Dir>){
        el.style.background = dir.value.background
    },
    beforeUpdate(){
        console.log('beforeUpdate')
    },
    updated(){
        console.log('update')
    },
    beforeUnmount(){
        console.log('beforeUnmount')
    },
    unmounted(){
        console.log('unmounted')
    }

}

</script>

<style lang="scss" scoped>

</style>

子组件A.vue

<template>
    <div class="box">
        A组件
    </div>
</template>

<script setup lang='ts'>

</script>

<style lang='scss' scoped>
.box{
    width: 200px;
    height: 200px;
    border: 1px solid yellowgreen
}
</style>

六、自定义Hooks

Vue3自定义Hook,主要用来处理利用代码逻辑的一些封装,将多个相同的逻辑抽离出来,各个组件只需要引入,就能实现一次写代码,多组件受益的效果。hooks是函数。
vueuse开源库

<template>
    <div>
        <!-- 这些传过去key-value在子组件使用Hooks拿到 -->
        <A aa="888" title="title"></A>
    </div>
    
</template>

<script setup lang="ts">
import A from './components/A.vue'

</script>

<style lang="scss" scoped>

</style>

A.vue

<template>
    <div class="box">
        A组件
    </div>
</template>

<script setup lang='ts'>
import { useAttrs } from 'vue'
let attr = useAttrs()
console.log(attr)
</script>

<style lang='scss' scoped>
.box{
    width: 200px;
    height: 200px;
    border: 1px solid yellowgreen
}
</style>

Hooks就是定义一个函数,暴露给其他组件使用。

最后

以上就是可耐彩虹为你收集整理的六、Vue基础之六一、兄弟组件传参和Bus二、Mitt三、TSX四、v-model五、自定义指令directive六、自定义Hooks的全部内容,希望文章能够帮你解决六、Vue基础之六一、兄弟组件传参和Bus二、Mitt三、TSX四、v-model五、自定义指令directive六、自定义Hooks所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部