6

Vue3(四)从jQuery 转到 Vue工程化 的捷径

 3 years ago
source link: http://www.cnblogs.com/jyk/p/14403214.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

不会 webpack 还想学 vue 工程化开发 的福音

熟悉jQuery开发的,学习vue的简单使用是没用啥问题的,但是学习vue的工程化开发方式,往往会遇到各种问题,比如:

webpack、node、npm、cnpm、yarn、脚手架、开发环境、测试环境、生产环境、各种安装、各种创建。

好在 vue3 不容易报错了,想当初 vue2.x 的时候各种报错,看到错误就只能干瞪眼,这都是啥?好像是webpack的报错。

当初学 vue2 就卡在了建立项目上,各种尝试居然一个项目都没跑起来。

如果能像jQuery那样,直接开鲁那多好呀!

各种阴差阳错+机缘巧合的情况下,弄出来了这种在 CND 模式下仿工程化开发的方式。一开始只是想方便我做在线演示,后来各种完善,发现还是应该有点搞头了。再加上大神在弄vite,似乎也是对webpack比较头疼。。。

好了不墨迹了,开始说我的做法。

vue全家桶和UI库的加载方式

这个很传统了,官方也支持。

<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/vue-router.global.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/vuex.global.js"></script>
  <link href="https://unpkg.com/[email protected]/lib/theme-chalk/index.css" rel="stylesheet">
  <script src="https://unpkg.com/[email protected]/lib/index.full.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

浏览器会对js文件做缓存,第一次有点慢,后缓存后就快了。

BVJrMnU.png!mobile

某网站有时候会卡一下,不卡的话还是很快的。

js代码的加载方式

<script type="module" src="src/main.js?v=4"></script>

听说vite也是这么加载的。好吧就是从vite建立的项目里copy来的。

要加上 type="module" 否则加载不了。

文件夹结构和代码编写风格

文件夹当然是把工程化的拿过来之间用了,挺简洁明了的。

因为浏览器也支持 import 的方式加载js,那么也就是说,CDN方式下也可以用import加载。那么js代码方面也不会有太大的差别。

我们来对比一下:

FZzaiqu.png!mobile

左面是CND的项目,右面是工程化的项目。

  • 文件夹结构完全一致,
  • js文件都能对应上
  • vue文件拆分成 html + js 两个文件(app.vue除外)

main.js

/*
import store from './store/index.js?v=1'
import router from './router/index.js?v=1'
import App from './app.js?v=1'

// 创建vue3的实例
const app = Vue.createApp(App)
  .use(store) 
  .use(router)
  .use(ElementPlus)
  .mount('#app')
*/

const ver = window.__ver || ''
Promise.all([
  import('./store/index.js' + ver),
  import('./router/index.js' + ver),
  import('./app.js' + ver),
]).then((res) => {
  // 创建vue3的实例
  const app = Vue.createApp(res[2].default)
    .use(res[0].default) // 挂载vuex
    .use(res[1].default) // 挂载路由
    .use(ElementPlus) // 加载ElementPlus
    .mount('#app') // 挂载Vue的app实例
})

注释掉的代码,和工程化里的代码是一致的,只是这种方式只支持常量,所以想把版本加在url地址上面就比较麻烦。

所以改为了这种异步的方式,这样可以把版本号给拼接上去。这样更新浏览器的js缓存就方便多了。

app.js

export default {
  name: 'app',
  setup() {
    do something...
  
    return {
    }
  }
}

工程化项目里面是App.vue,对应的是网页里 id=“app” 的div。

这里改成纯js文件的形式,因为模板就是index.html的div。

好吧,其实是main.js里面的加载方式不知道要怎么改。。。

router

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => myImport('views/home')
  },
  {
    path: '/About',
    name: 'About',
    component: () => myImport('views/About')
  },
  {
    path: '/component',
    name: 'component',
    component: () => myImport('views/component')
  },
  {
    path: '/store',
    name: 'store',
    component: () => myImport('views/store')
  }
]

const router = VueRouter.createRouter({
  history: VueRouter.createWebHistory(),
  routes
})

export default router
  • 动态路由

    这里采用动态路由的方式,另外换成了我自己封装的函数,可以加载html和js文件,然后变成动态组件的方式,这样组件就可以被路由加载了。

  • 路径设置问题

    本来想把html和js文件放在一个文件夹里面,就可以用同一个url加载了,结果和我想的不一样。

    由于加载 html 和加载 js 的路径规则不太一样,再加上路由导航的原因,

    所以只好用 src 作为分隔标识,统一从src开始计算路径。

myImport

// 直接放在Window里面好了。。。
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)
      }
    })
  })
}

一开始还想做个插件挂到vue上面,后来试了半天没成功。

然后觉得自己挺傻的,cnd环境,一个静态函数,直接挂在Window上面不就行了吗。

  • 加载 js 和 html

    先用 import 异步加载 js,目的是便于拼接url,然后判断是否有template。

    如果有的话,就不加载html了。

    如果没有的话,在用axios加载html,然后设置给template,这样就变成了一个标准的js组件。

  • 是否会重复加载?

    组件自带缓存机制,第一次会加载,以后就不会重复加载了。

store

import { Set_Count } from './mutation-types.js'

export default Vuex.createStore({
  state: {
    count: 0,
    myObject: {
      time: '现在的时间:'
    },
    myArray: [1,2,2,3,4]
  },
  getters: {
    getAddCount: (state) => {
      return state.count + 1
    } 
  },
  mutations: {
    // 计数器
    setCount(state, num = 1) {
      state.count += num
    },
    [Set_Count](state, num = 1) {
      state.count += num
    }
  },
  actions: {
  },
  modules: {
  }
})

基本上没啥区别。

如何方便的写模板

直接看图,更清晰一些。

iqmYzuv.png!mobile

一边写js代码,另一边写模板。这样也是很方便的。

一开始想在浏览器里面直接加载vue文件,然后处理成js组件。

想了半天,理论上应该可以,但是我这水平估计够呛,所以采用了这种折中的方式。

组件里面加载组件

QfINnym.png!mobile

  • defineAsyncComponent

    这个是Vue提供的异步组件,如果在工程化里面,可以直接加载vue文件。

    我在cnd里面试了一下,没成功。所以只好用纯js组件的方式。

动态路由不需要套这个,但是异步组件就要套上,否则没有效果。

搭一个梯子

这样做项目和 jQuery 的风格挺像的,文件copy过来,建立个网站就可以开鲁了。

同时代码编写方式又采用工程化的方式,熟悉之后可以方便的切换的工程化的开发方式。

就好像在 jQuery 与 vue 的工程化直接搭了一个梯子,应该大概可以方便我们翻过去吧。

便于调试

  • 设置断点看状态。

    2QRZJrm.png!mobile
  • 看成员

    uey2ea2.png!mobile
  • 进到内部了,好吧其实我都看不懂。。。

    ieE7Rjz.png!mobile

js文件的缓存问题

缓存是个好东东,避免我们重复加载js文件,加快页面显示速度,但是如果我们的js改了,浏览器却还是在用缓存怎么办?

我们可以设置一个版本号,加载文件后面就可以。当更新的时候,改一下版本号,就可以重新加载了。

源码

https://github.com/naturefwvue/nf-vue-cnd/tree/main/cnd/project-template

在线演示

https://naturefwvue.github.io/nf-vue-cnd/cnd/project-template/

一开始可能会有的卡,第一次点导航会加载文件,所以会慢一点,以后就好了。好像应该加一个加载中的状态。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK