- Back
# 최초 실행 할 때만
pip install -r requirements.txt
python manage.py makemigrations
python manage.py migrate
python manage.py initialize
python manage.py runserver
python 실행 전 할 일
Database 생성
Mysql 연동 드라이버 모듈 설치
pip install Mysqlclientbackend/settings.py 에서 환경 설정
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", # "NAME": os.path.join(BASE_DIR, "db.sqlite3"), "NAME": "realpricedb", "USER": "root", "PASSWORD": "ssafy", "HOST": "localhost", "PORT": "3306", } }만일, model.py가 달라지게 된다면
initial.py와 관련된 파일을 모두 삭제한 후 다시 마이그레이션 후 실행
- Front
npm install
npm run serve
- 싫어하는 음식 필터링
음식 리스트를 보여주고, 없으면 추가하도록
- enter 눌렀을때 button으로 넘어가기
<v-form>
<v-text-field @keyup.enter="submit" />
</v-form>
<!-- v-form으로 감싸고, input에 @keyup.enter을 준다 -->
- store
// data.js - state
// step1 : DB에 맞게 형식을 맞춰준다
const state = {
userInfo: {
token: "",
user: {
pk: "",
email: "",
username: "",
first_name: "",
last_name: ""
}
}
}
// data.js -- mutations
// step2 : 트랜잭션을 수행할 부분을 지정
const mutations = {
// LOGIN, LOGOUT
logout(state) {
// 값을 초기화
state.userInfo.token = null
state.userInfo.user.email = null
state.userInfo.user.username = null
state.userInfo.user.pk = null
sessionStorage.clear()
},
login(state, payload) {
// payload에 로그인에 필요한 정보를 담아서
// state에 저장한다
state.userInfo = payload
// session에 값 저장
sessionStorage.setItem("pk", payload.user.pk)
sessionStorage.setItem("email", payload.user.email)
sessionStorage.setItem("token", payload.token)
},
}
// data.js -- actions
// step3 : 해당 기능을 수행한다.
// commit 으로 수행, mutations와 코드 거의 유사
const actions = {
// LOGIN, LOGOUT
logout({ commit }) {
commit('logout')
},
login({ commit }, payload) {
commit('login', payload)
},
}
※ 이때 안됐던 부분
: 새로 고침했을때 state의 값이 사라졌다[ 해결방법 ]
vuex-persistedstate
npm install vuex-persistedstate// store/index.js export default new Vuex.Store({ modules: { data, app }, plugins: [ PersistedState({ path: ['data'], // 필요한 모듈을 감싸면 새로고침해도 state가 날라가지 않음 }) ] });-> 단점 : 모듈이 커지면 무거워짐
Toobar 에서 Session값 가져오기computed: { userId: function(){ return sessionStorage.getItem('pk') } // state에서 정보를 가져오던것을 Toolbar에서 가져옴 },※ 문제점 : 로그인/로그아웃 했을때 새로고침해야 화면이 바뀐다
store/data.js 에서 Session 값 가져오기// store/data.js const getters = { userStatus: () => { return sessionStorage.getItem('pk') },const getters = { userStatus: () => { return sessionStorage.getItem('pk') }, }// Toobar.vue computed: { userId: function(){ return this.$store.getters['data/userStatus'] } },※ 문제점 : 로그인/로그아웃했을때 새로고침해야 화면이 바뀐다
- session 값 확인 (해당 유저가 로그인 했는지 상태 판단)
// data.js -- getters const getters = { userStatus: (state) => { return state.userInfo.user.pk } };// Toolbar.vue computed: { userId: function(){ // store - index.js - modules - app.js // - data.js // 모듈화 되어있는 구조이기 때문에 // [모듈이름 / 메소드이름] 형태로 호출해야 한다 return this.$store.getters['data/userStatus'] } },
- 로그인, 로그아웃
vue에서 Vuex를 사용할땐, distpatch 사용 !
// 로그인 this.$store.dispatch('data/login', res.data); // 로그아웃 this.$store.dispatch('data/logout');
- 로그 아웃
※ 이때 계속 안됐던 부분
this.$router.push('/')Home화면에서 로그아웃했을 때, 같은 경로에서 같은 경로를 호출해서
vue router navigationduplicated 에러 발생
if(this.$route.path !== `/`) this.$router.push('home') // 현재 경로가 일치하지 않을때만 home으로 이동하게 수정
-
음식점 상세페이지
-
만족도 그래프
npm i vue-doughnut-chart
-
글자수 넘어가면 더보기 버튼
computed:{ content: function(){ if(!this.more) return this.review.content.slice(0, 50); else return this.review.content } }, // 더보기 누르면 more : true // computed 에서 if 조건으로 바꿔주기
-
리뷰 + 만족도 퍼센트
-
가격 내에 먹을 수 있는 음식점만 보여주기
// computed // price 이하인 음식메뉴만 보여주기 menus: function() { return this.$store.getters["data/menus"].filter( list =>{ return list.price <= this.store.price }); }
※ 이때 계속 안됐던 부분
새로운 화면에서 태그안에 click 이벤트를 걸었는데 작동하지 않았음 ==>
<mdb-card class="card-body2 mb-3 border-color" @click.native="clickItem()"> // @click.native 으로 해결
-
-
modal
-
v-dialog 사용
'유저 추가하기' 버튼을 누르면 모달 발생
※ 이때 계속 안됐던 부분
<v-btn slot="activator" color="primary" dark>유저 추가하기</v-btn>
이렇게 실행하면 [Vuetify] The activator slot must be bound 이 에러가 계속 발생
=> slot의 영역이 애매하게 엮여있어서 모호해서 발생하는 문제
[해결방법]
<template v-slot:activator="{ on }"> <v-btn color="primary" dark v-on="on">유저 추가하기</v-btn> </template>
버튼을 template으로 감싸준다
-
<v-dialog v-model="dialog" persistent max-width="500px"> <template v-slot:activator="{ on }"> <v-btn color="primary" dark v-on="on">유저 추가하기</v-btn> </template> /////// 모달 내용 </v-dialog>export default { data() { return { dialog: false }; } };
- UserSearch
이메일을 검색하면, 일치하는 유저가 나오도록 return
- Vuetify - click 이벤트
<v-btn @click="logout">로그아웃</v-btn>
<!-- Vuetify에서는 클릭이벤트 @사용 -->
-
세션
-
localStorage vs sessionStorage 비교
-
localStorage
사용자가 지우지 않는 이상 데이터가 계속 브라우저에 남아있는다
ex) 지속적으로 필요한 데이터( 자동로그인 )
-
sessionStorage
윈도우나 브라우저 탭을 닫을 경우 제거
ex) 잠깐 동안 필요한 정보(일회성 로그인 정보)
[공통점] 클라이언트에 저장한다
-
-
사용법
// 데이터 저장 sessionStorage.setItem(key, value) // 데이터 불러오기 sessionStorage.getItem(key) // 데이터 삭제 sessionStorage.removetem(key) // 모든 데이터 삭제 sessionStorage.clear()
-
로그아웃
-
Vuex 사용한 로그아웃
- store/modules/data.js 에서 mutations 사용
-
-
-
Vuex
-
store : 애플리케이션 상태를 보유하고 있는 컨테이너'
-
mutation : 동기적으로 트랜잭션
-
action
액션으로 변이에 대한 커밋
작업에는 비동기 작업이 포함될 수 있음
-
애플리케이션 구조 --- ##### 우리형식에 맞게 수정필요 !
├── index.html ├── main.js ├── api │ └── ... # API 요청을 위한 추상화를 포함합니다. ├── components │ ├── App.vue │ └── ... └── store ├── index.js # 모듈을 조합하고 저장소를 내보내는 곳 입니다. ├── actions.js # 루트 액션 ├── mutations.js # 루트 변이 └── modules ├── cart.js # cart 모듈 └── products.js # products 모듈
-
-
Component
Parent : Component 포함한 vue
데이터 전달 할 때 : v-bind로 보낸다
Child : component
v-on
※ 이때 내가 오해한 부분
java 처럼 확장의 개념으로 생각해서
component부분을 parent로 사용하고, view/vue 를 child로 생각한점...
- slot
- 기본값 설정
하위 컴포넌트에서 으로 값을 미리 설정
상위 컴포넌트에서 값을 넣어주면, 해당 값으로
안넣어주면, slot 값으로 화면 랜더링
하위 컴포넌의 값을 상위 컴포넌트에서 접근
원래는 하위 컴포넌트의 값을 상위 컴포넌트에서 접근 불가능
slot으로 쓰면 가능
<!-- 하위 컴포넌트 --> <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span><!-- 상위 컴포넌트 --> <current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>[ 설명 ] :
하위 컴포넌트에서 사용하고자 하는 data를 v-bind 로 지정
상위 컴포넌트에서 'slotProps' 로 지정해서 data에 접근해서 사용
- from 형식
<form @submit.prevent= "handleSubmit">
<!-- 입력양식을 확인해 준다-->
<v-text-field required/>
</form>
-
$ 의 의미
Vue 내에서 router, store을 접근하기 위해서는 $를 사용한다
예)
this.$store.dispatch('data/login', res.data);
상위 폴더를 접근하기 위해서 $ 사용
new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount("#app");
- Computed vs Watch
- Computed : 반응형 Getter
- Watch : 반응형 콜백 Vue의 인스턴스의 특정 프로퍼티가 변경될 때, 지정한 콜백 함수 실행
-
Git
-
권한 거부
cannot stat 'blahblah' : Permission denied
// git checkout / git pull 이 안됐던 문제
실행 중인 vs Code를 종료하고 다시 git pull 하니 문제가 해결되었다.
cannot stat 'blahblah' : Permission denied
-