上一篇做了简单介绍,这里开始进一步接触 vue3,可能大家比较熟悉jQuery那样直接引入js文件,然后就开干的方式,Vue也支持这种方式。
这种方式有一个好处,可以让我们尽快的了解 vue 的工作方式,加载组件、第三方插件的方式等。抛开干扰直接体会 vue3 的便捷。
学习vue3,从简单粗暴的方式开始,就像jQuery那样,直接开干,不要node,不要npm,不要各种乱乱的,就是干。。。放心,本章只是过渡一下,不会跑偏。
如果你对官网的例子有点茫然,不知如何下手的话,那么可以来看看也许会豁然开朗也说不定。
【CDN】引入 vue.js 的几种方式
还是先看看官网(cn.vuejs.org/guide/quick… ),其中提供了多种方式:
- 借助 script 标签引入
- 使用 ES 模块的方式引入
- 使用映射表(import maps)的方式引入
script标签引入,直接开干
用 script 标签引入 vue.js 是大家最熟悉的方式,比如这样:
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
<!--指定渲染位置-->
<div id="app">
<!--相当于 template-->
vue3 CDN 的 基础演示:<br>
person:{{person}} <!--插值-->
</div>
<script>
const { createApp, reactive } = Vue
// 定义一个对象,要有 setup、props等属性
const app = {
setup(props) {
const person = reactive({
name: 'composition API演示'
})
return {
person
}
}
}
// 创建 Vue 的一个应用
createApp(app)
.mount('#app') // 指定渲染的位置
</script>
这样看起来比较清晰了吧。这是 vue3 的 hello world,包含引入方式,创建方式,compositionAPI,setup,响应性,插值等。
上面是锁定版本的引入方式,还可以使用 src="https://unpkg.com/vue@3" 的方式,这样可以自动跳转到最新版本。
定义一个对象,设置一个名为 setup 的函数,然后用 createApp 创建一个vue的应用,使用 mount 指定渲染位置。一个简单的vue应用就搞定了。
ES模块是啥
简单地说,在 script 上面加上 type="module" 就可以使用 import 来加载js文件了,这种方式比 script 标签的方式要灵活很多。
<div id="app">
使用 ES 模块构建版本
person:{{person}}
</div>
<script type="module">
// 使用 import 的方式引入 vue
import { createApp, reactive } from 'https://unpkg.com/vue@3.2.47/dist/vue.esm-browser.js'
// 定义一个对象,要有 setup、props等属性
const app = {
setup(props) {
const person = reactive({
name: 'composition API演示'
})
return {
person
}
}
}
// 创建 Vue 的一个应用
createApp(app)
.mount('#app') // 指定渲染的位置
</script>
映射表又是啥
使用 import 引入 vue,如果每次都要写一大串url,那么就太麻烦了。所以我们可以使用映射方式来解决。
<script type="importmap">
// 使用映射
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<div id="app">
vue3 CDN 的 导入映射表 (Import Maps) 演示:<br>
person:{{person}}
</div>
<script type="module">
// 做映射后可以直接使用 ‘vue’
import { createApp, reactive } from 'vue'
// 定义一个对象,要有 setup、props等属性
const app = {
setup(props) {
const person = reactive({
name: 'composition API演示'
})
return {
person
}
}
}
// 创建 Vue 的一个应用
createApp(app)
.mount('#app') // 指定渲染的位置
</script>
加载js文件、组件的方式
上面的代码都写在一个网页里面,代码少好还好,但是代码多了怎么办?这时就需要一种分散代码、以及加载代码的方式。
我们可以使用 ES 模块的引入方式,因为这样比较方便。(不考虑浏览器的兼容问题)
比较完整的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!--加载 vue3 -->
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CDN建立项目的基本结构</title>
</head>
<body>
<div id="app"> 加载中。。。 </div>
<script type="module">
const { createApp } = Vue
// 引入一个 vue 的对象,相当于一个组件
import app from './src/app.js'
createApp(app)
.mount('#app')
</script>
</body>
</html>
这样 index.html 看起来就不那么乱了。而且这个页面的代码数量不会跟着项目变大而变大。
- app.js (js文件、组件)
export default {
template: `
Vue3 的 CDN 的分散代码的方式:<br>
person:{{person}}
`,
setup(props) {
const person = reactive({
name: 'composition API演示'
})
return {
person
}
}
}
这样我们可以把代码分散开编写,按照共用代码、组件等形式进行管理。
引入各种插件的方式
Vue 不是孤身奋战的,还需要UI库、路由、状态、第三方插件等来帮忙,那么在CDN环境下如何把这些战友拉进来呢?
引入 UI库的方式
现在支持 Vue3 的UI库有很多,这里以老牌的 elementPlus 为例,其他UI库也是类似的方法。
到官网(element-plus.gitee.io/zh-CN/guide… )查看,找到引入的方式,然后进行挂载。
<!--加载 vue3 -->
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.js"></script>
<!--加载 element-plus -->
<script src="https://unpkg.com/element-plus@2.3.4/dist/index.full.js"></script>
<!--加载 element-plus 需要的 css -->
<link href="https://unpkg.com/element-plus@2.3.4/dist/index.css" rel="stylesheet"/>
<script type="module">
const { createApp, reactive } = Vue
import app from './src/app.js'
createApp(app)
.use(ElementPlus) // 挂载 UI库
.mount('#app')
</script>
引入 路由的方式
vue3 一般使用 Vue Router(4.0) 实现路由的功能,引入方式和引入UI库类似,也是先去官网(router.vuejs.org/zh/installa… )查看。
挂载路由
首先使用 script 引入 Vue Router ,然后写一个js文件(router/index.js)设置路由。
<!--加载 vue-router -->
<script src="https://unpkg.com/vue-router@4.1.6/dist/vue-router.global.js"></script>
<script type="module">
// 引入路由设置
import router from './src/router/index.js'
// 引入起始组件
import app from './src/app2.js'
const { createApp, reactive } = Vue
// 建立vue应用
createApp(app)
.use(router) // 挂载路由
.use(ElementPlus) // 挂载 UI库
.mount('#app')
</script>
设置路由的方式
参照官网(router.vuejs.org/zh/guide/ )的实例,稍微修改一下:
- router/index.js
// 1. 定义路由组件.
// 从文件导入组件
import company from '../views/company.js'
import about from '../views/about.js'
// 引入 路由 的 API
const {
createRouter, // 创建路由
createWebHashHistory, // 带 # 的路由
createWebHistory // 不带 # 的路由
} = VueRouter
// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
const routes = [
{ path: '/company', component: company },
{ path: '/about', component: about },
]
// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
export default createRouter({
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
history: createWebHashHistory(),
// history: createWebHistory(),
routes // `routes: routes` 的缩写
})
使用路由的方式
上面两个步骤以及设置好路由并且挂载,然后如何使用呢?这里先简单介绍一下,我们可以使用 <router-link to="/company">公司介绍</router-link>,也可以使用UI库提供的menu:
<el-menu
router
>
<el-menu-item index="/company">
<template #title>公司介绍</template>
</el-menu-item>
<el-menu-item index="/about">
<template #title>关于我们</template>
</el-menu-itemu>
</el-menu>
其他使用方式请查看官网。
引入 状态(比如 Pinia)的方式
以前的状态管理采用 Vuex,现在官网推荐使用 Pinia(pinia.vuejs.org/zh/getting-… )了,所以我也以Pinia为例设置状态。
在 CDN 下使用 Pinia,需要引入两个js文件才行,后者是为了兼容vue2。然后挂载 Pinia,以及定义和引入状态。
挂载Pinia
<!--加载 pinia -->
<script src="https://unpkg.com/vue-demi@0.14.0/lib/index.iife.js"></script>
<script src="https://unpkg.com/pinia@2.0.35/dist/pinia.iife.js"></script>
<script type="module">
// 引入路由设置
import router from './src/router/index.js'
// 引入起始组件
import app from './src/app2.js'
const { createApp, reactive } = Vue
// 建立、初始化 Pinia
const pinia = Pinia.createPinia()
// 建立vue应用
createApp(app)
.use(router) // 挂载路由
.use(ElementPlus) // 挂载UI库
.use(pinia) // 挂载状态
.mount('#app')
</script>
Pinia 是全局状态,在 template 里面可以使用 $pinia.state 里获取状态集合。不过用处不大,因为这时候某个具体的状态可能还没有被创建。
定义一个状态
定义一个状态非常方便,还是先建立一个js文件
const { defineStore } = Pinia
export default defineStore('person', () => {
const person = reactive({
name: '我是状态',
age: 20
})
const ageAdd = () => {
person.age += 1
}
return {
person,
ageAdd
}
})
这里采用了 Pinia 的 setup 方式,而且直接使用 reactive 而不是ref,当然直接使用reactive会造成 状态多了一层,不过我不在意多这一层,如果你不喜欢的话,可以像官网那样使用 ref。
在组件里面引入状态
和引入一个js文件一样,好吧本身就是一个js文件:
// 引入状态
import usePerson from '../store/person.js'
// 导出一个 组件 的对象
export default {
template: `
关于我们:<br>
<el-button type="primary" @click="state.ageAdd">改变状态</el-button><br>
状态:{{state.person}}
`,
setup(props) {
const state = usePerson() // 获取状态
console.log('person:', state)
return {
state
}
}
}
小结
这样做项目的基本工具都准备好了,是不是可以开干了呢?当然不是!
本章只是过渡一下,热热身,做项目还是要用 工程化的方式。下一篇才是真正的开始。
ps:细心的你可能发现个问题,这里的 template 都是字符串的方式,这样太不友好了吧?这个全是不方便,也想了几种解决方法,但是都不够理想,所以这里就不说了。
所以做项目的正确打开方式,还是要用工程化的方式,可以避免各种麻烦事。这里只是过渡一下,辅助入门。