페이지 전환 스크롤 위치 복구
Vue Router: scrollBehavior
scrollBehavior을 사용하여 페에지 전환시 스크롤 위치를 원하는 곳으로 옮겨지도록 한다.
기존에는 홈 화면에서 스크롤을 최하단으로 내린 후, 영화를 선택하면 movie 페이지를 처음 보여줄때 홈에서 스크롤을 내렸던 만큼 화면을 내려서 보여줬다.
그러나, scrollBehavior을 통해 스크롤을 최상단으로 바꿔준다.
검색 정보 초기화
movie.js 파일에 기존에 존재하던 resetMovies 함수에 기능을 추가해준다.
기존에는 홈에서 movie 페이지로 전환 후, 다시 홈 화면으로 뒤로가기를 했을 때 변수 _defaultMessage 문구가 뜨지 않았다.
state.message를 통해서 문구를 나오게 한다. loading 이모션 또한 false로 변경해준다.
resetMovies(state) {
state.movies = [] // 빈 배열로 초기화
state.message = _defaultMessage
state.loading = false
}
Home.vue 파일에서 created라는 컴포넌트가 생성된 직후에 동작하는 라이프사이클에서 commit 메소드를 통해서 store안에 있는 movie 파일의 resetMovies라는 변이 메소드를 실행해준다.
created() {
this.$store.commit('movie/resetMovies')
}
메소드 실행을 통해서 화면을 리셋할때 배열이 초기화되면서 기본 메세지도 출력된다.
Vuex: State
계산된 데이터(computed)를 이용해서 컴포넌트 내부에서 사용할 데이터들을 하나씩 만들때, 유사한 코드들을 반복적으로 작성하게 된다.
computed: {
image() {
return this.$store.state.about.image
},
name() {
return this.$store.state.about.name
},
email() {
return this.$store.state.about.email
},
blog() {
return this.$store.state.about.blog
},
phone() {
return this.$store.state.about.phone
}
},
이럴때, mapState를 사용하면 간략하게 코드를 작성할 수 있다.
state를 map이라는 단어처럼 반복적으로 출력해서 computed 옵션에 등록을 시켜줄 수 있다.
문서 예시
computed: mapState([
// map this.count to store.state.count
'count'
])
mapState함수를 실행해서 내부에 하나의 배열 데이터를 추가해주고, 배열 데이터안에서 내가 사용하고 싶은 스토어의 상태만 문자데이터로 명시해주면 된다.
mapState 뿐만 아니라 mapGetters, mapMutations, mapActions 등, vuex helper등이 있다.
mapState 적용하기
computed: {
...mapState('about', [
'image',
'name',
'email',
'blog',
'phone'
])
},
mapState 앞에 전개연산자 (…)을 붙여준다. mapState 함수가 실행이 되고, 반환된 결과가 작성했던 계산된 데이터처럼 자동으로 등록될 수 있다.
첫번째 인수로는 우리가 사용할 모듈을 작성해준다. 두번쨰 인수로, 배열안에 상태(state)를 작성해주면 된다.
해석하자면 about 모듈안에 있는 image 상태, name 상태를 가져와서 등록해준 것이다.
전개연산자를 붙여주는 이유는 우리가 computed 옵션에 mapState 작성하는 것이 아니기 때문이다. 우리가 만든 함수가 있을 수도 있기 때문이다. 그렇기에 mapState 함수를 문서 예시처럼 직접 할당하지 않는 것이 좋다.
되도록이면 다른 계산된 데이터가 없더라도 앞에 전개연산자를 통해서 하나의 객체 데이터 내부에 작성하는 방식을 추천한다.
mapActions
created() {
console.log(this.$route)
this.$store.dispatch('movie/searchMovieWithId', {
id: this.$route.params.id
})
},
methods: {
requestDiffSizeImage(url, size=700) {
if (!url || url === 'N/A') {
this.imageLoading = false
return ''
}
const src = url.replace('SX300', `SX${size}`)
this.$loadImage(src)
.then(() => {
this.imageLoading = false
})
return src
}
}
mapState와 거의 동일하며 두번째 인수에는 메소드처럼 사용하고 싶은 action의 이름을 문자 아이템으로 등록하면 된다.
그리고 기존 dispatch는 삭제하고 this에 등록한 action의 이름을 메소드로 바로 실행하면 된다.
created() {
console.log(this.$route)
this.searchMovieWithId({
id: this.$route.params.id
})
},
methods: {
...mapActions('movie', [
'searchMovieWithId'
])
requestDiffSizeImage(url, size=700) {
if (!url || url === 'N/A') {
this.imageLoading = false
return ''
}
const src = url.replace('SX300', `SX${size}`)
this.$loadImage(src)
.then(() => {
this.imageLoading = false
})
return src
}
}
mapActions의 경우, store에서 코드만 봐서는 actions라는 것을 알수 없기 때문에 직접적으로 dispatch 메소드를 사용해서 해당하는 action을 사용해주는 것이 직접적이여서 추천한다.
따라서, mapstate가 아닌 actions, mutations에서는 활용도가 높지는 않다.
BT: Breakpoint (반응형)
BootStrap: Breakpoints
부트스트랩 내부에서 mixin을 통해서 만들어져 있는 기본적인 재활용 가능한 코드(media-breakpoint-up 등..)를 제공한다. 이 코드를 include 규칙을 통해서 가지고 와서, 인수로 뷰포트의 크기가 sm,md,lg 등 인지를 명시해서 내용을 활용할 수 있다.
@include media-breakpoint-down(sm) {
.nav {
display: none;
}
}
모든 컴포넌트에서 전역 스타일 가져오기
style 태그에서 매번 import를 통해 scss의 main.scss 파일을 가져왔다.
하지만, 매번 작성하지 않아도 컴포넌트 내부에서 사용할 수 있는 구조를 만들어보고자 한다.
GitHub - webpack-contrib/sass-loader: Compiles Sass to CSS
sass-loader의 additionalData를 사용하여 모든 컴포넌트에서 전역 스타일을 가져온다.
webpack.config.js 파일에서 rules option 부분에 sass-loader를 사용하는 곳에서 문자 데이터 형태를 객체 데이터 형태로 바꿔준다.
loader는 sass-loader, options는 additionalData를 통해서 필요로 하는 데이터를 추가해준다.
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: "$env: " + process.env.NODE_ENV + ";",
},
},
],
},
],
},
};
additionalData의 명시된 코드가 우리가 사용하는 모든 scss파일의 가장 앞 부분에 삽입이 된다. 이로인해, 우리가 따로 import를 추가하여 scss폴더의 main.scss 파일을 불러오지 않아도 자동으로 가져와진다.
-
기존
{
test: /\.s?css$/,
use: [
// 순서 중요!
'vue-style-loader',
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
}
-
변경
{
test: /\.s?css$/,
use: [
// 순서 중요!
'vue-style-loader',
'style-loader',
'css-loader',
'postcss-loader',
{
loader: 'sass-loader',
options: {
additionalData: '@import "~/scss/main";'
}
}
]
},
additionalData부분에 우리가 매번 명시하는 코드를 작성해주면 된다.
이때, 주의할 점은 세미콜론 빼먹지 말기!이다.
해당 코드를 추가하면, 기존에 파일에 작성했던 코드들은 모두 제거해줘야 한다.
Vue Router: 404 Page Not Found
Vue Router: 404 not found route
특정한 경로 부분에 정규표현식을 제공해서, 정규표현식과 매칭되는 주소는 NotFound라는 component를 제공해서 메세지를 보여줄 수 있다.
const routes = [
{ path: '/:pathMatch(.**)**', name: 'NotFound', component: NotFound },
{ path: '/user-:afterUser(.*)', component: UserGeneric },
]
주소부분에 슬래쉬(/) 하나만 작성하게 되면 메인페이지가 된다.
/moive/:id 는 movie페이지에 id라는 파라미터를 가지고 페이지를 동적으로 제어할 수 있다.
404 not found의 경우에는 슬래쉬 뒤에 pathMatch라는 파라미터를 추가해서 뒤에 소괄호 안에 정규식을 작성해 줄 수 있다.
소괄호 안의 정규표현식은 마침표(.)는 임의의 하나의 문자와 일치, 별표(*) 최대한 많은 문자와 일치이다.
즉, 우리가 지정한 것 이외에 모든 것들을 매칭해서 notfound 페이지를 보여주게 된다.
위 코드에서는 파라미터 이름이 pathMatch라고 되어있는데 해당 이름으로 사용 안하고 원하는 이름으로 변경해도 된다.
flex-shrink
컨테이너의 크키가 부족해질 때, 아이템의 크기가 얼마나 줄어들 수 있는지를 나타낸다.
기본값은 1이다. 값이 1일때, 컨테이너 사이즈에 따라 자동으로 축소된다.
아이템의 크기가 축소되지 않게 하려면 값을 0으로 바꿔주면 된다.
flex-grow
컨테이너의 공간이 남을 경우 각 아이템들의 크기가 얼마나 더 할당이 가능한지 타나낸다.
만약 컨테이너 사이즈가 600px이고 아이템 1은 100px, 2는 200px일때, 컨테이너는 300px이 남는다. 아이템들에 flex-grow 값을 1은 1, 2는 2로 할당하면 남은 컨테이너 크키만큼 각 아이템들이 커진다. 따라서 1은 200px, 2는 400px이 된다.
가운데 점 ( · ) 추가하기
span {
&::after {
content: "\00b7";
margin: 0 6px;
}
&:last-child::after {
display: none;
}
}
content의 “\00b7”은 css entities in numeric order이다.
기호를 숫자로 나타낼 수 있도록 하는 것이다.
span태그 뒤에 가운데 점을 추가하고 싶기 때문에 가상요소 after을 통해 점을 만들어준다.
맨 마지막 span 태그 뒤에는 점이 필요하지 않기 때문에 없애주기 위해 last-child를 통해 display를 none으로 만들어줌으로 점을 보이지 않게 한다.
사진 고해상도로 변경
실시간 이미지 리사이징
서버에 저장이 된 특정한 이미지를 특정한 url 주소로 요청을 할때, 사이즈를 명시해서 요청을 전송한다. 실시간으로 이미지를 요청 받은 사이즈로 리사이징해서 사용자에게 전달한다.
AWS Lambda@edge로 실시간 이미지 리사이징(updated)
이미지의 주소를 봤을 때, 특정 부분의 숫자를 변경해주면 더 큰 사이즈의 고해상도 이미지를 얻을 수 있다고 판단했을 때 사용이 가능하다.
이미지의 뒷부분을 확인해 봤을 때 SX300이라고 되어있다. 300부분을 700으로 변경해보면, 700사이즈의 고해상도 이미지가 출력되는 것을 확인할 수 있다.
methods: {
requestDiffSizeImage(url, size=700) {
return url.replace('SX300', `SX${size}`)
}
}
script 태그에 methods를 추가하여 requestDiffSizeImage함수를 만든다. 해당 함수는 원하는 size를 넣어서 해당 size의 이미지로 변경하게 만들어주는 함수이다.
replace를 통해서 SX300을 SX${size}로 변경해준다.
이때, 때마다 입력하는 사이즈를 다르게 변경해야하기 때문에 size 변수를 만든 것이다. size를 넣기 위해서는 보간을 통해 넣어야 한다.
:style="{ backgroundImage: `url(${requestDiffSizeImage(theMovie.Poster)})` }"
해당 함수를 poster 이미지를 출력하는 부분에 넣어주면 원하는 사이즈(700)로 출력되는 것을 볼 수 있다.