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)로 출력되는 것을 볼 수 있다.
문제
분명 이틀전까지만 해도 vue파일에서 emmet과 저장을 매우 멀쩡하게 잘만 사용했었다.
그런데.. 오늘 사용하려니까 갑자기 vue 확장자를 가진 파일들만 저장이 되지 않고!
'’Vetur’, ‘ESLint’‘(구성)에서 코드 동작을 가져오는 중입니다.
위와 같은 문구들이 경고창으로 뜨면서 계속 로딩 표시만 나타났다..
그리고 다음 사진과 같은 경고창이 갑자기 생겼다..

vetur 파일이 tsconfig.json 파일 어쩌구 경고는 이전에도 계속 떴던거라 걍 무시했고, in the vue3 project 어쩌구 경고는 오늘부터 갑자기 뜨기 시작했다.
경고창에 vue language server를 다운 받으라기에 일단 다운 받았었다.
output에도 vue language server에 error가 뜨고…
이 경고가 뜬 이후부터 나의 모든 vue파일들은 emmet이 작동되지 않고 파일이 제대로 저장되지 않았다…
In the vue 3 project, The Vue Language Features (Volar) is new recommended extension in VSCode.
Request textDocument/colorPresentation failed.
Message: Request textDocument/documentColor failed with message: (0 , rCe.default)(…).filter is not a function
Code: -32603
해결
아무리!!! 서칭을 해도 나오지가 않아서 @volar-plugins/vetur
도 설치하구.. 설정 파일에서 emmet관련 코드도 추가했지만.. 도저히 제대로 작동하지가 않았다.
그렇게 몇시간을 헤매던 중..
vue3는 vetur가 아닌 volar이라는 것을 사용해야 한다는 걸 알게됐고.. 기존의 vetur은 비활성화를 해두고 volar만 사용을 하라는 글을 발견했다.
그렇다. 이것이 정답이었다!!!!!
vetur는 다음 사진과 같이 비활성화를 하고 volar (vue language sever)
만 활성화를 해야지 위와 같은 오류들도 안 생기고, 정상적으로 vue를 사용할 수 있다.

사용안함(작업영역)으로 변경하면 된다. 나중에 또 사용할때는 사용으로 돌리면 된다!
정상작동

