2021-12-20 FE

ansunny1170·2021년 12월 19일
0

UVC BOOTCAMP.FE

목록 보기
3/3

Vue.js 기초.html

수업 시작! 수업 준비 한다.

프리티어 설치하고 DISABLE해놓자 BACKEND와 충돌난다고 한다.


vetur를 disable하면 전체 snippets까지 disable된다...
우선 snippets enable로 해놓자.

component

vue.js를 하는 이유?

http://localhost:8080/test-comp
headerfootercomponent로 구성해 본다.
헤더 머릿말?윗단?, 풋터 꼬릿말?밑단?

Header component 만들기

component 호출하기

app-header라는 이름은 변경이 가능하다.(kebab-case로 가능)
보통 컴포넌트는 절대경로로 많이 쓴다.(@사용한 경로)

router 세팅은 이렇게

만일 컴포넌트에서 호출하는 파일이 index.vue로 되어있으면 해당 파일명을 생략할 수 있다.
(../views/comp/index.vue === ../views/comp)

URL을 호출했을때 Header와 Footer가 한 페이지 내에 함께 존재하는지 확인 한다.

Not Found

존재하지 않는 url을 호출해도 페이지에는 아무런 에러 메세지가 없다.
(예: http://localhost:8080/abc123 --> 이런 페이지는 없지만 화면은 깨끗하게 잘 나온다.)

Not Found 페이지 만들기

다음과 같이 Not Found에서 사용할 페이지를 만든다. (위치는 크게 상관 없지만 보통 component들이 모여있는 곳에 작성 한다)

Router 설정

Not Found를 설정하기 위해서는 라우터의 설정이 중요하다.
다음과 같은 설정은 반드시 라우터 설정의 맨 하단에 위치해야 한다.

path: '*'의 뜻는 모든 path를 잡아낸다는 뜻이다. 따라서 맨 하단에 위치해야 위에서 놓치는(존재 하지 않는)URL의 모든 것을 잡아낼 수 있다.
(맨 상단에 있으면 어떤 일이 발생 할까??)

다음과 같이 존재하지 않는 url을 방문해 보자
http://localhost:8080/abc123

위에서부터 경로 찾다가 path '*' 경로 직전 경로까지 즉, /test-comp 경로까지 걸리지 않으면 나머지 모든 경로(오타로인한)는 NotFound로 가게 된다.
그래서 path '*'경로는 무조건 마지막에 위치해야 한다.

props

http://localhost:8080/test-family/props
부모 컴포넌트에서 자식 컴포넌트로 값을 전달 할 수 있다.
부모 ->props(properties)-> 자식
자식 ->emit-> 부모

자식1(Alice) 컴포넌트 만들기

props로 선언된 부분을 통해 부모 컴포넌트에서 프로퍼티를 전달할 수 있다.

<template>
  <div>
    <h3>Hi, I am Alice</h3>
    <p>I have to {{ job }}</p>
    <p>{{ user.name }} {{ user.who }}</p>
  </div>
</template>

<script>
export default {
  props: {
    job: {
      //job이라는 이름으로 줄 것이고
      type: String, //타입은 문자열이고
      required: false, //false는 꼭 데이터를 안념겨도 괜찮다는 거고
      default: 'Nothing'
    },
    user: {
      type: Object, //타입은 user라는 객체이고
      required: false, //역시 데이터를 꼭 안넘겨도 괜찮고
      default: null
    }
  }
}
</script>
<style lang="scss" scoped></style>

자식2(Bob) 컴포넌트 만들기

부모(Parent) 컴포넌트 만들기

와 같이 job프로퍼티를 통해 자식 컴포넌트에 값을 전달할 수 있다.
자세한 props사용에 대해서는 https://kr.vuejs.org/v2/guide/components-props.html 문서를 참조 할 것.

변수를 전달할때는 v-bind를 이용 해서 전달 한다.
(v-bind:user는 :user와 같다.)

Router 세팅

라우터 세팅 후 페이지를 확인해 볼 수 있다.
전달하는 job의 값에 따라 자식 컴포넌트의 job값이 달라짐을 확인 할 것.

아래와 같이 하면 에러가 날 것이다.

주석처리 해보고 다시 해보자. 된다. user에는 data가 없어서 아예 표시가 안된다.

job을 주었다. string으로 넘겼고, 다음에는 객체를 넘겨보자

객체를 넘겨보자. 객체를 넘겨주기 위해 bind변수를 사용해야한다. : or v-bind를 사용하자.

emit 자습필요

자식1(Alice) 컴포넌트 만들기

<template>
  <div>
    <h3>Hi, I am Alice</h3>
    <p>I want my parent to give me money.</p>
    <b-button variant="primary" @click="updateTodo">Money</b-button>
    <!-- 클릭 이벤트가 받았을 때 아래 methods의 업데이트 를 호출한다. 즉 emit의 updateTodoA인데
    이건 부모의 updateTodoA  -->
  </div>
</template>

<script>
export default {
  methods: {
    updateTodo: function () {
      this.$emit('updateTodoA', 'give to Alice money')
      //나를 부모로 같고있는것의 updateTodoA를 때린다?
    }
  }
}
</script>

<style lang="scss" scoped></style>

자식2(Bob) 컴포넌트 만들기

<template>
  <div>
    <h3>Greeting to you, I am Bob</h3>
    <p>I want my parent to give me food.</p>
    <b-button variant="success" @click="updateTodo">Food</b-button>
  </div>
</template>

<script>
export default {
  methods: {
    updateTodo: function () {
      this.$emit('updateTodoB', 'feed Bob food')
      // this.$는 vue.js의 내장함수다
    }
  }
}
</script>

<style lang="scss" scoped></style>

부모 컴포넌트 만들기

<template>
  <div>
    <h1>Emit Test</h1>
    <h2>I am Parent</h2>
    <p>I have to do something for my children.</p>
    <p style="font-weight: bold">I will {{ todo }}</p>
    <div style="border: 1px solid red">
      <alice @updateTodoA="updateTodoB($event)" />
      <!-- 왼쪽 업데이트가 오른쪽을 실행시킨다? -->
      <!-- 부모에서 엘리스한테 업데이트투두A 일므으로 호출하면 받을께 라고 준비 -->
    </div>
    <div style="border: 1px solid blue">
      <bob @updateTodoB="updateTodo($event)" />
    </div>
  </div>
</template>

<script>
import Alice from './Child1.vue'
import Bob from './Child2.vue'

export default {
  components: {
    Alice,
    Bob
  },
  data() {
    return {
      todo: 'do nothing'
    }
  },
  methods: {
    updateTodoB: function (newTodo) {
      // child1에서 give to alice money를 받게된다. 8번째 줄 이벤틀를 통해서!!
      // 명칭을 보면 updateTodoB가 같은것을 알 수 있다.
      this.todo = newTodo
    }
  }
}
</script>

<style lang="scss" scoped></style>

event bus

http://localhost:8080/test-family/event-bus

자식 컴포넌트 끼리 event를 발생 시킬 수 있다. (하지만 권장하지는 않는다. Store를 사용하면 된다.)

자식1(Alice) 컴포넌트 만들기

EventBus.$emit('eventName', 'message') 를 통해서 이벤트를 전파할 수 있다.
eventName: 전파하는 이벤트 이름
message: 전파하는 메세지(객체도 가능함)

자식2(Bob) 컴포넌트 만들기

EventBus.$on('eventName', function (message) { ... })를 통해서 메세지를 받을 수 있다.

함수 function (message) { ... }는 message => { ... }와 같다. (화살표 함수)

<template>
  <div>
    <h3>Greeting to you, I am Bob</h3>
    <p>Alice said to me: {{ aliceMessage }}</p>
    <p>
      Bob said: I don't know. <b-button size="sm" variant="success">reply to Alice</b-button>(여기를 구현해 보도록
      하자.)
    </p>
  </div>
</template>

<script>
import { EventBus } from './eventBus'
// import EventBus from './eventBus'
//export한것을 사용하기 위해 중괄호를 사용해야 한다.

export default {
  data() {
    return {
      aliceMessage: ''
    }
  },
  created() {
    EventBus.$on('aliceSaid', message => {
      // 13번 째 줄과 같은 것이고, $on이라는게 있다. 이벤트 버스를 on시키는 메서드이다.
      // 백엔드에서 사용한 이벤트 리스너 같은건가?
      // on뒤에 `,`를 기준으로 첫번째 파라미터는 string or string list로 넣고
      // ,뒤에는 콜백 함수로 넣는다.
      this.aliceMessage = message

      // 받아서 엘리스한테 보낸다.
    })
  }
}
</script>

부모 컴포넌트 만들기

부모 컴포넌트에서는 그냥 두 자식컴포넌트를 호출했을 뿐이다.

자식1(Alice)컴포넌트의 [send to Bob]버튼을 통해 메세지 전달 테스트를 해보자.

자식2(Bob)컴포넌트에서 자식1(Alice)컴포넌트로 메세지를 보내 보자. ([reply to Alice]버튼 기능 구현)

  • 중괄호 유무 차이가 있을까?

Store (Vuex)

vue.js를 사용하는 이유

