# Vue.js 學習旅程Mile 6 – 資料單向綁定篇:v-text & v-html
###### tags: `w3HexSchool` `Vue` `Javascript`
## 資料單向綁定
藉由改變 data 來改變畫面 view
### v-text
更新文字內容,如同 js 中的 `textContent`。
`<div v-text="">` 可用 `{{ mustache }}` 簡寫。
:::info
`v-text` 與 `{{ mustache }}` 的不同之處在於,`v-text` 會更新整塊標籤的內容(包含本身),但 `{{ mustache }}` 只會更新標籤內的局部內容。
:::
#### 範例
```htmlmixed=
<div id="app">
<p v-text="message">這是原本的文字,</p>
<p>這是原本的文字,{{message}}</p>
</div>
```
```javascript=
let app = new Vue({
el: "#app",
data: {
message: "這是後來的文字"
}
});
```

### v-html
可渲染出 HTML,如同 js 中的 `innerHtml`
#### 範例
```htmlmixed=
<div id="app">
{{ message }}
<div v-text="message"></div>
<div v-html="message2"></div>
</div>
```
```javascript=
var app = new Vue({
el: '#app',
data: {
message: '哈囉',
message2: '<span style="background-color: yellow;">hi</span>'
}
})
```

#### XSS 攻擊
:::warning
任意在網站上動態渲染 HTML 是非常危險的,因為容易導致 XSS 攻擊。
:::
XSS(Cross-site scripting,跨網站指令碼攻擊):藉由網頁開發時留下的漏洞,利用巧妙的方法注入惡意指令代碼到網頁,使用戶載入並執行攻擊者惡意製造的網頁程式。
關於XSS攻擊,可參考[這篇文章](https://forum.gamer.com.tw/Co.php?bsn=60292&sn=11267),內有詳細的解說。
因此,盡量避免在表單或是留言區使用 `v-html`,因為很有可能會被有心人力從外部寫入惡意程式碼。
#### v-html 套用 CSS 樣式
:::warning
單一元件(.vue)中 `v-html` 的內容不會套用有寫 `scoped` 的 CSS style,因為 `v-html` 的內容並沒有被 Vue 模板編譯器編譯過。
:::
在不設為全域變數下,若想要讓 `v-html` 能套用 CSS scoped 樣式,有三種方式:
1. 使用 [CSS modules](https://vue-loader.vuejs.org/guide/css-modules.html#css-modules)
2. 在全域變數中,透過特殊的命名(例如:[BEM](http://getbem.com/))
3. 使用 [Deep Selectors](https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors)
範例(使用 Deep Selectors):
```htmlmixed=
<template>
<div class="a" v-html="content"></div>
</template>
<script>
export default {
data() {
return {
content: 'this is a <a class="b">Test</a>',
}
},
}
</script>
<style scoped>
.a >>> .b {
color: red;
}
</style>
```
### 參考與延伸閱讀資料
* [Vue.js API](https://cn.vuejs.org/v2/api/)
* [[Vue學習筆記](三)Vue指令(上) — v-text, v-html, v-if, v-show, v-for](https://medium.com/andy%E7%9A%84%E8%B6%A3%E5%91%B3%E7%A8%8B%E5%BC%8F%E7%B7%B4%E5%8A%9F%E5%9D%8A/vue%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-%E4%B8%89-vue%E6%8C%87%E4%BB%A4-%E4%B8%8A-v-text-v-html-v-if-v-show-v-for-4eb6cd994359)
* [跨網站指令碼](https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%B6%B2%E7%AB%99%E6%8C%87%E4%BB%A4%E7%A2%BC)
* [【網頁安全】給網頁開發新人的 XSS 攻擊 介紹與防範](https://forum.gamer.com.tw/Co.php?bsn=60292&sn=11267)
* [BEM](https://cythilya.github.io/2018/05/22/bem/)
* [BEM 規範思維 – 讓 CSS 更利於開發與維護 (一)](https://www.astralweb.com.tw/apply-bem-to-css-coding-and-maintenance-2/)
* [Scoped styles with v-html](https://medium.com/@brockreece/scoped-styles-with-v-html-c0f6d2dc5d8e)
* [vue 中控制v-html 中的樣式,但不影響全局的小技巧](https://juejin.im/post/5a9ab6716fb9a028d7001188)
* [CSS Modules 用法教程](http://www.ruanyifeng.com/blog/2016/06/css_modules.html)