日常遇到的小問題匯總, 內容小篇幅少的就全放這里了, 內容多的會在Vue專欄單獨分享~
目錄
【Q】 el-form-item值為 null 或 undefined顯示““
【Q】dialog內組件數據刷新總是延遲慢一拍
問題背景描述
解決方案
代碼簡單模擬
JS
【Q】el-input 不能輸入的解決辦法
方法1:標簽嵌套太深
方法2:使用了 template 作為 el-input 的父標簽
方法3:v-model
【Q】npm ERR A complete log of this run can be found in: npm ERR
【Q】el-tabs表格右下角按鈕被遮擋
【Q】this.$refs.xxx 報錯undefined解決辦法
【Q】this.$refs[‘form’].resetFields()
【Q】this.defParams = {...this.params}
【Q】Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
【Q】數據還沒獲取就已渲染頁面
【Q】頁面跳轉后沒有重新請求接口
a、updated刷新組件內的方法更新數據
b、監聽路由去請求方法更新數據
【Q】調用子組件提示this.$refs["xxxRef"].xx()? underfined
a、首次渲染不調用
b、加載完數據再請求
【Q】Error in callback for watcher "$route": "TypeError: this.$refs.xxxRef is undefined"
【Q】 el-form-item值為 null 或 undefined顯示““
可以在 `el-form-item` 中使用表達式,使用 `v-if` 指令判斷當前表單項的值是否為 null 或 undefined,如果為 null 或 undefined,就顯示空字符串。
例如:
<template><el-form ref="form" :model="formData" :rules="formRules" label-position="left"><el-form-item label="姓名" :label-width="labelWidth"><el-input v-model="formData.name" clearable v-if="formData.name !== null && formData.name !== undefined"></el-input><span v-else> </span></el-form-item><el-form-item label="性別" :label-width="labelWidth"><el-select v-model="formData.gender" clearable v-if="formData.gender !== null && formData.gender !== undefined"><el-option label="男" value="male"></el-option><el-option label="女" value="female"></el-option></el-select><span v-else> </span></el-form-item><el-form-item label="年齡" :label-width="labelWidth"><el-input type="number" v-model.number="formData.age" clearable v-if="formData.age !== null && formData.age !== undefined"></el-input><span v-else> </span></el-form-item></el-form>
</template><script>
export default {data() {return {formData: {name: null,gender: null,age: null},formRules: {name: [{ required: true, message: '請輸入姓名', trigger: 'blur' }],gender: [{ required: true, message: '請選擇性別', trigger: 'change' }],age: [{ required: true, message: '請輸入年齡', trigger: 'blur' },{validator: (rule, value, callback) => {if (value < 0) {callback(new Error('年齡不能小于0歲'));} else {callback();}},trigger: 'blur'}]},labelWidth: '120px'};}
};
</script>
在上面的代碼中,我們在每個表單項中使用 `v-if` 判斷當前表單項的值是否為 null 或 undefined,如果為 null 或 undefined,則將當前表單項的值設置為空字符串。這樣就可以將值為 null 或 undefined 的表單項顯示為空。我們使用 ` ` 來占位,使表單外觀更美觀。
注意:如果在 `el-form-item` 的 `label` 屬性和 `v-if` 判斷條件中都使用了表達式,那么應該將所有表達式放在一對花括號中。例如:
<el-form-item :label="'年齡:' + labelSuffix" :label-width="labelWidth" v-if="formData.age !== null && formData.age !== undefined"><el-input type="number" v-model.number="formData.age" clearable></el-input>
</el-form-item>
<span v-else> </span>
在上面的代碼中,我們在 `el-form-item` 的 `label` 屬性和 `v-if` 判斷條件中都使用了表達式,因此應該將它們放在一對花括號中。
【Q】dialog內組件數據刷新總是延遲慢一拍
問題背景描述
用dialog做了一個一個新增功能,有個多層復選框,關聯一個文本域。
選中復選框時,文本域刷新,但是總是慢一拍。
:destroy-on-close="true", v-if, $nextTick,用個遍了,都不好使。
同樣的功能在編輯頁面就是正常的,區別僅僅是因為新增是dialog子頁面,
由此入手排查問題,發現竟然是...
解決方案
代碼簡單模擬
源碼不便展出,湊合看解決問題就好~
<el-dialog :destroy-on-close="true" title="國服李白" :visible.sync="dialogEdit"><span>這是一段信息</span><flow-chart :dialogNodes="dialogNodes" :key="timer0"></flow-chart><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">確 定</el-button></span>
</el-dialog>
組件上添加 :key="timer1"
data 中定義 timer0
為 ''
在獲取數據成功后 將 timer0 賦值為 this.timer1 = new Date().getTime()
JS
const res = await ApiUserManage.execDiagram(param)if (res.success){this.timer0 = new Date().getTime()this.dialogNodes = res.result.nodes
【Q】el-input 不能輸入的解決辦法
輸入框動態填充值,但是填充后不能編輯了,
就像是被禁止了一樣, 就很無語...查了下資料, v-model填寫了, 也沒有templete標簽嵌套最終方法一即可解決問題...
方法1:標簽嵌套太深
如果標簽嵌套太深,會導致無法獲取到 DOM,這是我們需要 $forceUpdate() 強制刷新,才可獲取<el-input type='text' v-model='value' @change='change()'></el-input>
data(){return {value:'',}
}
change(){this.$forceUpdate(); //強制刷新
}
方法2:使用了 template 作為 el-input 的父標簽
這種情況需要在 template 中添加 slot-scope 屬性,<template slot-scope="scope">
方法3:v-model
el-input 中沒有 v-model
【Q】npm ERR A complete log of this run can be found in: npm ERR
總是提示這個錯誤,以為是nodejs版本v16太高的問題,換成v12后,還是不行...
npm i后總是提示這個
nnpm ERR! Unexpected token '.' npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\admin\AppData\Local\npm-cache\_logs\2022-08-29T15_07_28_136Z-debug-0.log
后來發現管理員打開VSCode就好了...
【Q】el-tabs表格右下角按鈕被遮擋
該列設置了?fixed="right",? 去掉?fixed="right"即可
常規方法:? 看下是否是下方組件margin設置過大
【Q】this.$refs.xxx 報錯undefined解決辦法
【Vue】this.$refs.xxx 報錯undefined解決辦法
【Q】this.$refs[‘form’].resetFields()
要想this.$refs[‘form’].resetFields()方法有效,必須配置el-form :model?屬性和el-form-item中的prop屬性才可以
this.$refs[‘form’].resetFields()這個做法其實是重置表單到初始值,不是清空表單,當表單第一次在頁面中渲染時所用的數據就是初始數據,
【Q】this.defParams = {...this.params}
this.params=this.defParam;初始化默認參數, vue2會把內存地址也復制過去,當params里面的值修改后, this.defParams也會相應改動,所以要先復制一份再賦值給this.params
this.defParams = {...this.params},
這樣它們之間的值才不會相互影響, 不過這在Vue3里面都已經解決了
【Q】Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
改動了子組件中引用的父組件的變量,也就是props中的數據
中組件props中的數據只能單向流動,即只能從父組件通過組件的DOM屬性attribute傳遞props給子組件,子組件只能被動接收父組件傳遞過來的數據,并且在子組件中,不能修改由父組件傳來的props數據。
props:{cid:{type:String,},},methods: {//父組件刷新子組件數據1flush(cid){const params = {cid:cid};this.getData(params);},//父組件刷新子組件數據2, 這種情況就會出現上述問題flush(cid){this.cid= cid;const params = {cid:this.cid};this.getData(params);},
【Q】數據還沒獲取就已渲染頁面
簡單舉例...
v-if="loading"
...data(){return{loading:false,}
}created(){ this.init();
}, methods: {init() {this.getList();},getList() {queryListData(this.params).then((res) => {if(res.code==='200'){...this.loading = true;}}).finally(() => {...});},
}
【Q】頁面跳轉后沒有重新請求接口
a、updated刷新組件內的方法更新數據
簡單舉例...
ref="demoRef"
...created() {},
mounted() {},
updated() {this.init();
},methods: {init() {this.$refs["demoRef"].flush();}},
}
b、監聽路由去請求方法更新數據
簡單舉例...
ref="demoRef"
...created() {},
mounted() {},
updated() {},watch: {$route(a, b) {if (a.path != b.path) {this.init();}},//-----或-----$route(-) {this.init();},
},methods: {init() {this.detail();...}},
}
【Q】調用子組件提示this.$refs["xxxRef"].xx()? underfined
a、首次渲染不調用
b、加載完數據再請求
簡單舉例...
ref="demoRef"
...data() {return {loadingData:false,},
}
created() {this.init();
},
mounted() {},
updated() {if(loadingData){this.$refs["demoRef"].flush();}
},methods: {init() {queryListData(this.params).then((res) => {...this.loadingData= true;});}},
}
【Q】Error in callback for watcher "$route": "TypeError: this.$refs.xxxRef is undefined"
父頁面監控路由變動時刷新子組件提示, 這里是同一個頁面路由參數改變,
Error in callback for watcher "$route": "TypeError: this.$refs.tableOneRef is undefined"
困擾許久, this.nextTick(){}等等都不好使, 原因是在Vue中,當路由發生變化時,組件的實例會被銷毀然后重新創建。因此,在路由切換后,組件的this上下文會發生改變。
當你監聽路由變化時,如果在回調函數中使用了this關鍵字,它將指向新創建的組件實例,而不是之前的組件實例。這意味著你無法直接訪問之前組件實例中的數據和方法。
為了解決這個問題,你可以在監聽路由變化時,將需要保留的數據和方法保存到其他變量中,或者使用Vue提供的beforeRouteUpdate導航守衛來處理組件的更新邏輯。
beforeRouteUpdate(to, from, next) {// 保存需要保留的數據和方法const preservedData = this.data;const preservedMethod = this.method;// 執行路由變化前的邏輯// ...// 調用next()繼續路由更新next();// 在路由更新后恢復數據和方法this.data = preservedData;this.method = preservedMethod;
}
依然不好使哈
這里說下最后的解決思路:
定義一個狀態isReloadChild:true
監控路由變化時, 先false,? 然后更改狀態為true, 需要控制的組件v-if控制
簡化代碼如下
this.isReloadChild = false;setTimeout(() => {this.isReloadChild = true;}, 0);
有用請點贊,養成良好習慣!
疑問、交流、鼓勵請留言!