前端發展百花放,一技未熟百技出。未知何處去下手,關注小編勝百書。 我是前端人,專注分享前端內容!
本篇文章主要是,使用 vite 建立一個vue3 專案,實踐 vie-router4 vuex4 結合 componsition API 的使用。目的是讓未接觸過 vue3 的同學快速上手。
一、vue3.0 建立專案
vue3 建立專案的時候有兩種方式,第一種就是官方推薦的 vite 。另外一種就是使用 webpack 建立。
1.1、vite 建立專案
vite 需要 Node.js >= 12.x版本。所以使用 vite 搭建專案之前,請先檢查 node 版本!
執行 :$ npm init vite@latest 命令,然後按照提示資訊選擇建立專案的型別。具體的步驟可以參考《什麼,你還使用 webpack?別人都在用 vite 搭建專案了》文章。
也可以通過附加命令列選項,指定使用的模板。如:
npm init vite@latest my-vue-app --template vue
使用最新 vite 建立 vue 模板專案。
專案目錄如圖所示:
1.2、webpack 建立專案
使用 vue/cli 腳手架建立 vue3 專案時,需要升級 vue cli v4.5版本!使用 vue -V 檢查版本,如果版本過低時,請全域性重新安裝。
npm install -g @vue/cli
使用命令,開始建立專案:
vue create project-name
選擇需要建立 vue3 專案,根據提示建立專案就可以了。
1.3、vite 與 webpack 相比優缺點
Vite |
Webpack |
vite 啟動不需要打包,開發伺服器比 Webpack 快 10-100 倍 |
webpack先打包,然後啟動服務,比 vite 慢很多 |
熱更新時,按需載入 |
熱更新時,全部載入 |
僅支援 vue3 |
支援 vue 各個版本 |
與 CommonJS 模組不完全相容 |
支援 CommonJs |
在本篇文章內,我們選擇 第一種方式 vite 建立一個 learn-vue3 的專案。
二、vue-router4
專案建立完成之後,我們要做的第一件事就是配置路由了,新增路由的時候,需要在 main.js 內引入 router。
main.js 程式碼:
import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app')
此時發現與 vue2 的建立例項完全不一樣,vue3 使用的是 createApp ,使用前需要先引入。
2.1、引入路由
在 vue3 中使用 vue-router 時,需要安裝 vue-router 4 。
npm install vue-router@4
安裝之後可以在 package.json 檔案中檢視 vue-router 的版本。
{ "dependencies": { "vue": "^3.2.25", "vue-router": "^4.0.12" } }
vue-router 4 的大多數的 API 是保持不變的,但是在 vue3 中以外掛形式存在,所以在建立的時候有一定的改變。
新建 router 資料夾,新建 index.js 檔案
// 1、按需引入方法 import { createRouter, createWebHashHistory } from "vue-router" // 2、定義一些路由 const routes = [ // 每個路由都需要對映到一個元件 ] //3、建立路由例項 const router = createRouter({ routes, history:createWebHashHistory("./") }) export default router
然後到 main.js 中,將路由掛載到例項上。
import { createApp } from 'vue' import App from './App.vue' import router from "./router/index" createApp(App) //整個應用支援路由 .use(router) .mount('#app')
2.2、新建元件配置路由
在 src 目錄下,新建 pages 資料夾,新建 index.vue 檔案:
<template>
首頁入口
</template>
在 router.js 檔案內,定義路由
const routes = [ { path:"/", component:()=>import("../pages/index.vue") } ]
然後在 App.vue 檔案內新增 router-view 容器。
<template> <img alt="Vue logo" src="./assets/logo.png" /> <router-view></router-view> </template>
此時執行專案的時候就能看到新建的 index.vue 的內容了。
三、vue-router4 結合 composition API 使用
3.1、composition API
composition API 中文叫做組合式API,它是 Vue3 特有的,同時 vue3 也能夠向下相容 Options API。
setup 函式就是 composition API 的入口,是處於生命週期鉤子函式 beforeCreate 和 created 兩個函式之間,所以 setup 中的屬性和方法在外部使用時,需要先 return 暴漏出去。
修改 index.vue 元件,採用 composition API 。
<template> <div> <input type="text" v-model="msg" /> </div> </template> <script> export default { setup() { const msg = '前端人,前端魂' return { msg, } } } </script>
3.2、響應式資料
上述的例項中中,如果我們在 template 內,列印 msg 的時候,就會發現響應式失效。
<template>
<div>
<input type="text" v-model="msg" />
{{ msg }}
</div>
</template>
是因為在 setup 內地自定義屬性不具備響應式能力。vue3 的響應式原理是 通過底層代理 proxy 將資料包裝一下,使得具有響應式。vue3 的響應式原理詳情可檢視《vue3 學習筆記 (五)——vue3 的 setup 如何實現響應式功能?》
此處 msg 是一個基礎資料型別,可以通過 ref 包裝下資料,ref 使用之前需要從 vue 中先引入。修改 script 中的程式碼
<script> import { ref } from 'vue' export default { setup() { const msg = ref('前端人,前端魂') return { msg, } } } </script>
此時在 input 或在 setup 內改變 msg 的值,如:
<script> import { ref } from 'vue' export default { setup() { const msg = ref('前端人,前端魂') setTimeout(()=>{ msg.value = "我是前端人" },3000) return { msg, } } } </script>
此時無論如何修改 msg 都會保證實時響應。
與 ref 類似的還有 reactive 。ref 是讓基礎資料型別具有響應式,reactive 是讓引用資料型別具有響應式。
3.3、組合式內如何使用路由?
一個專案中,導航選項卡是很常見的,在 App.vue 檔案內,加入兩個導航:
<template> <router-view></router-view> <router-link to="/">首頁</router-link> <router-link to="/my">我的</router-link> </template>
如果把上述路由跳轉方式修改成 push 時,如何修改呢?
composition API 內使用路由時,需要先匯入 userRouter 方法,呼叫該方法,生成 router。
如:
import { useRouter } from 'vue-router'
const router = useRouter()
router 是路由【導航物件】。
想要獲取當前路由時,使用 useRoute 方法,如:
import { useRoute } from 'vue-router'
const route = useRoute()
route 是當前啟用的路由狀態資訊物件,包含所有路由中的引數,params, query 都屬於它。
修改上邊路由跳轉方式使用 push ,程式碼如下:
<script > import { useRouter } from 'vue-router' export default{ setup(){ const router = useRouter() function go() { router.push({ path: '/my' }) } return{ go } } } </script> <template> <router-view></router-view> <router-link to="/">首頁</router-link> <button @click="go">我的</button> </template>
路由傳參以及引數獲取,只需要把之前的 this.$router 換成 router 就可以啦。
四、vuex 4
vuex 是專為 vue.js 應用程式開發的狀態管理模式+庫。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
在 vue3 中使用的是 vuex4 。vuex4 提供了和 vuex3 相同的 API 。
安裝:
npm install vuex@next
package.json 檢查版本
"dependencies": { "vue": "^3.2.25", "vue-router": "^4.0.12", "vuex": "^4.0.2" }
4.1、引入 vuex 狀態管理
vuex4 建立 store 例項時,使用 createStore 函式建立,createStore 在使用之前需要先引入。
在 src 目錄下,新建 store 資料夾下建 index.js :
import { createStore } from "vuex" // 建立新的 store 例項 const store = createStore({ state: { name:'前端人' }, getters: { }, mutations: { }, actions: { }, modules: { } }) export default store
在 main.js 中將 store 例項作為外掛安裝。
import { createApp } from 'vue' import App from './App.vue' import router from "./router/index" import store from "./store/index" createApp(App).use(router).use(store).mount('#app')
4.2、獲取狀態資訊
在 App.js 檔案內,使用狀態資訊,這與 vuex3 使用方式相同。
<template> 獲取 state 內的狀態資訊 {{ this.$store.state }} 獲取 getters 內的屬性 {{ this.$store.getters.getName }} </template>
五、vuex 結合 composition API
在 組合式 API 中使用 store 時,需要使用 useStore 把 store 引入元件,然後才能操作。
<script> import { useStore } from 'vuex' export default { setup() { const store = useStore() console.log('store', store.state.name) }, } </script>
useStore 使用之前,需要先引入,然後呼叫。
5.1、操作 vuex 狀態資訊
vuex 中同步運算元據是由 commit 呼叫 mutations 內的方法,非同步操作是 dispatch 呼叫 actions 內的方法。
示例1:mutations 內方法修改 name 的值。
// 在 index.js 內 mutations: { changeName(state,data) { //data 是傳入要修改的值 state.name = data } } //App.vue 內 <script> import { useStore } from 'vuex' export default { setup() { const store = useStore() console.log('store', store.state.name) store.commit('changeName', '我是前端人') console.log('store', store.state.name) } } </script>
示例1:actions 內方法修改 name 的值。
actions 內的方法是沒有辦法直接操作 state 的狀態資訊,只有 mutations 內的方法才可以,所以需要呼叫 mutations 的方法,實現修改 。
index.js 程式碼
import { createStore } from "vuex" const store = createStore({ state: { name:'前端人' }, getters: { getName(state) { return state.name } }, mutations: { changeName(state,data) { state.name = data } }, actions: { changeVal(state) { // 借用setTimeout 模擬非同步操作 setTimeout(() => { state.commit('changeName','我是前端人') },2000) } }, modules:{} }) export default store
App.vue 程式碼
<script> import { useStore } from 'vuex' export default { setup() { const store = useStore() store.dispatch('changeVal') } } </script> <template> {{ this.$store.state.name }} {{ this.$store.getters.getName }} </template>