簡介
感覺vue3的新特性很舒服,這樣才是寫軟件的感覺嘛。打算用Vue實(shí)現(xiàn)自己的一些想法。
Vue3還有幾個(gè)必備庫,比如Vue-Router(負(fù)責(zé)路由導(dǎo)航)、Vuex(狀態(tài)管理、組件間通信),還有第三方UI庫,比如element Plus、Antdv、Vant 等。
這里會介紹他們的CND的安裝方法,以及簡單的使用方式。
Vue3 的使用方式
使用方式有兩大類:
- CDN package
- 工程化方式開發(fā)
cnd方式就是在script里面引用js文件(類似于JQuery),然后就可以開魯了,簡單粗暴,適合于新手學(xué)習(xí)基礎(chǔ)知識,或者做點(diǎn)小項(xiàng)目。
但是如果想要開發(fā)中大型項(xiàng)目的話,就需要使用工程化的開發(fā)方式了。
本來想在這里把這兩種方式都寫完,但是沒想到cnd的方式越寫越多,所以還是分成兩份來寫把。工程化方式在下一篇。
CND package 的方式
由于使用范圍比較小,所以網(wǎng)上的介紹資料比較少,往往都是一筆帶過,這里想做一個(gè)整體介紹,也許是因?yàn)槲冶容^喜歡這種簡單粗暴的方式吧。
不啰嗦,簡單粗暴,直接上代碼:
js腳本的引用方式
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@next"></script>
<script src="https://unpkg.com/vuex@next"></script>
// element-plus 引入樣式
<link rel="stylesheet" >
// element-plus 引入組件庫
<script src="https://unpkg.com/element-plus/lib/index.full.js"></script>
// Ant Design Vue 引入樣式
<link rel="stylesheet" href="js/antdv/antd.css">
// Ant Design Vue 引入組件庫
<script src="js/antdv/antd.js"></script>
// Vant 引入樣式文件
<link rel="stylesheet" />
// Vant 引入組件庫
<script src="https://cdn.jsdelivr.net/npm/vant@next/lib/vant.min.js"></script>
https://unpkg.com/vue
引用默認(rèn)版本的vue.js文件,目前是 v2.6.12。https://unpkg.com/vue@3
@后面可以指定版本號。https://unpkg.com/vue@next
引用最新版本。Ant Design Vue
似乎沒有提供cnd的方式,我們需要先使用npm安裝,然后到 (node_modules/)ant-design-vue/dist 里面找到需要的文件,或者到 UNPKG 進(jìn)行下載。https://unpkg.com/element-plus@1.0.2-beta.30/lib/index.full.js
目前是 v1.0.2-beta.30,沒有發(fā)現(xiàn)next版本。
js腳本一般都可以采用這種方式引入,UI庫需要引入對應(yīng)的css文件。
注意:https://unpkg.com/antd 這個(gè)是 react 的UI庫,并不是Vue的,不要混淆。
- 優(yōu)化加載速度
反復(fù)測試了幾次,發(fā)現(xiàn)寫@next雖然簡單,但是加載的時(shí)候會發(fā)生跳轉(zhuǎn),有的時(shí)候會比較卡,所以可以改成跳轉(zhuǎn)后的地址,比如這樣:
<script src="https://unpkg.com/vue@3.0.5/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue-router@4.0.3/dist/vue-router.global.js"></script>
<script src="https://unpkg.com/vuex@4.0.0-rc.2/dist/vuex.global.js"></script>
<!-- element-plus 引入樣式 -->
<link rel="stylesheet" >
<!-- element-plus 引入組件庫 -->
<script src="https://unpkg.com/element-plus@1.0.2-beta.30/lib/index.full.js"></script>
<!-- Ant Design Vue 引入樣式 -->
<link rel="stylesheet" href="js/antdv/antd.css">
<!-- Ant Design Vue 引入組件庫 -->
<script src="js/antdv/antd.min.js"></script>
<!-- Vant 引入樣式文件 -->
<link rel="stylesheet" />
<!-- Vant 引入組件庫 -->
<script src="https://cdn.jsdelivr.net/npm/vant@next/lib/vant.min.js"></script>
vue3的簡單使用
引入之后要如何使用呢?vue官網(wǎng)上有很詳細(xì)的介紹,這里不多介紹了,其他的關(guān)于cnd的介紹就比較簡略了,所以這里做一下創(chuàng)建和掛載的介紹。
數(shù)據(jù)綁定和UI庫的使用
數(shù)據(jù)綁定和UI庫的演示<br>
{{value}}<br>
<!--原生dom-->
<input type="button" value="測試" @click="click"/><br>
<!--element-plus 的 按鈕-->
<el-button @click="click">elemet的按鈕</el-button><br>
<!--Ant Design Vue 的 按鈕-->
<a-button type="primary" @click="click">antdv的按鈕</a-button><br>
<!--Vant 的 按鈕-->
<van-button type="success" @click="click">vant的按鈕</van-button><br>
用插值實(shí)現(xiàn)數(shù)據(jù)綁定,使用UI庫提供的組件。
// vue3的 Composition API 的奧義,
// 不要傻傻的把代碼都寫到setup里面了,分出來寫才是王道。
// 便于復(fù)用,可以寫到單獨(dú)的js文件里面
const testManage = () => {
const value = Vue.ref('你好,世界') // 相當(dāng)于data
const click = () => { // 相當(dāng)于 methods 里面的事件
value.value = '好的,收到!' + new Date()
}
return {
value,
click
}
}
// 定義 vue3 的對象
const vue3Composition = {
setup() { // 傳說中的setup
// 使用上面的定義的“類”,分散setup內(nèi)部的代碼
const { value, click } = testManage()
return { // 返回給模板,否則模板訪問不到。這里返回的是對象。
value,
click
}
}
}
// 創(chuàng)建vue3的實(shí)例
const vm = Vue.createApp(vue3Composition)
.use(myVuex) // 掛載vuex,myVuex在下面介紹
.use(router) // 掛載路由,router 在下面介紹
.use(antd) // 加載 Ant Design Vue
.use(ElementPlus) // 加載ElementPlus
.use(vant) // 加載vant
.mount('#app') // 掛載Vue的app實(shí)例
- 代碼都要寫在setup里面嗎?
當(dāng)然不是。這里的例子雖然非常簡單,但是我怕帶來無解,所以特意在setup外面做了一個(gè)“管理類”,然后在setup里面引用這個(gè)管理類,以此表達(dá)代碼可以寫在哪里的問題。
一般UI庫用一個(gè)就行,不用都安裝。這里只是想看看都安裝上會不會沖突,好吧,是我懶不想弄多個(gè)文件。
Vuex狀態(tài)管理的簡單使用
vue3里面的vuex的使用方式,cnd里面需要?jiǎng)?chuàng)建實(shí)例,然后才能掛載,不能直接掛載Vuex。setup里面的使用方式是一樣的。好吧有一點(diǎn)點(diǎn)區(qū)別。
模板里的使用方式
vuex狀態(tài)演示<br>
<!--模板里面可以直接使用$store,當(dāng)然不建議這么用-->
$store - count:{{$store.state.count}}<br>
$store - myObject:{{$store.state.myObject}}<br>
$store - myObject.time:{{$store.state.myObject.time}}<br>
<!--setup里面返回的對象-->
setup - count:{{count}}<br>
setup - obj :{{obj}}<br>
setup - objTime :{{objTime}}<br>
<a-button type="primary" @click="setCount">vuex的 計(jì)數(shù)</a-button><br>
<a-button type="primary" @click="setTime">vuex的 設(shè)置屬性</a-button><br>
- $store
在模板里面可以直接使用,在setup里面不能直接使用。
不過根據(jù)規(guī)則,不建議直接使用$store.state。
定義一個(gè)vuex實(shí)例
// vuex 的簡單使用 =======================
const myStore = {
state: { // 可以理解為大號 data(不準(zhǔn)確)
count: 0,
myObject: {
time: '現(xiàn)在的時(shí)間'
}
},
getters: { // 設(shè)置屬性的值
getCount: (state) => {
return state.count
},
getMyObject: (state) => {
return Vue.readonly(state.myObject)
},
getTime: (state) => {
return state.myObject.time
}
},
mutations: { // 獲取屬性的值
setCount(state) {
state.count++
},
setTime(state) {
state.myObject.time = '現(xiàn)在時(shí)間:' + new Date()
}
} // 其他方法暫略
}
// 建立vuex的實(shí)例,vue3需要掛載實(shí)例,掛載方式在上面
const myVuex = Vuex.createStore(myStore)
state
在vue3里面,整個(gè)state都是Proxy的,也就是說,可以認(rèn)為state是一個(gè)reactive。
這里定義一個(gè)簡單類型和引用類型,state里的簡單類型不會變,但是引用類型也會自動變成Proxy,也就不用我們自己用Reactive了。getMyObject 和 readonly
因?yàn)椴唤ㄗh在組件里面直接對state設(shè)置值,而是要用 mutations 設(shè)置值,使用getters獲取值。
如果state是簡單類型的話沒有問題,但是如果state里面有對象類型的話,那么getters里面直接return,就有可能發(fā)生誤賦值的問題。
為了避免這個(gè)漏洞,可以使用readonly來返回,這樣組件里面就無法直接給state賦值了。
setup里的使用方式
setup() { // 傳說中的setup
// 獲得store對象
const store = Vuex.useStore()
console.log(store) // 打印出來看看
const setCount = () =>{ // 使用 mutations 的 setCount 實(shí)現(xiàn)計(jì)數(shù)
store.commit('setCount')
}
const setTime = () =>{ // 使用 mutations 的 setTime 實(shí)現(xiàn)修改屬性
store.commit('setTime')
// 測試直接修改
// 加上 readonly 就不可修改了,
// 但是代碼并不會報(bào)錯(cuò)
setTimeout(() => {
obj.time = '222'
console.log('setTimeout-obj',obj)
},500)
}
// 獲取state
// const count = store.state.count 強(qiáng)烈建議不要直接訪問
const count = store.getters.getCount
const obj = store.getters.getMyObject
const objTime = store.getters.getTime
console.log('obj', obj)
console.log('objTime', objTime)
return { // 返回給模板,否則模板訪問不到。
value,
click,
setCount,
setTime,
count,
obj,
objTime
}
路由的簡單使用
在cnd模式里面,也是可以用路由的,只是一般路由要加載對應(yīng)的組件,而在cnd模式下寫組件比較麻煩,管理也不方便,雖然可以想各種辦法來實(shí)現(xiàn)管理和編寫的問題,但是與其這樣還不如直接用工程化的方式來開發(fā)項(xiàng)目。
這里只是簡單介紹一下cnd模式里面的使用方式。
模板里的使用方式,簡單版
路由的演示<br>
<div>
<p>
路由的簡單演示,其實(shí)CND方式不太適合用路由,因?yàn)榻M件寫起來比較麻煩。<br>
<!-- 使用 router-link 組件來導(dǎo)航. -->
<!-- 通過傳入 `to` 屬性指定鏈接. -->
<!-- <router-link> 默認(rèn)會被渲染成一個(gè) `<a>` 標(biāo)簽 -->
<router-link to="/home">首頁</router-link>
<router-link to="/product">產(chǎn)品</router-link>
</p>
<!-- 路由匹配到的組件將在這里渲染 -->
路由入口<br>
<router-view></router-view>
</div>
router-link
類似于 a 標(biāo)簽。但是不要直接用 a 標(biāo)簽,因?yàn)闀?dǎo)致頁面重新加載。router-view
路由入口,或者說是容器,加載路由指定的組件的位置。
定義一個(gè)路由,簡單版
// 路由的簡單使用 ========================================
// 1、定義組件,便于路由導(dǎo)航的演示,里面可以加vuex的state
const home = {
template: '<div>假裝這是首頁{{$store.state.myObject.time}}</div>',
setup() {
// alert('我是首頁')
}
}
const product = {
template: '<div>假裝這是商品頁面{{$store.state.count}}</div>',
setup() {
// alert('我是商品介紹')
}
}
// 2、定義路由,路由規(guī)則
const routes = [
{ path: '/home', component: home },
{ path: '/product', component: product }
]
// 獲取路由方式
const history = VueRouter.createWebHistory()
// 3. 創(chuàng)建 router 實(shí)例,vue3需要掛載實(shí)例,掛載方式在上面
const router = VueRouter.createRouter({
history,
routes
})
const home 、const product
需要先定義兩個(gè)簡單的組件,便于演示。const routes
定義一個(gè)簡單的路由規(guī)則。VueRouter.createWebHistory()
創(chuàng)建一個(gè)導(dǎo)航方式,hash 和 history api(歷史模式)。默認(rèn)是history api。VueRouter.createRouter
創(chuàng)建一個(gè)路由的實(shí)例,然后把這個(gè)實(shí)例掛到app實(shí)例上面。這樣就可以正式使用路由了。setup
可以不在在setup里面寫代碼,當(dāng)然也可以在setup里面手寫路由,這里就不演示了。
小結(jié)
以上就是cnd方式的vue3的加載方式和簡單使用,包含路由、狀態(tài)管理、UI庫的引入、綁定、事件等。
這里主要介紹如何組合起來,而不是具體用法。具體用法后面會陸續(xù)介紹。
在線演示
https://naturefwvue.github.io/nf-vue-cnd/cnd/init/
github 有點(diǎn)卡,可能會轉(zhuǎn)很久。(或者是js掛的有點(diǎn)多。。。)
如果等不急的話,可以到下面看源碼。