git clone

$ git clone https://github.com/joshua1988/vue-til-server.git

$cd vue-til-server

 

반응형

 

Vuter

 

Vue VSCode Snippets

 

ESLint

 

TSLint

 

반응형

https://swagger.io/

 

API Documentation & Design Tools for Teams | Swagger

 

swagger.io

 

반응형

Vue 3.X 이상의 경우 ES6사용으로 인해 IE브라우저를 지원하지 않는다 
IE 지원을 위해 polyfill등의 추가 세팅이 필요

Polyfill 

Vue 3.X 이상의 경우 ES6사용으로 인해 IE브라우저를 지원하지 않는다 
IE 지원을 위해 polyfill등의 추가 세팅이 필요
  • @babel/polyfill, @babel/preset-env 설치 
npm install --save @babel/polyfill
npm install --save-dev @babel/preset-env
  • main.js (※ 최상단에 위치할 것)
//main.js

import '@babel/polyfill'
import Vue from 'vue'

 

  • vue.config.js 세팅된 선언이 많을 경우 하단에 ' , ' 입력 후 이어서 붙여주기
//vue.config.js

const ansiRegex = require('ansi-regex');

module.exports = {
	transpileDependencies: [ansiRegex]
}

 

  • babel.config.js
// babel.config.js

module.exports = {
	presets: [
		['@babel/preset-env']
	]
}

 

반응형

vue.config.js

- vue.config.js 파일에 configureWebpack 옵션을 추가

- 프로젝트 bulid 시 css 와 js 파일 단일파일로 추출 (컴파일)

// vue.config.js
module.exports = {
  css: {
  	extract: {
    	filename: 'portfolio_ui' +"-"+ require("./package.json").version + '.min.css'
    },
  },
  configureWebpack: {
    output: {
        filename: 'portfolio_ui' +"-"+ require("./package.json").version + '.min.js'
    },
    optimization: {
        splitChunks: false
    }
  },
}
반응형

@mixin 

재사용할 스타일의 선언그룹을 만들면 불필요한 중복을 줄일 수 있다.

css에서 다양한 브라우저를 지원하기위해 vendor prefix를 여러차례 재사용할 경우가 있는데 이때 재사용할 CSS 선언그룹을 만들 수 있다. 

 

_mixins.scss

//----------------------------------
//      Vendor Prefix
//----------------------------------
// @param {*} $property Property
// @param {*} $value Value
@mixin prefix($property, $value) {
  -webkit-#{$property}: $value;
  -moz-#{$property}: $value;
  -ms-#{$property}: $value;
  -o-#{$property}: $value;
  #{$property}: $value;
}

// @param {Size} $radius [5px] - Radius
// @require {mixin} prefix

@mixin border-radius($radius: 5px) {
  @include prefix("border-radius", $radius);
}

//----------------------------------
//      Animation & keyframes
//----------------------------------
// Keyframes
// @param {*} $animation-name - Animation name
// @content [Animation css]

@mixin keyframes($animation-name) {
  @-webkit-keyframes #{$animation-name} {
    @content;
  }
  @-moz-keyframes #{$animation-name} {
    @content;
  }
  @-ms-keyframes #{$animation-name} {
    @content;
  }
  @-o-keyframes #{$animation-name} {
    @content;
  }
  @keyframes #{$animation-name} {
    @content;
  }
}

// Animation
// @param {*} $str - name duration timing-function delay iteration-count direction fill-mode play-state ([http://www.w3schools.com/cssref/css3_pr_animation.asp](http://www.w3schools.com/cssref/css3_pr_animation.asp))
// @require {mixin} css3-prefix

@mixin animation($str) {
  @include prefix("animation", $str);
}

//------------------
//   placeholder
//------------------

@mixin optional-at-root($sel) {
  @at-root #{if(not &, $sel, selector-append(&, $sel))} {
    @content;
  }
}

@mixin placeholder {
  @include optional-at-root("::-webkit-input-placeholder") {
    @content;
  }

  @include optional-at-root(":-moz-placeholder") {
    @content;
  }

  @include optional-at-root("::-moz-placeholder") {
    @content;
  }

  @include optional-at-root(":-ms-input-placeholder") {
    @content;
  }
}

//  float  clearfix
@mixin clearfix {
  &::before {
    content: "";
    display: block;
    clear: both;
    overflow: hidden;
   // visibility: hidden;
    height: 0;
  }
}

@mixin ghostVerticalAlign() {
  &:before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    height: 100%;
    width: 0.1px;
  }
}

