从jQuery到Vue3的快捷通道
当初使用 jQuery 做了几个简单的项目,算是有一点点了解,现在学习Vue3,发现了一个可以快速转换思维的通道 —— 使用CDN的方式模拟 Vite 建立的项目! CDN方式
jQuery的使用非常方便,用 script 引入 js文件即可,然后找到DOM即可开始操作。
而 Vue3 也支持直接用 script 引入的方式,然后使用插值的方式绑定数据,我们来看一下使用方法: 引入 vue.js Vue3 CDN的简单演示
这样我们就可以在网页里面使用 Vue 了,另外我们引入了一个UI库——element-plus。 绑定数据和事件
然后我们写一个 hello word:
自增
{{ count }} 插值
在模板里面使用双大括号即可实现数据绑定。 事件
可以使用原生button,也可以使用UI库提供的button,用v-on(简写:@)添加事件。 定义数据
这里采用 composition API 的方式,使用 ref,实现简单的计数功能。 挂载
使用 createApp 创建一个App,然后挂载插件、UI库、路由、状态等。
本篇只做简单介绍,详细介绍请移步官网:https://staging-cn.vuejs.org/ 组件化
一个项目有很多功能,显然不能把所有代码都放在一起,那么如何管理代码呢?Vue提供了组件化的方式,便于组织代码。
我们可以建立一个 count.js 文件(单文件组件),实现上面那个简单的计数功能: count.js const { ref } = Vue export default { name: "count", template: `
自增
{{ count }} ` setup() { const count = ref(0) return { count } } }
这样就可以建立一个单独的Vue组件,相关的代码都可以放在这里,管理起来就更容易了。 工程化项目
一般我们可以用 Vite 建立一个项目,然后安装需要的各种插件,但是这需要我们先了解 node、npm、yarn、vite等,还要先配置好环境,这些对于新手来说容易懵。
那么能不能 暂时 跳过这些,直接建立一个工程化的项目呢?当然是可以的!
我们可以模仿 Vite 建立的项目的文件结构,用CDN的方式实现一个项目。
为啥要用CDN的方式模拟一下呢?因为这样可以先不用了解node等前置知识点,可以比较清晰地看到 Vue 的运作方式,快速理解Vue的特点,可以作为一种过渡方式。 目录结构
可以发现和 Vite 建立的项目的结构是基本一样的,只是把.vue后缀变成了.js后缀。 加载各种插件 pinia 状态管理
pinia 需要加载两个文件,一个是pinia.js,另一个是其依赖项 vue-demi,实现兼容vue2的功能。 加载 main.js
main.js 是入口文件,需要在 index.html 使用 type="module" 的方式引入,这样main里面才可以使用"import"。 这里是CDN仿工程化开发的演示... 设置 main.js
然后在main里面加载根节点、路由设置、状态设置、UI库等操作。 const ver = window.__ver || "?v=0" const pinia = Pinia.createPinia() Promise.all([ import("./app.js" + ver), import("./router/index.js" + ver), ]).then((res) => { Vue.createApp(res[0].default) .use(res[1].default) // 挂载路由 .use(ElementPlus) // 加载ElementPlus .use(pinia) // 状态管理 .mount("#app") // 对应p })
可以直接使用 import App from "./app.js" 的方式加载,但是不好管理缓存。
所以采用了这种增加版本号的方式,以确保可以加载最新文件。 App.js
可以在 app.js 做页面布局,当然也可以实现其他功能。 const { ref, defineAsyncComponent } = Vue // 加载菜单组件 const myMenu = defineAsyncComponent(() => import("./views/menu.js" + window.__ver)) export default { name: "app", components: { myMenu }, template: ` CND的方式 模仿工程化项目 CND的简单演示。by Vue3、element-plus、Pinia、vue-Router `, setup() { return { } } }
这里采用异步组件的方式加载子组件,方便设置版本号,确保可以加载最新文件。 设置路由
为了更方便的加载组件,我们可以使用 vue-router 设置路由。 // 定义路由 const routes = [ { path: "/", name: "Home", component: () => myImport("views/home") }, { path: "/pinia", name: "pinia", component: () => myImport("views/state/pinia") }, { path: "/", name: "ui", component: () => myImport("views/ui/ui-elp") }, { path: "/h", name: "h-test", component: () => myImport("views/h/h") }, { path: "/jsx", name: "jsx-test", component: () => myImport("views/h/jsx") } ] const base = "/cdn3/" const router = VueRouter.createRouter({ history: VueRouter.createWebHistory(base), routes }) export default router
如果组件只有js文件,那么可以直接使用 import 来加载,如果组件由js+html组成,需要使用 myImport 来加载,myImport 是我自己封装的函数,在最后介绍。 设置菜单
我们先做一个简单的菜单: menu.js export default { name: "menu", template: ` 首页
pinia
h的演示
jsx的演示
`, setup() { return { } } }
这里先使用 router-link 做个简单的连接,也可以使用 el-menu 做菜单。 状态管理
这里采用最新的 pinia 进行状态管理,因为 Vuex 有点臃肿。
首先需要在 main.js 里面挂载pinia,见 main 的部分。
然后我们建立一个js文件,定义一个状态,再建立一个js文件作为组件。 count.js const { defineStore } = Pinia const testPromie = () => { return new Promise((resolve) => { setTimeout(() => { resolve(100) }, 500) }) } export const useCounterStore = defineStore("counter", { state: () => { return { count: 0, name: "" } }, actions: { increment() { this.count ++ }, async loadData(val, state) { const foo = await testPromie() this.count += foo this.name = "async 赋值:" + new Date().valueOf() }, loadData2(val, state) { testPromie().then((val) => { this.count += val this.name = "异步赋值:" + new Date().valueOf() }) } } }) pinia.js
然后在组件里面引入: // 状态 import { useCounterStore } from "./count.js" export default { name: "pinia-test", setup() { const test = useCounterStore() return { count } } } pinia.html
我们可以把 template 部分拿出去,做成 html 文件: 测试pinia的状态
{{ test }}
修改
这样一个简单的项目结构就搭建起来了。 小结
本篇仅为过渡,并不是说正式项目要用这种方式开发,因为缺点也是很明显的。
当然也是有一些优点: 可以更充分的利用CDN,缓存vue.js这类的变化频率低的 js 文件,只需要更新业务相关的代码即可。 如果CDN不卡的话,加载速度可以更快。 可以利用CDN的资源,缓解自己服务器的压力。 项目可以分模块开发,稳定且基础的模块可以打包、发布到CDN里面使用。 源码和演示源码:https://gitee.com/naturefw-project/vue3-cnd 演示:https://naturefw-project.gitee.io/vue3-cnd/ 补充
template 部分,如果用字符串的方式写,那么比较麻烦,所以可以分为 html 文件的方式来写,这样可以使用提示、补全和验证等功能。
然后做一个加载的函数 myImport : window.myImport = (url) => { return new Promise((resolve, reject) => { const ver = window.__ver || "" const baseUrl = window.__basrUrl || "/src/" // 先加载 js import(baseUrl + url + ".js" + ver).then((resjs) => { const js = resjs.default if (!js.template) { // 如果模板是空的,表示需要加载 html作为模板 axios.get(baseUrl + url + ".html" + ver).then((resHTML) => { js.template = resHTML.data resolve(js) }) } else { // 否则直接使用 js 注册组件 resolve(js) } }) }) }