User Store 파일 생성(빈 파일 생성)

state, mutations 직접 호출 금지
getters, actions
아래 사진과 같이 입력

Store의 index파일에서 User Store파일 import 하기

index.js(store)내용을 그대로 사용해도 된다.

User Store 파일 코딩

User List 파일 생성



User Info 파일 생성

아래와 같이 세팅된 Store의 정보는 다른 컴포넌트에서도 실시간으로 받아볼 수 있다.(this.$store.getters.User를 통해 동일한 User정보를 받을 수 있음)

Axios

UserList: http://localhost:8080/test-user/list
UserInfo: http://localhost:8080/test-user/info

백엔드의 RestAPI를 호출하기 위해서 axios를 설치 한다.
Axios란? https://github.com/axios/axios

Axios 설치

npm install axios vue-axios --save

axios 함수 파일 생성

  • 아래 체크한 파일들을 db에서 받아 올 것이다.

https://jsonplaceholder.typicode.com/users db에서
https://jsonplaceholder.typicode.com/users/1이렇게 치면 어떻게 될까
1이 들어간 자리는 <:id>즉 아이디 값이다.
id:1인 userList가 출력될 것이다. 이것은 RESTfull하게 이미 정해진 약속이다.

Store 파일 수정

GET https://jsonplaceholder.typicode.com/users
src/store/models/user.js에서 user db파일을 받아온다(api.get)

  • 1 번째줄에서 import api from '../apiUtil'로 임포트한다.

  • response && response.data는 response에 데이터가 있는지 확인을 한것이다. 타입스크립트 방식??

  • 데이터가 있는지 확인 했다는 것은 .catch(err)처럼 작동하게 한것이다. 그래서 .catch(err)대신 사용하면 된다.

  • 보면 알겠지만 41줄의 console.log....는 콘솔에 db에서 받아온 userlist를 확인차 출력하는 코드이다.

  • 37.38줄은 주석처리한다.
    이내용들은 db에서 REST FULL하게 받기전에 어떻게 작동하는지 보기 위함이었다.

User List 테스트
http://localhost:8080/test-user/list 에서 [Search]를 클릭하면 실제 네트워크를 통해 정보를 받아 온다.

User Info 테스트
http://localhost:8080/test-user/info 에서 User.id값에 따라 해당 사용자가 조회 된다. (범위는 1~10)

(해당 사용자 범위를 벗어나는 id를 입력해 보자. --> 서버에서 404에러가 리턴되는 것을 확인해 볼 것)

SocketIo

SocketIo 서버 생성(Node.js)

개발PC에서 C:\Workspace\vuetest\socketserver 폴더를 생성한다.
해당 폴더에 다음과 같이 nodejs를 이용해서 SocketIo서버를 만든다.(vue 파일이 아니다.)

다음과 같이 해당 프로젝트 폴더로 이동 한다.
cd C:\Workspace\vuetest\socketserver

  • cd 이동하고
  • 인스톨 하고
  • 열고
  • node index.js 입력하고 소켓 띄웠음 3010포트에 접속한 사람들 끼리 채팅 가능함

npm init

