概述
文章目录
- 一、兄弟组件传参和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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复