Vuex 스토어의 로컬 복사본에서 데이터 업데이트
나는 처음에 데이터를 처음에 로딩된 데이터로 구성된 사용자 프로파일 편집 페이지를 구현하고 있습니다에서 로드로 구성된 사용자 프로필 편집 페이지 구현입니다.vuex보관하세요. 그리고 사용자가 자유롭고 마침내 그 가게에 저장한 자료를 편집할 수 있다.그러면 사용자는 자신의 데이터를 자유롭게 편집하여 저장해 둘 수 있습니다.
또한 취소 버튼을 클릭하여 원래 상태로 되돌릴 수 있기 때문에 스토어에서 가져온 사용자 데이터의 '로컬' 보기 복사본을 만들기로 했습니다.이 데이터는 뷰에 저장되며 사용자가 저장을 누르면 스토어에 저장됩니다.
보기는 다음과 같습니다.
<template class="user-profile">
<v-form>
<template v-if="profile.avatar">
<div class="text-center">
<v-avatar width="120" height="120">
<img
:src="profile.avatar"
:alt="profile.firstname"
>
</v-avatar>
</div>
</template>
<div class="text-center mt-4">
<v-btn
color="primary"
dark
@click.stop="showImageDialog=true"
>
Change Image
</v-btn>
</div>
<v-row>
<v-col>
<v-text-field
label="First name"
single-line
disabled
v-model="profile.firstname"
></v-text-field>
</v-col>
<v-col>
<v-text-field
label="Last name"
single-line
disabled
v-model="profile.lastname"
></v-text-field>
</v-col>
</v-row>
<v-text-field
label="Email"
single-line
v-model="profile.email"
></v-text-field>
<v-text-field
id="title"
label="Title"
single-line
v-model="profile.title"
></v-text-field>
<v-textarea
no-resize
clearable
label="Biography"
v-model="profile.bio"
></v-textarea>
<v-dialog
max-width="500"
v-model="showImageDialog"
>
<v-card>
<v-card-title>
Update your profile picture
</v-card-title>
<v-card-text>
<v-file-input @change="setImage" accept="image/*"></v-file-input>
<template v-if="userAvatarExists">
<vue-cropper
ref="cropper"
:aspect-ratio="16 / 9"
:src="profile.avatar"
/>
</template>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
text
@click="showImageDialog=false"
>
Cancel
</v-btn>
<v-btn
color="green darken-1"
text
@click="uploadImage"
>
Upload
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<div class="mt-8">
<v-btn @click="onUpdateUser">Update</v-btn>
</div>
</v-form>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import VueCropper from 'vue-cropperjs';
import 'cropperjs/dist/cropper.css';
export default {
components: { VueCropper},
mounted() {
this.profile = this.getUserProfile ? this.getUserProfile : {}
},
data() {
return {
profile: {},
avatar: null,
userAvatarExists: false,
showImageDialog: false,
}
},
watch: {
getUserProfile(newData){
this.profile = newData;
},
deep: true
},
computed: {
...mapGetters({
getUserProfile: 'user/me',
})
},
methods: {
...mapActions({
storeAvatar: 'user/storeAvatar',
updateUser: 'user/update'
}),
onUpdateUser() {
const data = {
id: this.profile.id,
email: this.profile.email,
title: this.profile.title,
bio: this.profile.bio,
avatar: this.profile.avatar,
}
this.updateUser(data)
},
uploadImage() {
this.$refs.cropper.getCroppedCanvas().toBlob((blob => {
this.storeAvatar(blob).then((filename => {
this.profile.avatar = filename.data
this.$refs.cropper.reset()
}));
this.showImageDialog = false
}));
},
setImage(file) {
this.userAvatarExists = true;
if (file.type.indexOf('image/') === -1) {
alert('Please select an image file');
return;
}
if (typeof FileReader === 'function') {
const reader = new FileReader();
reader.onload = (event) => {
this.$refs.cropper.replace(event.target.result);
};
reader.readAsDataURL(file);
} else {
alert('Sorry, FileReader API not supported');
}
}
}
}
</script>
문제/질문:
- 보면 알수 있듯이변경한 후 프로파일을 사용자간 후 사용자가 profile코드를을 바꾸듯이 코드에서 볼 수 있다.
사진 이미지 the그림, 이미지는 다음 정보를 기반으로 렌더링되어야 합니다에 따라 렌더링 되어야 한다.
v-if="profile.avatar"그 다음이문제는 그 다음입니다. 그 문제 있다.profile.avatar그로 설정되어 있다에 설정됩니다.uploadImage기능, 템플릿도 없고 이미지가 렌더링 된 변화를 보지 않는다.템플릿은 이 변경을 인식하지 않으며 이미지는 렌더링되지 않습니다.그래서 하지만 만약 내가 코드를 바꾸면 그러나 나는 코드를 개정한다.profile.avatar단지정의로워지다가 되avatar(그것이 더 이상(이후,에 있다.profile개체), 탬플릿을 변화를 보게, 탭 이미지 correctly.object이 시작한다.에서 템플릿이 변경 내용을 표시하기 시작하고 이미지를 올바르게 렌더링합니다.왜 그럴까요?왜 그럴까?뭔가를매장에 있는에 그 편의점에서 복사하는 것과 관련이 있나것과 관련이 있나요 복사하는 가게에서?watch능하하??? ??? - 일반적으로 프로파일을 로컬 뷰 상태로 유지하는 것이 좋은 접근법입니까?아니면 일시적인 데이터라도 vuex 스토어에 저장하는 것이 좋습니까?
- 에서 알 수
mounted기능, 설정 중입니다.profile한 값getUserProfile는 '아', '아', '아', '아', '아', '아', '아', '아',watch루트를 전환할 때 함수가 다시 호출되지 않는 것 같습니다.른른른른 른른른?
이 문제는 데이터 속성의 반응성으로 인해 발생합니다.
프로파일을 개체로 사용했지만 기본적으로 아바타나 이름과 같은 속성이 없습니다. 비어 있을 뿐입니다.
vue js에서는 개체를 선언하는 경우 선언에서 키가 언급하는 것은 반응성의 일부에 불과합니다.프로파일 내의 키가 변경되면 템플릿이 재생성됩니다.
그래도 $set을 사용하여 데이터 속성 개체에 새 속성을 추가할 수 있습니다.
프로파일로 선언한 데이터: {}
실행 시 아바타를 새로운 반응 속성으로 설정하고 싶은 경우
this.$set(this.profile, key, value)
어느 것이
this.$set(this.profile, avatar, imageData)
위의 코드에서 setIuploadImage 함수는
uploadImage() {
var self = this;
self.$refs.cropper.getCroppedCanvas().toBlob((blob => {
self.storeAvatar(blob).then((filename => {
self.$set(self.profile, "avatar", filename.data)
self.$refs.cropper.reset()
}));
self.showImageDialog = false
}));
},
이것은 vuejs의 화살표 함수 안에서 작동하지 않기 때문에, 이것을 다른 변수 "self" 안에 보존하고 화살표 함수 안에서 사용했을 뿐입니다.
마운트된 함수에서도 this.getUserProfile이 빈 객체를 반환하는 경우 javascript에 따르면 빈 객체는 항상 truthy하며 프로파일에 객체를 직접 할당해도 객체는 반응하지 않습니다.
mounted() {
this.profile = this.getUserProfile ? this.getUserProfile : {}
},
위의 코드는 다음과 같이 쓸 수 있습니다.
mounted() {
if (this.getUserProfile && Object.keys(this.getUserProfile).length) {
var self = this;
Object.keys(this.getUserProfile).map(key => {
self.$set(self.profile, key, self.getUserProfile[key])
});
} else {
this.profile = {};
}
}
언급URL : https://stackoverflow.com/questions/61448072/update-data-from-local-copy-of-vuex-store
'programing' 카테고리의 다른 글
| Vuejs의 데이터에 계산된 속성 사용 (0) | 2022.08.24 |
|---|---|
| Vue 3: 컴포넌트가 반응하지 않는 이유는 무엇입니까? (0) | 2022.08.24 |
| 이게 뭘까?$root는 컴포넌트 내를 의미합니까? (0) | 2022.08.24 |
| Vue 컴포넌트 데이터 변수 이름에 동적으로 액세스 (0) | 2022.08.24 |
| 직접 DOM조작하지 않고 d3-axis을 그리세요. (0) | 2022.08.22 |