다음과 같이 npm 초기화를 한다.
npm init -y
난 안했는뎅? 안해도 되나 ㅎ
생성된 package.json파일을 확인해 본다. 확인만 해본다.

npm install

소켓 서버로 사용하기 위한 최소한의 라이브러리만 설치 한다.
npm install http socket.io
나는 강사님 따라, npm install 했다.

index.js 생성

다음과 같이 웹소켓 서버를 생성 한다.

const { createServer } = require("http");
const { Server } = require("socket.io");
const httpServer = createServer();

const io = require("socket.io")(httpServer, {
  // CORS 처리
  cors: {
    origin: "http://localhost:8080",
    methods: ["GET", "POST"]
  }
});

// socket.io 연결
io.on("connection", (socket) => {
  console.log('connected socket.io', socket.id);

  socket.on('chat', msg => {
    console.log('chat', msg);
    io.emit('chat', msg);
  });
});

// http서버 실행
const port = 3010;
httpServer.listen(port);
console.log(`socket.io listening: ${port}`);

nodejs를 통해 http서버를 동작 시킨다.

node index.js
socket.io listening: 3010
connected socket.io hQHYkUvolpvRH0MOAAAB

SocketIo 클라이언트 생성(Vue.js)

라우터 설정하자 http://localhost:8080/test-socket
vuetest 프로젝트에서 소켓 클라이언트를 만들어 보자.

socketIo-client 설치

npm install socket.io-client --save
잘봐야한다 .vuestudy에서 설치했다.

그리고 다시 serve run.

main.js에 socket 등록

다음과 같이 main.js파일에 socket.io를 등록하도록 한다.
가져온 io에 127.9.9.1:3010을 넣었다.

socket 3010 떠있는 상태이다.

Vue.prototype.\$socket = socket를 통해 vue인스턴스 변수로 등록하여 컴포넌트에서 this.$socket으로 호출할 수 있도록 했다.

socketIo-client 파일 생성

주석을 읽자

<template>
  <div>
    <h1>Socket Test</h1>
    <b-container fluid>
      <b-row>
        <b-col style="text-align: right"></b-col>
        <b-col style="text-align: center">
          <b-form-input v-model="message" placeholder="message" />
          <h5>Chat message</h5>
          <b-form-textarea id="textarea" v-model="messageHistory" rows="7" max-rows="6"></b-form-textarea>
        </b-col>
        <b-col style="text-align: left">
          <b-button variant="primary" @click="sendMessage">Send</b-button>
        </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
      //날릴 메세지
      messageHistory: ''
      //메세지 히스토리
    }
  },
  created() {
    this.$socket.on('chat', data => {
      //socket 이벤트 리스너이고 chat 명령? 이 떨어지면..
      //chat이라는 이름으로 메세지 받으려고 대기 중임
      //채팅방에 따라 이름 다르게 할 수 있지만 여기서는 한가지 톡만 가능하다?
      //data에서 메세지가 들어온다.
      this.messageHistory += data + '\n'
      // 뒤에 \n과 함께 메세지가 올텐데 \n은 enter값이다.
      //textarea에 뿌려질 data들이다.
    })
  },
  methods: {
    sendMessage() {
      this.$socket.emit('chat', this.message)
      //메세지를 어딘가에 셋팅할 건데, 저 위에 return 안에 message에 chat이라는
      //이름으로 날릴것이다.
      this.message = ''
      //
    }
  }
}
</script>

<style lang="scss" scoped></style>

웹브라우저 두개를 띄워서 각각의 페이지에서 메세지를 입력해 보자. (종류가 다른 브라우저에서도 가능하다.)

i18n(다국어 처리)

i18n을 통해 다국어를 처리할 수 있다.

다국어 처리에 대해서는 참고만 하도록 한다.
https://kazupon.github.io/vue-i18n/started.html#html

dir을 dir.txt에 넣어라


profile
4년차 설비 개발 연구원에서 IT 웹 서비스 개발자로 경력 이전을 준비 중입니다. Node.js/Vue.js를 공부하고 있으며, 백엔드 기반 풀스택 개발자를 목표로 하고 있습니다.

0개의 댓글