依赖注入inject 提供provide、兄弟组件传参、tsx、自动引入插件

214 阅读2分钟
依赖注入 provide inject 
用来实现组件级别的传参  

注入 provide
取出 inject (都要从vue引)
注入 provide('color', colorVal)
取出 const color = inject('color')
provide('color', readonly(colorVal)) 此时其他组件就无法修改color值了

setup下css也能取到js里的值
.box {
  width: 50px;
  height: 50px;
  border: 1px solid #ccc;
  background: v-bind(color);
} 
此时color的值就是js里定义的值

兄弟组件传参 A传给B 
通过中间一个父组件充当桥梁
A组件 子传父传给父组件 父组件再传给B子组件

父组件
<template>
  <div>
    <A @on-click="getFlag"></A>
    <B :flag="flag"></B>
  </div>
</template>
<script setup lang='ts'>
import A from './components/A.vue'
import B from './components/B.vue'
import { ref } from 'vue'
let flag = ref(false)
const getFlag = params => {
  flag.value = params
}
</script>

A组件
<template>
  <div>
    A组件
    <button @click="emitB">派发一个事件</button>
  </div>
</template>
<script setup lang='ts'>
const emit = defineEmits(['on-click'])
let flag = false
const emitB = () => {
  flag = !flag
  emit('on-click', flag)
}
</script>

B组件
<template>
  <div>
    B组件{{ flag }}
  </div>
</template>
<script setup lang='ts'>
type Props = {
  flag: boolean
}
defineProps<Props>()
</script>

tsx
安装 cnpm i -D @vitejs/plugin-vue-jsx
vite.config.ts中 
import vueJsx from '@vitejs/plugin-vue-jsx'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  plugins: [vue(), vueJsx()],
  css: {
    preprocessorOptions: {
        scss: {
            additionalData: "@import './src/bem.scss';"
        }
    }
}
})

在src文件夹下新建App.tsx
内容 
直接返回渲染函数
export default function() {
	return (<div>小满</div>)
}
vue2风格
import {defineComponent} from 'vue'
export default defineComponent({
	data() {
		return {
			age: 23
		}
	},
	render() {
		return (<div>{this.age}</div>)
	}
})
setup风格
import {defineComponent} from 'vue'
export default defineComponent({
	setup() {
		const flag = false
		return () => (<div v-show={flag}>C</div>)
		
	}
})
jsx中插值表达式为单花括号
App.vue中直接引import xiaoman from './App'
<template>
  <div>
    <xiaoman></xiaoman>
  </div>
</template>

ref包裹的对象在template中会自动解包,在tsx中不会(函数) 所以要加.value

setup风格盒子不支持直接v-if,替代方法 
const data = [
			{
				name: '小满1'
			},
			{
				name: '小满2'
			},
			{
				name: '小满3'
			}
		]
		return () => (<>
			{data.map(v=> {
				return <div>{v.name}</div>
			})}
			</>)
                
接收值,派发事件
export default defineComponent({
	props: {
		name:String
	},
	emits: ['on-click'],
	setup(props:Props) {
		const flag = ref(false)
		const data = [
			{
				name: '小满1'
			},
			{
				name: '小满2'
			},
			{
				name: '小满3'
			}
		]
		return () => (<>
		<div>props:{props?.name}</div>
		<hr />
			{data.map(v=> {
				return <div>{v.name}</div>
			})}
			</>)
		
	}
})

setup风格绑定方法 放在回调里,不然一加载就执行了
<div onClick={()=> fn()}>{v.name}</div>

派发事件
export default defineComponent({
	props: {
		name:String
	},
	emits: ['on-click'],
	setup(props:Props, {emit}) {
		const flag = ref(false)
		const data = [
			{
				name: '小满1'
			},
			{
				name: '小满2'
			},
			{
				name: '小满3'
			}
		]
		const fn = (item) => {
			console.log('触发了')
			emit('on-click', item)
		}
		return () => (<>
		<div>props:{props?.name}</div>
		<hr />
			{data.map(v=> {
				return <div onClick={()=> fn(v)}>{v.name}</div>
			})}
			</>)
		
	}
})
父组件
<template>
  <div>
    <xiaoman name="xiaoman" @on-click="getItem"></xiaoman>
  </div>
</template>
<script setup lang='ts'>
import xiaoman from './App'
const getItem = item => {
  console.log('item', item)
}
</script>
<style lang='scss' scoped>
</style>

v-model用法
const v = ref('')
	<input v-model={v.value} type="text" />
	<div>{v.value}</div>

自动引入插件
安装 cnpm i -D unplugin-auto-import
vue.config.ts中引入 import AutoImport from 'unplugin-auto-import/vite'
注册+配置 
plugins: [vue(), vueJsx(), AutoImport({
    imports: ['vue'],
    dts: 'src/auto-import.d.ts'
})]