// generic transform
@mixin transform($transforms) {
  -moz-transform: $transforms;
  -o-transform: $transforms;
  -ms-transform: $transforms;
  -webkit-transform: $transforms;
  transform: $transforms;
}

// rotate
@mixin rotate($deg) {
  @include transform(rotate(#{$deg}deg));
}

// scale
@mixin scale($scale) {
  @include transform(scale($scale));
}
// translate
@mixin translate($x, $y) {
  @include transform(translate($x, $y));
}
@mixin translateX($x) {
  @include transform(translateX($x));
}
@mixin translateY($y) {
  @include transform(translateY($y));
}

//transform origin
@mixin transform-origin($origin) {
  moz-transform-origin: $origin;
  -o-transform-origin: $origin;
  -ms-transform-origin: $origin;
  -webkit-transform-origin: $origin;
  transform-origin: $origin;
}

// Flexbox display
@mixin flexbox {
  display: -webkit-box;
  //@debug: -webkit-flex;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;
}

@mixin justify-content($justify) {
  -webkit-justify-content: $justify;
  -moz-justify-content: $justify;
  -ms-justify-content: $justify;
  justify-content: $justify;
  -ms-flex-pack: $justify;
}
@mixin align-items($align) {
  -webkit-algin-items: $align;
  //algin-items: $align;
}

//Get the value for justify-content
@function getJustify($arg) {
  $justify: (
    "sa": space-around,
    "sb": space-between,
    "se": space-evenly,
    "center": center,
    "fs": flex-start,
    "fe": flex-end,
  );

  @each $key, $value in $justify {
    @if ($key == $arg) {
      @return $value;
    }
  }
}

//Get the value for align-items
@function checkAlign($arg) {
  $align: (
    "b": baseline,
    "s": stretch,
    "sa": space-around,
    "sb": space-between,
    "center": center,
    "fs": flex-start,
    "fe": flex-end,
  );

  @each $key, $value in $align {
    @if ($key == $arg) {
      @return $value;
    }
  }
}

// Display flex
@mixin display-flex() {
  @include flexbox;
  @content;
}


@mixin hover-support {
  @media not all and (pointer: coarse) {
    &:hover {
      @content;
    }
  }
}

 

_common.scss

input { 
  @include prefix(box-sizing, border-box);
  @include prefix(appearance, none);
  @include placeholder {
    color: #aeaeae;
    opacity: 1;
  }
}
반응형

Variables (변수)

$를 사용하여 변수를 지정한다. 중복된 단어를 변수로 치환하여 유지보수가 쉬워진다.

 

_variables.scss


// font-family
$font-bk: "NotoBK", san-serif;
$font-b: "NotoB", san-serif;
$font-m: "NotoM", san-serif;
$font-r: "NotoR", san-serif;
$font-dl: "NotoDL", san-serif;
$font-l: "NotoL", san-serif;

// txt-colors
$txt-gray: #747473;
$txt-def: #333;
$txt-disabled: #b8b8b8;
$txt-pink: #f34176;
$txt-red: #ea6575;
$txt-navy: #24364f;
$txt-blue: #2b40ab;
$txt-yw: yellow;

 

_common.scss

- 등록한 변수 사용하기

body {
	font-family: $font-r;
    color: $txt-def;
}

 

반응형

Nesting (중첩)

계층적으로 상속되는 CSS를 더욱 계층적으로 보이게 만드는 기능으로 중괄호가 겹쳐져서 작성됩니다.

관련 요소들을 그룹화 하여 보다 깔끔해지고 중복을 최소화합니다.

// scss
nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  
  li {
  	display: block;
  }
  
  a {
    display: blick;
    padding: 6px 12px;
    text-decoration: none;
  }
}
반응형

CSS Pre-Processor란?

자신만의 특별한 구문(Syntax)을 가지고 CSS를 생성하는 프로그램이다.

CSS의 문제점을 프로그래밍 방식, 즉 변수·함수·상속 등 일반적인 프로그래밍 개념을 사용하여 보완한다.

CSS 전처리기에는 다양한 모듈이 존재하는데 그 중에서도 Sass·Less·Stylus가 가장 많이 사용된다.

CSS 전처리기는 공통 요소 또는 반복적인 항목을 변수 또는 함수로 대체할 수 있는 재사용성, 임의 함수 및 내장 함수로 인해 개발 시간과 비용 절약, 중첩·상속과 같은 요소로 인해 구조화된 코드 유지 및 관리 용이 등의 장점이 있다.

반면 전처리기를 위한 도구가 필요하고 다시 컴파일하는데 시간이 소요된다는 단점도 존재한다.

 

CSS Pre-Processor 사용률

 

SASS
- 가장 오래된 전처리기. 활발히 개발되고 있으며, 가장 많은 개발자들이 선택한 라이브러리
- Ruby, Node-sass 

Less
- 브라우저에 내장된 JS인터프리터만으로 컴파일 가능하므로 디펜던시에서 자유로움
- Node.js 기반으로 구동되며 Sass다음으로 활발히 개척되고 있어서, 유용한 라이브러리나 mixin 구현물들을 쉽게 찾을 수 있다.

PostCSS
- Sass, Less 와 같은 전처리기는 내부에서 제공하는 문법이 정해져있고 한정적이지만 PostCSS는 플러그인이 굉장히 다양하다. 이 때문에 최근 Sass와 Less보다 PostCSS사용에 대한 높은 만족도로 선호도가 올라감.

Stylus
- 상대적으로 프로그래밍 언어의 특징을 많이 포함하고 있습니다.
- CSS 프로퍼티 내에서 연산자나 함수, 루프 등을 비교적 자유롭게 사용할 수 있습니다.
- 반대로 위 특징때문에 문법에 혼재가 있어서 처음 전처리를 시작하는 사람에게는 상대적으로 장벽이 높습니다.

 

 

반응형

반응형 (PC,태블릿,모바일) 웹브라우저 환경에서 미지원화면 대체 컨텐츠 노출 대응

모바일 가로모드 미지원시 대체화면이 노출되도록 대응하는 내용입니다.

 

NotSupport.vue라는 미지원대체화면 컨텐츠 파일생성

 

App.vue

- 루트 파일인 App.vue에서 NotSupport 연결

<!-- App.vue -->
<template>
	<NotSupport v-show="isNotSupport" id="isNotSupport"/>
</template>
<script>
import Vue from 'vue'
import NotSupport from './components/NotSupport.vue';

export default {
  	name : 'App',
    data () {
      return {
        isNotSupport: false,
      }
    },
    components : { 
      NotSupport,
    },
 
}
</script>

- 디바이스 감지에 대한 스크립트 

<!-- App.vue -->
<script>
export default { 
    ...

    methods : {
      // 미지원 대체화면
      srceenHandler() {
        // 모바일 & 태블릿 구분
        var mobileTablet = /Android|Mobile|iP(hone|od|ad)|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/;

        // 세로모드 구분
        var isPortrait = window.innerWidth <= window.innerHeight;

        if (navigator.userAgent.match(mobileTablet)) {
          if (navigator.userAgent.match(/iPad|Android/i)) {
            // 아이패드, 안드로이드 OS
            if (window.matchMedia("(min-width: 361px) and (max-width: 600px)").matches) {
              if (isPortrait) {
                // 세로 모드일때 
                this.isNotSupport = false;
              } else {
                // 가로 모드일때
                this.isNotSupport = true;
              } 
            } else {
              this.isNotSupport = false;
            }

          } else if(navigator.userAgent.match(/iPhone|iPod/i)) {
            // 아이폰
            if (isPortrait) {
              // 세로 모드일때 
              this.isNotSupport = false;
            } else {
              // 가로 모드일때
              this.isNotSupport = true;
            } 
          } else {
            if (window.matchMedia("(max-width: 767px)").matches) {
              if (isPortrait) {
                // 세로 모드일때 
                this.isNotSupport = false;
              } else {
                // 가로 모드일때
                this.isNotSupport = true;
              } 
            } else {
              this.isNotSupport = false;
            }
          }
        } else { 
            // PC 
            if (window.matchMedia("(max-width: 767px)").matches) {
              if (window.innerWidth <= window.innerHeight) {
                // 세로 모드일때 
                this.isNotSupport = false;
              } else {
                // 가로 모드일때
                this.isNotSupport = true;
              } 
            } else {
              this.isNotSupport = false;
            }
        }
      },
  }
 
}
</script>

 

- 각 해당되는 라이프사이클에 screenHandler 이벤트 등록

// app.vue

export default {
  name : 'App',
  data () {
    return {
      isNotSupport: false,
    }
  },
  components : { 
  	NotSupport,
  },
  beforeCreate() {
    window.addEventListener('load', this.srceenHandler);
  },
  created: function() {
    window.addEventListener('load', this.srceenHandler);
    window.addEventListener('resize', this.srceenHandler);
  },
  mounted() {
    window.addEventListener('resize', this.srceenHandler);
	},
  beforeDestroy() {
    // 컴포넌트가 제거되기 직전 이벤트리스너 해제
    window.removeEventListener('resize', this.srceenHandler);
  },
 }

 

반응형

+ Recent posts