從官網的介紹會發現有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">
循著這樣的規律,有了整體的觀念後,剩下的就是各個細部的功能學習
以及 利用範例及專案練功了