從官網的介紹會發現有2種API,Composition API及 Options API
還有 SFC模式及 HTML模式
今天來學習這些不同的組合,以便在查看Vue的程式時,不會侷限在單一的語法
先從簡單的範例來看出這些語法的差別
參考Vue官網的 Handling User Input 的範例
https://vuejs.org/examples/#handling-input
首先是 熟悉的 Composition+SFC
App.vue
<script setup>
import { ref } from 'vue'
const message = ref('Hello World!')
function reverseMessage() {
message.value = message.value.split('').reverse().join('')
}
function notify() {
alert('navigation was prevented.')
}
</script>
<template>
<h1>{{ message }}</h1>
<button @click="reverseMessage">Reverse Message</button>
<button @click="message += '!'">Append "!"</button>
<a href="https://vuejs.org" @click.prevent="notify">
A link with e.preventDefault()
</a>
</template>
<style>
button, a {
display: block;
margin-bottom: 1em;
}
</style>
這個程式,先從<template>看起
有2個 <button>綁定了 @click 的事件,分別執行 reverseMessage 及 message += '!'reverseMessage是一個function
function reverseMessage() {
message.value = message.value.split('').reverse().join('')
}
執行的結果 是將 變數message的內容 message.value從反向排列的處理message += '!' 是 inline的程式碼,所以不用寫成 message.value 而是 message就可以了
message再綁定到 <h1>的內容 {{ message }}const message = ref('Hello World!') 使用ref('Hello World!')進行綁定,初值是 'Hello World!'
最後是 <a> 綁定了 @click.preven的事件 這裡使用 click.prevent 是指在click的時候,
不會開啓 超連結的網址,就是將原本預設的動作 prevent 停止掉,改以執行 notify的function
function notify() {
alert('navigation was prevented.')
}
則是開啟一個alert視窗
由以上的說明,我個人覺得 Composition+SFC的組合是最簡潔好理解的語法
只是這個需要透過vue+vite build之後才能在網站上執行
因此,若想要直接在HTML上不經過build說可以執行的話
就要使用 Composition+HTML 的組合
//-----------------------------------------------------
再來是 Composition+HTML
index.html
<script type="module">
import { createApp, ref } from 'vue'
createApp({
setup() {
const message = ref('Hello World!')
function reverseMessage() {
message.value = message.value.split('').reverse().join('')
}
function notify() {
alert('navigation was prevented.')
}
return {
message,
reverseMessage,
notify
}
}
}).mount('#app')
</script>
<div id="app">
<h1>{{ message }}</h1>
<button @click="reverseMessage">Reverse Message</button>
<button @click="message += '!'">Append "!"</button>
<a href="https://vuejs.org" @click.prevent="notify">
A link with e.preventDefault()
</a>
</div>
style.css
button, a {
display: block;
margin-bottom: 1em;
}
這個組合 是直接使用HTML+CSS
樣式的部份分開到 style.css
主網頁的部份 index.html
原本的<template>改成 <div id="app"><template> 的內容跟 <div id="app"> 是相同的,
不一樣的是在 script 的部份
原本的 <script setup> 改成 <script type="module">
在 <script type="module"> 中
使用 createApp({ setup(){} }).mount('#app') 的結構
其中 setup(){} 像是 <script setup> 中的setup一般
在 setup()中,
const message = ref('Hello World!')
function reverseMessage() {
message.value = message.value.split('').reverse().join('')
}
function notify() {
alert('navigation was prevented.')
}
return {
message,
reverseMessage,
notify
}
變數 message 宣告綁定的方式一樣,但要多寫 return 的部份
等於是有綁定到的變數,功能都要列出來
setup(){} 像是在設定 setup() 的功能
就像 在 <script setup> 內設定一樣
參考一下官網上的說明
import { createApp } from 'vue'
const app = createApp(/* ... */)
app.mount('#app')
所以 createApp({ setup(){} })的部份中的 createApp({}) 是 vue的預設功能
const app = createApp({}); 先產生一個vue物件,然後再透過app.mount('#app') 掛載到 <div id="app"> 上
其中 createApp({ setup(){} }) 可以理解為
在 createApp() 中輸入一個物件 {},物件中設定一個 setup(){} 的函式或功能
在 setup(){} 中,宣告vue元件或物件需要的各種變數及功能
其實在 Composition+SFC 組合中
只是將 <script type="module">,<div id="app">,<style> 整合到 App.vue上
最基本的index.html還是有的
附帶列出來對照一下
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
/src/main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
App.vue
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<input v-model="msg">
</template>
因此,變成可以專心在 App.vue 上設計就可以了
若是網頁式的
index.html
<style>
button, a {
display: block;
margin-bottom: 1em;
}
</style>
<script type="module">
import { createApp, ref } from 'vue'
createApp({
setup() {
const msg = ref('Hello World!')
return {
msg
}
}
}).mount('#app')
</script>
<div id="app">
<h1>{{ msg }}</h1>
<input v-model="msg">
</div>
基本上,還是使用 Composition API的模式
只是 createApp({ setup(){} }) 與 <script setup>的差別
//-----------------------------------------------------
再來是 Options+SFC
App.vue
<script>
export default {
data() {
return {
message: 'Hello World!'
}
},
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
},
notify() {
alert('navigation was prevented.')
}
}
}
</script>
<template>
<h1>{{ message }}</h1>
<button @click="reverseMessage">Reverse Message</button>
<button @click="message += '!'">Append "!"</button>
<a href="https://vuejs.org" @click.prevent="notify">
A link with e.preventDefault()
</a>
</template>
<style>
button, a {
display: block;
margin-bottom: 1em;
}
</style>
Options+SFC的組合 <template>及<style>不變
主要是<script> 的部份
export default { } 可以看作是 原本的 <script setup> 或是 setup(){}
data() {
return {
message: 'Hello World!'
}
},
算是設定了data()的函式,return回傳 綁定的 變數message,及初值 'Hello World!'
至於 data(){ return { } } 就可看作是與 <template> 綁定的介面
對應的是 變數宣告的部份const message = ref('Hello World!')
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
},
notify() {
alert('navigation was prevented.')
}
}
函式的宣告設定,則是要在 methods: { } 的屬性中設定
每個函式的宣告,要用 逗號分開
像是物件中的函式宣告
對應 Composition API的語法,在<script setup>中
變數及函式的宣告,都是獨立設定的
在 Options的語法上,主要是使用物件的語法
整個來看,可以理解為export default{} 代表產出一個 物件,像是 createApp({}) 產出App物件一般
這個 default 物件 就像 App.vue 會被 import App from './App.vue' 匯入一樣
這個 App 就是這個 default 物件
Composition API 與 Options API 之間的語法差異
可以整理出一個對照表,網路上可以找到很多資料
補充一下,在網路上有看到 Composition API 也有 export default 的語法
<script>
import { ref } from 'vue'
export default {
setup() {
const message = ref('Hello World!')
const reverseMessage = () => {
message.value = message.value.split('').reverse().join('')
}
const notify = () => {
alert('navigation was prevented.')
}
return {
message,
reverseMessage,
notify
}
}
}
</script>
這很像後來的 Composition API+HTML <script type="module"> 模式
<script type="module">
import { createApp, ref } from 'vue'
createApp({
setup() {
const message = ref('Hello World!')
function reverseMessage() {
message.value = message.value.split('').reverse().join('')
}
function notify() {
alert('navigation was prevented.')
}
return {
message,
reverseMessage,
notify
}
}
}).mount('#app')
</script>
將 export default { setup() { } } -> (<script>)
變成 createApp({ setup() { } } -> (<script type="module">)
最後再變成 <script setup> 模式
我相信這些都是Vue在改進或改版的過渡過程
到目前為止,
Composition API+SPC <script setup>會是最佳的狀態
我覺得因為版本的語法差異還不小,容易造成學習上的混淆
如果都以最新版的來對照學習,就可以快速的掌握vue的重點
//-----------------------------------------------------
最後是 Options+HTML
index.html
<script type="module">
import { createApp } from 'vue'
createApp({
data() {
return {
message: 'Hello World!'
}
},
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
},
notify() {
alert('navigation was prevented.')
}
}
}).mount('#app')
</script>
<div id="app">
<h1>{{ message }}</h1>
<button @click="reverseMessage">Reverse Message</button>
<button @click="message += '!'">Append "!"</button>
<a href="https://vuejs.org" @click.prevent="notify">
A link with e.preventDefault()
</a>
</div>
style.css
button, a {
display: block;
margin-bottom: 1em;
}
有了上述的分析 在看到這個組合時,就等於是直接看懂了
結論就是
Composition API+SFC <script setup>
Composition API+HTML <script type="module">
循著這樣的規律,有了整體的觀念後,剩下的就是各個細部的功能學習
以及 利用範例及專案練功了