이제는 emmet도 정상적으로 작동하고 vue 파일 저장 역시 정상적으로 잘 작동한다.
아무리 서칭해도 안 나오길래… 나같은 분을 위해서 (나만 바보인걸지도) 글을 적어본다.
Container 너비 사용자 지정
BootStrap: Containers
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px,
xxl: 1320px
);
bootstrap의 containers 내용에서 sass 부분을 확인하면 container의 너비가 지정되어져 있는 것을 볼 수 있다.
해당 내용을 복사하여 src 폴더의 scss 폴더 내부의 main.scss 파일에 붙여넣는다. 그리고 원하는 너비로 변경해주면 된다.
변경한 너비
$container-max-widths: (
sm: 540px,
md: 704px,
lg: 924px,
xl: 1140px,
xxl: 1364px
);
해당 내용을 variables 파일에 덮어써져서 사용된다.
에러 메세지 출력과 로딩 애니메이션
로딩 애니메이션
BootStrap: Spinners
class 이름으로 "spinner-border text-primary"
만 작성하면 간단하게 로딩 애니메이션을 사용할 수 있다.
-
검색 시작과 끝에만 사용하기
검색을 시작하는 부분인 searchMovie의 가장 윗부분에 loading 상태가 true가 되도록 작성한다.
loading 상태는 catch 구문이 실행되던 안되던 간에 무조건 끝나야 하기 때문에 finally를 통해 loading이 false가 되도록 한다.
-
중복실행 방지
다음과 같은 코드를 추가하여 loading 값이 true일때 return을 실행하게 하여 loading 값을 false로 반환하도록 한다.
if (state.loading) {
return
}
commit('updateState', {
message: '',
loading: true
})
최초의 searchMovies는 loading값이 false이기 때문에 if 조건문이 실행되지 않고 아래의 로직이 실행되게 된다.
그러나, 최초의 searchMovies가 아직 실행되고 있는 상태(loading: true)에서 또 검색 버튼을 누르는 등의 행위를 통해 searchMovies 부분을 또 실행시키게 되면 loading 값은 아직 true인데 if 조건문으로 인해 retrun 값이 반환되면서 loading이 false상태가 되는 등의 에러가 발생하게 된다.
그렇게 되면 함수가 종료되면서 밑의 로직은 동작하지 않게 된다.
이렇게 간단한 if 조건문을 통해서 사용자가 searchMovies를 여러번 실행하는 것을 방지하게 한다.
그리고 정상적으로 로직이 종료되게 되면 finally를 통해 무조건적으로 loading은 false로 변하게 된다.
정상적으로 로직이 종료되면 다시 searchMovies를 정상적으로 실행이 가능하게 된다. loading이 false가 되었으니 if 조건문에 걸리지 않게 되기 때문이다.
에러 메세지 출력
에러 메세지가 출력되는 부분에 다음과 같은 코드를 추가한다.
:class="{ 'no-result': !movies.length }"
해당 코드는 class: no-result를 추가하는 속성이다.
movies의 length(길이) 즉, 검색된 영화가 없을때 해당 class 이름을 추가하도록 한다.
movie.js 의 _fetchMovie의 catch에서 error가 발생하면 error 문구를 출력하도록 하는데, 검색된 영화가 존재하지 않는다는 error문구가 이때 출력된다.
텍스트 말줄임 표시와 배경 흐림 처리
텍스트 말줄임 표시
div {
whith-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
-
white-space: nowrap;
공백문자를 처리해주는 속성이다.
nowrap, 감싸지 않겠다는 의미이다. 줄바꿈 처리가 되지 않고 한줄로만 표시될 수 있도록 한다.
MDN: white-space - CSS
추가) 공백 문자는 띄어쓰기(space)나 들여쓰기(tab) 등을 의미한다.
-
overflow: hidden;
텍스트가 박스 바깥으로 튀어나오는 부분을 잘라낸다.
-
text-overflow: ellipsis;
텍스트가 박스 바깥으로 넘쳐서 잘리는 부분이 말줄임 표시가 된다.
ellipsis는 생략이라는 의미이다.
text-overflow는 overflow와 white-space와 대부분 같이 사용하며, 해당 방식의 사용이외에는 잘 사용되지 않는다.
MDN: text-overflow - CSS
배경 흐림 처리
div {
backdrop-filter: blur(10px);
}
-
backdrop-filter: blur();
backdrop-filter은 해당하는 요소 범위에서 보이는 배경에 css의 여러 필터 효과를 적용해주는 속성이다.
단, 브라우저 호환성을 확인했을 때 Firefox에서는 호환이 불가능하다는 단점이 있다.
-
blur(px)
배경을 흐림처리한다.
-
grayscale(%)
배경을 흑백처리한다.
MDN: backdrop-filter - CSS
비동기
콜백 (callback)
function a(callback) {
setTimeout(() => {
console.log('A')
callback()
}, 1000)
}
function b() {
console.log('B')
}
a(function () {
b()
})
callback, 호출 뒤에 실행한다는 것으로. a함수의 로직이 끝난 다음에 b함수 로직을 실행하도록 콜백함수를 사용하였다.
콜백함수를 사용하지 않고 단순히, a와 b를 호출했다면, a의 setTimeout으로 1초뒤에 출력되기 때문에, b가 먼저 출력되고 a가 출력되었을 것이다.
하지만, 콜백함수 사용으로 a가 호출되고 나면 b가 실행되는 구조가 되었다.
어떤 상황에서든 우리가 실행한 함수 순서대로 출력이 되는 것이다.
Promise 객체
promise는 약속의 객체이다.
function a() {
return new Promise(function (resolve) {
setTimeout(function () {
console.log('A')
resolve()
}, 1000)
})
}
function b() {
console.log('B')
}
async function test() {
await a()
b()
}
test()
promise 객체의 생성자(new)를 통해서 내부에 1초뒤에 ‘A’가 출력되도록 작성했다.
a 함수가 실행되고 내부에 있는 console.log의 A를 출력하는 로직이 동작한 다음에 다른 코드가 실행되는 것을 보장하려면 콜백에서 callback()을 호출한 것 처럼 resolve라는 매개변수를 호출하면 된다.
즉, 단순하게 설명하자면 callback 자리에 resolve를 작성하면 된다.
test 함수 내부에서 a 함수를 기다린(async await)다음에 b함수를 실행해줄 수 있다.
promise라는 약속의 객체가 반환이 되면, 해당 자리에 await 키워드를 붙일 수 있다. 해당 부분에서 resolve 매개변수가 실행될 때까지 기다려(await) 줄 수 있다.
a 함수가 실행되기 시작해서 마지막에 resolve 매개변수가 호출되기 전까지 기다렸다가, resolve가 호출되면 그 다음 코드로(b 호출) 넘어갈 수 있다.
즉, 실행 순서는 a함수 → resolve → b함수
-
콜백 지옥을 promise 객체로 벗어나기
async function test() {
await a()
await b()
await c()
await d()
console.log('Done!')
}
test()
예외처리
Promise
비동기를 통해서 로직을 기다렸다가 처리가 끝나면 처리가 온전히 완료되거나 실패될 수 있는데 그것에 대한 결과를 반환하는 것을 말한다.
MDN: Promise - JavaScript
대기, 이행, 거부
-
대기(pending)
이행하지도, 거부하지도 않은 초기 상태.
비동기 함수가 실행되기 시작해서 이행이나 거부가 되기 직전까지의 내용을 전부 대기라고 한다.
-
이행(fulfilled)
연산이 성공적으로 완료됨.
기본적인 로직이 완료되면 resolve 매개변수를 실행한다.
이것은, 로직이 정상적으로 처리됐다는 것을 의미하기 때문에 resolve 매개변수가 실행된다는 것이 성공적으로 연산이 완료됐다는 이행을 의미한다.
-
거부(rejected)
연산이 실패함.
비동기 패턴에서 기본적인 로직에 문제가 발생해서 연산이 실패하면 비동기에 대한 거부를 할 수 있고 reject가 실행됨으로 rejcet이 실행됐다는 것은 거부를 의미한다.