常識(shí)
- 項(xiàng)目都用的若依vue3,且項(xiàng)目統(tǒng)一有基礎(chǔ)架子,不用操心從零配置項(xiàng)目
- 項(xiàng)目遵循一個(gè)規(guī)范是:一個(gè)頁(yè)面對(duì)應(yīng)一個(gè)文件夾,頁(yè)面主體用index.vue命名,拆分出的局部vue不要放在components里,而是和index.vue并排放,比如DetailDialog.vue
- 左側(cè)菜單配置在若依里配置,不是李春時(shí)代直接寫數(shù)據(jù)表的土法子
- code插件裝Vue-Offical
Vue3基礎(chǔ)
- <script>用
<script setup lang="ts">
,里面視為普通邏輯代碼,沒有Vue2那種導(dǎo)出大對(duì)象 - 不會(huì)再有任何
this
- 組件import之后就不用管了,沒有components: {}這種聲明
- 以下提到的
ref
defineProps
computed
什么的,通常不需要專門import,如果真的需要,vscode會(huì)提示你怎么引入 - 原來的props,現(xiàn)在用
const props = defineProps({......})
,無(wú)論組件要定義多少prop,只用定義1次props - 原來的data,現(xiàn)在用
const abc = ref(初始值,可以是[],可以是空值)
,注意,不能在函數(shù)里定義,必須在最表層定義,簡(jiǎn)單說,除了函數(shù)里臨時(shí)用一下的變量,其他變量一律在最表層定義。還有,凡是在<template>用的變量一律用ref,其他變量一律不寫ref - 修改data,用
abc.value = 新值
,注意別忘了.value -
ref
包裹任何類型,reactive
只包裹數(shù)組和對(duì)象,ref
使用概率90%,reactive
10% - 包裹對(duì)象的前提下,
ref
用于整體對(duì)象被替換的場(chǎng)景,如abc.value = xxx
,reactive
用于局部賦值的場(chǎng)景,如const abc = reactive({a:1}); abc.a = 2
- 只有ref對(duì)象有
.value
,reactive對(duì)象不寫.value - template里寫變量,不加
.value
,JS里寫變量,加.value
- 原來的methods,現(xiàn)在是一個(gè)個(gè)的函數(shù),函數(shù)和相關(guān)的const在書寫時(shí)就近寫
- 原來的計(jì)算屬性,現(xiàn)在是
const def = computed(()=> {return abc.value * 333222111})
- 監(jiān)聽,現(xiàn)在是
watch(()=>abc.value, ()=> {do something})
,watch不用賦值給什么變量,寫在<script>表層任意位置均可 - 修改了變量后DOM不會(huì)第一時(shí)間生效,Vue2的nextTick現(xiàn)在的寫法是:
nextTick(()={...})
- <script>代碼第一部分,
import
,如同Vue2 - <script>第二部分,如果是子組件可能需要接props,寫法:
const props = defineProps({ // props變量名永遠(yuǎn)是這個(gè)變量名,defineProps函數(shù)不需引入,因?yàn)榭蚣茏詭? xxxxx: { // Vue2寫法,不解釋
type: Boolean,
default: true
}
})
- <script>第三部分,如果是子組件可能需要定義emit,寫法:
const emit = defineEmits(['abc']) // emit永遠(yuǎn)是emit,defineEmits不需要引入,abc是父組件里寫的那個(gè)@abc=
- <script>第四部分,按功能開始寫代碼,建議用明顯的注釋來劃分模塊,例如:
//region ************************************************** 一般常量 **************************************************
...
//region ************************************************** 一般函數(shù) **************************************************
...
//region ************************************************** XX區(qū)塊 **************************************************
...
//region ************************************************** OO區(qū)塊 **************************************************
...
//region ************************************************** 某某Dialog **************************************************
...
- 區(qū)塊就是頁(yè)面里的一塊塊的部分,沒什么玄妙
- 以XX區(qū)塊為例,比如一個(gè)輸入框
<input :value="inputVal" @input="onInput" />
,實(shí)質(zhì)上并不會(huì)用原生<input />,我就是告訴你,除了const就是function,沒什么玄妙:
const inputVal = ref('')
function onInput() {
......
}
- 如何emit:
function xxx(){
emit('上文自定義的那個(gè)事件名', '傳的值')
}
- 周期鉤子:所有的鉤子都要背下來,用的時(shí)候一般只用
onMounted
onUnmounted
,寫法:
onMounted(()=> {
do something
})
onMounted可以多次定義,可以分布在任何角落,執(zhí)行的時(shí)候依次執(zhí)行,根據(jù)業(yè)務(wù)邏輯放置就行了。
- 如何引用DOM:比如
<el-form ref="formRef" ......
,格式是隨便取個(gè)名字,最后加Ref
,這個(gè)名字怎么寫都行,不受限制,推薦是相關(guān)名字
跟Ref
。用的時(shí)候:
const formRef = ref(); // 這里的formRef必須和<el-form ref="formRef"同名,必須在表層寫
onMounted(()=>{ formRef.value.offsetHeight ...........}) // 用的時(shí)候,必須在onMounted里,不然DOM獲取不到,你懂的。
- 立即ajax
就在表層直接寫,注意表層不支持await,函數(shù)內(nèi)支持。所以表層用:
import mainApi from '@/api/xxx/ooo'
....
const xxList = ref([])
mainApi.getList({...}).then(res=> {
xxList.value = res
})
Element Plus
- 圖標(biāo)引入:
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
TS
- 隨便定義個(gè)對(duì)象的接口:
interface SysUser {
userId: number
nickName: string
}
- 如何用這個(gè)接口:
const abc: SysUser = {userId: 22, nickName: '李月靜'}
- 復(fù)雜情況:對(duì)象套對(duì)象,所以接口套接口:
interface SysUser {
userId: number
nickName: string
child: SysUser[]
}
上面是更特殊的情況,自己套自己,也可以套別的接口,不難理解。[]
表示它是由SysUser組成的數(shù)組
- type的用法:
type age = number | string
這就是更簡(jiǎn)單的定義。|
表示“或”,number
用小寫。
type age = 15 | 16 | 17 | 18
約束僅限于這4個(gè)值。
type SysUser = {
userId: number
nickName: string
}
這和interface功能一樣。
- 函數(shù)參數(shù)定義類型:
type Sex: number
function abc(sex: Sex, age: Age) {}
- 總結(jié):
- 首字母大寫
- interface 用花括號(hào),type用等于號(hào)
- interface用來定義對(duì)象(type也可以,但一般用interface),type用于定義簡(jiǎn)單類型,可以加
|
- 函數(shù)的參數(shù)一定要定義上類型
- 別的咱不用管,工作中學(xué)習(xí)
示例:
import ... from ...
import ... from ...
//region ************************************************** 部門樹 **************************************************
interface SysUser {
userId: number
nickName: string
}
interface DeptUser {
deptId: number
parentId: number | null
deptName: string
sysUsers: SysUser[]
}
interface DeptUserList {
value: DeptUser[]
}
let deptUserList: DeptUserList = ref([])
const deptTreeOptions = ref<any>([])
let deptUserListLoading = ref(false)
getUserTree().then((res) => {
deptUserList.value = res.filter((v) => v.isUser === '1')
deptTreeOptions.value = DeptUtils.arrayToTree(res)
deptUserListLoading.value = false
})
-
工作中棘手的事
- 頁(yè)面是典型的搜索+表格的樣子的話,我給你一套快速開發(fā)模版
- 左右結(jié)構(gòu)的話,多用flex:1,讓右側(cè)彈性
- element-plus有3中樹形相關(guān)的組件,tree,tree-select,cascader,你怎么從扁平數(shù)據(jù)構(gòu)建樹形數(shù)據(jù)?你問AI:
JS有數(shù)組,格式類似于{......后端返回的扁平格式.....},我想構(gòu)建成{id:'原id值', value:'原id值',label:'原name值',children:[]}的樹形格式,給我算法