vue3用composition api 取代了之前的options api,並且加強了支持typescript,另代碼可讀性和可改性更強了,用習慣了setup函數真的可以說句,真香。
但是不可避免的,需要趟一些雷,比方說element-plus的表單驗證功能。由於setup里取消了this獲取實例,就突然變得不知所措。以下是我填坑的一些經驗。
先看element-plus官方文檔中的驗證寫法。
methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, }
可以看到,element-plus的官方示例中,還是按照vue2的options api寫法。這顯然是我們不會采用的。
於是上網搜索資料,發現很多人說要引用getCurrentInstance方法來獲取實例,這個方法是取代vue2中的this的。引用方法是在當前組件import。
import {getCurrentInstance} from "vue";
我們console了一下,發現確實可以找到$refs,但是這個方法顯然不是很好的,而且是開發環境中用做調試的方法。我就不詳細說了,可以看下面這篇文章,寫的很詳細。
https://juejin.cn/post/6901087576195760141
我比較吃驚的是,竟然有一些培訓機構就用這個方法去寫案例進行培訓。vue3設計初不就是不讓你這樣獲取實例,否則取消this干嘛呢?你這樣取巧繞過去,真的沒問題嗎?
但是還有一種獲取實例的方法,就是在setup中傳入context參數,這個我沒仔細研究,就是傳入打印了一下,沒看到自己想要的東西。
於是我們不如從reactive refs api入手。
看相關資料,發現reactive主要作為定義響應式對象,而ref主要作為響應式單值。當然這是我粗淺的理解。
而且還有torefs,unref,toref等等等等很多api,一時間需要一些時間消化。
可以參考https://blog.csdn.net/Yomuki/article/details/112563904
所以,我們的表單驗證就可以這么去寫。
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left" > <el-form-item prop="username"> <el-input ref="username" v-model="loginForm.username" :placeholder="請輸入用戶名" name="username" type="text" tabindex="1" autocomplete="on" /> </el-form> <el-form-item prop="password"> <el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType" :placeholder="請輸入密碼" name="password" tabindex="2" autocomplete="on" @keyup="checkCapslock" @blur="capsTooltip = false" @keyup.enter="handleLogin" /> </el-form> <el-button :loading="loading" type="primary" style="width:100%; margin-bottom:30px;" @click="handleLogin()" > 登錄 </el-button> </el-form>
import{自己寫} from 'vue'
export default defineComponent({
setup(){
const loginRules=ref({.....})
const handleLogin = async () => {
if (!loginRules.value) return;
await loginRules.value.validate((valid: boolean) => {
console.log(1, valid);
...
});
}
}
})