Почему функция превращается в объект?
Делаю страницу для изменения данных видео, в которой есть форма (выступает в качестве отдельного компонента, поэтому принимает пропс fields), где присутствует валидация.
Я хочу получить данные видео с сервера, записать их в объект videoData, чтобы потом заполнить начальные данные формы на странице.
Проблема заключается в том, что когда я хочу произвести проверку на валидность, то у меня выводится ошибка fields[fieldKey].isMatchRegexp is not a function, хотя метод isMatchRegexp является функцией, но после обращения к серверу данный ключ становится пустым объектом.
Данная проблема появляется тогда, когда у меня присутствует инструмент fetch, без него у меня все работает.
Страница edit
data параметры
data: () => ({
fields: {
title: {
title: "Название",
// Проверяет на валидность данный параметр
isMatchRegexp(val) {
return /.{6,}/g.test(val);
},
type: "text",
},
},
videoData: {},
}),
Получение видео по id с сервера
async fetch() {
try {
const token = this.$store.getters["auth.store/getToken"];
const { id: videoId, } = this.$route.params;
const { ok, video, } = await this.$store.dispatch("video.store/getOne", { token, id: videoId, });
if (ok) {
const { poster, src, } = video;
const validPoster = await this.getValidUrlDataFile(poster);
const validVideoSrc = await this.getValidUrlDataFile(src);
this.videoData = {
...video,
video: validVideoSrc,
poster: validPoster,
};
}
} catch (err) {
throw err;
}
},
Запись начальных данных формы в объект fields
created() {
Object.keys(this.videoData).map((key) => {
if (key in this.fields) {
this.fields[key].model = this.videoData[key];
}
});
},
Компонент формы
HTML
<form class="form">
<div
v-for="(fieldKey, index) in getFieldsKeys"
:key="index"
class="form__field"
>
<label
class="form__label"
:for="fieldKey"
>
<input
:id="fieldKey"
v-model.trim="dataForm[fieldKey].model"
class="form__input"
:class="{
<!-- Здесь будет ошибка -->
'form__input--invalid': !fields[fieldKey].isMatchRegexp(dataForm[fieldKey].model) && dataForm[fieldKey].model.length,
}"
:type="fields[fieldKey].type"
>
</label>
</div>
</form>
Создание подобных элементов в объекте dataForm, содержащих ключи, необходимые для проверки валидации
created() {
Object.keys(this.fields).map((key) => {
this.dataForm[key] = { model: this.fields[key].model || "", };
});
},
Возвращает ключи объекта fields
computed: {
getFieldsKeys() {
return Object.keys(this.fields);
},
},
Ответы (1 шт):
Исследовав отдельно файл _edit.vue и vForm.vue мне удалось обнаружить где происходит подмена функции объектом.
Причина действительно при использовании async fetch — когда она есть Nuxt пытается преобразовать через stringify данные компонента, а в данном случае функция не может пройти такую.трансформацию, о чем сообщается в консоли:
Таким образом после вызова fetch в данных лежит уже не функция:
а объект:
После чего я принял решение избавится от функции в объекте fields (если нужно использовать async fetch). Так как пока в проекте используется только 5 vForm, проще везде заменить функции на строки:
data: () => ({
fields: {
title: {
title: "Название",
matchRegexp: "/.{6,}/g", // <- замена функции на строку
type: "text",
}
},
Этот формат пройдет stringify разумеется нужно поправить код в vForm, я добавил ему метод isMatchRegexp принимающий reText — ту самую регулярку как строку и value — значение для проверки:
isMatchRegexp(reText, value){
const re = new RegExp(reText)
return re.test(value)
},
Далее в двух местах заменил использование:
// в шаблоне
:class="{
'form__input--invalid': !isMatchRegexp(fields[fieldKey].matchRegexp, dataForm[fieldKey].model && dataForm[fieldKey].model.length),
}"
// и в sendReq
return this.isMatchRegexp(this.fields[key].matchRegexp, itemForm["file" in itemForm ? "file" : "model"]);
Хочу еще заметить что метод edit:
methods: {
edit(data) {
console.log(data);
},
вызываемый из:
this.$emit("sendReq", this.isVideo ? { ...data, ...this.video, } : data);
до этих правок возвращал пустой объект:
После, ошибки больше не возникает и в методе edit нормальный объект:
Весь код запускался в отдельном проекте с двумя файлами edit и vForm, поэтому видео данные нигде не фигурируют, да и они в данном случае не были нужны.




