這些任務對於日常和業務打交道的同學來說當然很有挑戰性,12月16日,村長特意準備了一節0元公開課《vue3+ts組件庫開發實戰》,本次課準備給小夥伴們實戰一下Tree組件的開發,深度體驗vue3+tsx開發的各種知識點。
報名連結
知識儲備本次我要帶大家編寫一個Tree組件,會用到JSX,因此我們提前做一些知識儲備:
Vite中引入JSX本次Tree組件實現要用到JSX支持,所以小夥伴們有必要先了解如何在Vite項目中引入JSX。
我們可以通過一個叫做@vitejs/plugin-vue-jsx插件實現,
首先安裝它:
yarn add @vitejs/plugin-vue-jsx -D配置一下該插件,vite.config.ts:
// vite.config.js
import vueJsx from '@vitejs/plugin-vue-jsx'
export default {
plugins: [
vueJsx({
// options are passed on to @vue/babel-plugin-jsx
})
]
}測試一下,components/Tree.tsx
export default () => <div>tree</div>
如何定義一個組件在TSX文件中定義組件有幾種常用方式:
函數式組件:最簡單的方式,你可以把它理解為setup函數,但是不同之處它可以直接返回JSXexport default (props, ctx) => <div>tree</div>
defineComponent:傳遞render選項,也就是Options API,這種缺點是要訪問thisexport default defineComponent({
render() {
return <div>tree</div>
}
})
defineComponent:傳遞setup選項,利用Composition API,避免this,是推薦的形式export default defineComponent({
setup(props, ctx) {
return () => <div>tree</div>
}
})
Vue3中JSX/TSX特殊語法如果有過react的開發經驗,可以發現除了vue中獨有的幾個新概念:slot、directive、emit等以外,其他都是相同的,因此這裡僅關注這些特殊部分:
指令指令使用需要我們轉換思維,有幾種不同情況:
常用指令v-model,v-show跟以前用法類似,但也要注意後面是{},不是""<input type="text" v-model={this.counter} /><div>{ condition ? <span>A</span> : <span>B</span> }</div>import { defineComponent, ref } from "vue";
const App = defineComponent({
setup(){
const list = ref<string[]>([])
return () => {
list.value.map((data,index) => <p key={index}>{data}</p>)
}
}
});
插槽JSX中想要實現Vue中的插槽寫法也有很大不同,主要利用一個叫做v-slots的指令來實現:
Parent.tsx
export default defineComponent({
setup() {
return () => (
<Child
v-slots={{
prefix: () => <i>prefix</i>, // 具名插槽
suffix: (props: Record<"name", string>) => <span>{props.name}</span>, // props可作插槽作用域的作用
}}
>
默認插槽內容
</Child>
);
},
});const Child = defineComponent({
setup(props, { slots }) {
return () => (
<>
默認插槽: {slots.default && slots.default()}
<br />
具名插槽: {slots.prefix && slots.prefix()}
<br />
作用域插槽:{slots.suffix && slots.suffix({ name: "suffix" })}
</>
);
},
});
emitvue中子向父傳值一般都是emit的方式,這個在vue3中大致寫法相似,只是多了一個定義emit的步驟,這也是為了後續的類型推倒做準備。
defineComponent({
emits: ["click"],
setup(props ,{ emit }) {
return () => (
<button onClick={() => {emit("click")}}>點我觸發emit</button>
);
},
});
村長公開課