윤개발
Vue에서 외부 Markdown 보여주기(class 설정 포함) 본문
이번에 진행하는 프로젝트의 요구사항이 다음과 같습니다.
- gitlab에 public으로 Markdown(이하 md) 업로드 - 로그인 없이 볼 수 있는 페이지여야함
- Vue에서 gitlab markdown을 로딩하여 보여줌 - gitlab 페이지 호출
이렇게 진행하면 다음과 같은 장단점이 있습니다.
장점
- html을 수정할 필요 없이 바라보는 gitlab md 파일만 수정하여도 운영환경에 반영(재배포가 필요없음)
- 프로젝트 초기 자주 수정될 수 있는 Guide, Faq등은 md로 간단하게 표현 가능
단점
- gitlab(또는 github) 에서 md를 가져오므로 정적파일을 로딩하는 것보다는 시간이 조금 더 걸림
- md를 이용하다 보니 style 적용은 힘듬
Vue에서 Markdown을 불러오며 단점을 극복하기 위해 Class 를 적용하여 스타일을 먹이는 방법을 알아보겠습니다.
1. 생성 및 가져오기
- gitlab 또는 github에 public으로 접근 가능한 Repository를 생성합니다
- test용 markdown을 작성하여 업로드합니다.
그리고 오른쪽 상단에 Raw를 클릭하면 아래와 같이 Md만 보여주게 됩니다. (gitlab의 경우 다운로드 후 url 확보)
이제 Vue에서 raw 주소로 get요청을 보내고 받은 text를 보여주면 됩니다.
2. 의존성 설치
md를 가져오고 보여주기 위해서 2개의 의존성을 설치해야합니다.
- axios - vue http 통신을 위한 라이브러리
- marked - markdown을 html 형식으로 변경해주는 라이브러리
npm install axios
npm install marked --save-dev
3. 컴포넌트 생성
새로운 vue 컴포넌트를 생성하고 axios를 이용하여 주소의 md를 불러옵니다.
<template>
<div class="test">
<textarea rows="10" v-model="mdText"></textarea>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "ShowMdPage",
data() {
return {
mdText: ""
};
},
mounted() {
this.getMarkdown();
},
methods: {
getMarkdown() {
const url =
"https://raw.githubusercontent.com/sungjaeyoon/show-md/main/README.md";
axios.get(url).then(response => {
this.mdText = response.data;
});
}
}
};
</script>
- data > mdText : markdown text가 저장
- mounted() : 컴포넌트가 마운트될때 해당 함수를 호출
- getMarkdown() : axios를 이용하여 URL을 호출하고 md_text에 넣어줌
아래와 같이 md를 잘 불러온 모습입니다.
이제 markdown을 html로 변경해야 합니다. 변경을 위해 marked 라이브러리를 이용합니다.
marked를 import 하고 아래와 같이 computed 함수를 작성합니다.
computed: {
changeMarkdown() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
headerIds: false,
tables: true,
breaks: true,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
return marked(this.mdText);
}
}
다음으로 template에 해당 함수를 바인딩하고 변경된 html 을 확인합니다.
또한 v-html 태그를 이용해서 실제 html로 렌더링 합니다.
<div>
<textarea rows="10" v-model="changeMarkdown"></textarea>
</div>
<div v-html="changeMarkdown"></div>
다음과 같이 md, html, 렌더링된 html이 모두 보여집니다.
4. 클래스 적용
이제 스타일을 입히기 위해 클래스를 적용해보겠습니다.
md 파일을 다음과 같이 수정하여 span 태그를 입히고 클래스를 적용합니다.
# show-md
## <span class="red-color">show-md</span>
### <span class="blue-color">show-md</span>
#### <span class="yellow-color">show-md</span>
그러면 보여지는 웹이 이상하게 변하게 됩니다.
< , " , > 3가지를 문자로 인식하여 다음과 같이 나오게 되므로 원래 문자열로 변경해주면 됩니다.
changeMarkdown 함수를 다음과 같이 변경합니다.
changeMarkdown() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
headerIds: false,
tables: true,
breaks: true,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
let changedText = marked(this.mdText);
changedText = changedText.replaceAll("<", "<");
changedText = changedText.replaceAll(">", ">");
changedText = changedText.replaceAll(""", '"');
return changedText;
}
그러면 다음과 같이 태그가 적용되고 실제 보여지는 html에서는 span태그가 표시되지 않는 모습입니다.
이제 css를 적용해보겠습니다.
아래와 같이 ::v-deep을 이용하여 css를 작성합니다.
::v-deep .red-color {
color: red;
}
::v-deep .blue-color {
color: blue;
}
::v-deep .yellow-color {
color: yellow;
}
그러면 css가 색상이 적용됩니다.
이렇게 md 파일을 가져오고 class를 적용하는 법을 알아보았습니다.
감사합니다.
전체 소스코드
<template>
<div class="test row">
<div>
<textarea rows="10" cols="20" v-model="mdText"></textarea>
</div>
<div>
<textarea rows="10" v-model="changeMarkdown"></textarea>
</div>
<div v-html="changeMarkdown"></div>
</div>
</template>
<script>
import axios from "axios";
import marked from "marked";
export default {
name: "ShowMdPage",
data() {
return {
mdText: ""
};
},
mounted() {
this.getMarkdown();
},
methods: {
getMarkdown() {
const url =
"https://raw.githubusercontent.com/sungjaeyoon/show-md/main/README.md";
axios.get(url).then(response => {
this.mdText = response.data;
});
}
},
computed: {
changeMarkdown() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
headerIds: false,
tables: true,
breaks: true,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
let changedText = marked(this.mdText);
changedText = changedText.replaceAll("<", "<");
changedText = changedText.replaceAll(">", ">");
changedText = changedText.replaceAll(""", '"');
return changedText;
}
}
};
</script>
<style scoped>
.test {
background-color: white;
color: black;
}
::v-deep .red-color {
color: red;
}
::v-deep .blue-color {
color: blue;
}
::v-deep .yellow-color {
color: yellow;
}
</style>
'프론트 > Vue.js' 카테고리의 다른 글
[Vue.js] v-for를 이용해 테이블 만들기 (0) | 2020.06.10 |
---|---|
[Vue.js] data의 boolean 값으로 클래스 적용하기 (0) | 2020.06.10 |
[Vue.js] 회원가입 폼 만들기(3) - 중복체크 (1) | 2020.06.10 |
[Vue.js] 회원가입 폼 만들기(2) - api 호출 (1) | 2020.06.07 |
[Vue.js] 회원가입 폼 만들기(1) - 기본 view 생성 (0) | 2020.06.06 |