美文网首页每天学一点Vue3Vue.jsVue技术
从 jQuery 到 Vue3 的快捷通道

从 jQuery 到 Vue3 的快捷通道

作者: 自然框架 | 来源:发表于2022-05-06 19:00 被阅读0次

    当初使用 jQuery 做了几个简单的项目,算是有一点点了解,现在学习Vue3,发现了一个可以快速转换思维的通道 —— 使用CDN的方式模拟 Vite 建立的项目!

    CDN方式

    jQuery的使用非常方便,用 script 引入 js文件即可,然后找到DOM即可开始操作。
    而 Vue3 也支持直接用 script 引入的方式,然后使用插值的方式绑定数据,我们来看一下使用方法:

    • 引入 vue.js
      <head>
        <meta charset="UTF-8" />
        <!--加载 vue3 -->
        <script src="https://unpkg.com/vue@3.2.33/dist/vue.global.js"></script>
        <!--加载 element-plus -->
        <script src="https://unpkg.com/element-plus@2.1.9/dist/index.full.js"></script>
        <link href="https://unpkg.com/element-plus@2.1.9/dist/index.css" rel="stylesheet"/>
        <title>Vue3 CDN的简单演示</title>
      </head>
    

    这样我们就可以在网页里面使用 Vue 了,另外我们引入了一个UI库——element-plus。

    • 绑定数据和事件

    然后我们写一个 hello word:

    <body>
        <div id="app">
          <button @click="count++">自增</button> <br>
          <el-button @click="count++" >自增</el-button> <br>
          {{ count }}
        </div>
        <script>
          const { ref, createApp } = Vue
          const app = {
            setup() {
              const count = ref(0)
              return {
                count
              }
            }
          }
          
          createApp(app)
            .use(ElementPlus)
            .mount('#app')
        </script>
      </body>
    
    • 插值
      在模板里面使用双大括号即可实现数据绑定。

    • 事件
      可以使用原生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: `
         <button @click="count++">自增</button> <br>
         <el-button @click="count++" >自增</el-button> <br>
         {{ count }}
      `
      setup() {
        const count = ref(0)
        return {
          count
        }
      }
    }
    

    这样就可以建立一个单独的Vue组件,相关的代码都可以放在这里,管理起来就更容易了。

    工程化项目

    一般我们可以用 Vite 建立一个项目,然后安装需要的各种插件,但是这需要我们先了解 node、npm、yarn、vite等,还要先配置好环境,这些对于新手来说容易懵。

    那么能不能暂时跳过这些,直接建立一个工程化的项目呢?当然是可以的!

    我们可以模仿 Vite 建立的项目的文件结构,用CDN的方式实现一个项目。

    为啥要用CDN的方式模拟一下呢?因为这样可以先不用了解node等前置知识点,可以比较清晰的看到 Vue 的运作方式,快速理解Vue的特点,可以作为一种过渡方式。

    目录结构

    CDN目录.png

    可以发现和 Vite 建立的项目的结构是基本一样的,只是把.vue后缀变成了.js后缀。

    加载各种插件

      <head>
        <meta charset="UTF-8" />
        <link rel="icon" href="../nfwt.ico" />
        <script src="src/script/appImport.js?v=1"></script>
        <!--加载 axios -->
        <script src="https://unpkg.com/axios@0.26.1/dist/axios.min.js"></script>
        <!--加载 vue3 -->
        <script src="https://unpkg.com/vue@3.2.33/dist/vue.global.js"></script>
        <!--加载 vue-router -->
        <script src="https://unpkg.com/vue-router@4.0.14/dist/vue-router.global.js"></script>
        <!--加载 pinia -->
        <script src="https://unpkg.com/vue-demi@0.12.5/lib/index.iife.js"></script>
        <script src="https://unpkg.com/pinia@2.0.13/dist/pinia.iife.js"></script>
        <!--加载 element-plus -->
        <script src="https://unpkg.com/element-plus@2.1.9/dist/index.full.js"></script>
        <link href="https://unpkg.com/element-plus@2.1.9/dist/index.css" rel="stylesheet"/>
      </head>
    
    • pinia 状态管理
      pinia 需要加载两个文件,一个是pinia.js,另一个是其依赖项 vue-demi,实现兼容vue2的功能。

    加载 main.js

    main.js 是入口文件,需要在 index.html 使用 type="module" 的方式引入,这样main里面才可以使用“import”。

      <body>
        <div id="app">
          这里是CDN仿工程化开发的演示... 
        </div>
        <script type="module" src="src/main.js"></script>
      </body>
    

    设置 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') // 对应div
    })
    

    可以直接使用 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: `
      <el-container>
        <el-header>
          CND的方式 模仿工程化项目
        </el-header>
        <el-container>
          <el-aside width="200px">
            <!--菜单-->
            <my-menu/>
          </el-aside>
          <el-container>
            <el-main>
              <!--路由容器 -->
              <router-view></router-view>
            </el-main>
            <el-footer>
              CND的简单演示。by Vue3、element-plus、Pinia、vue-Router
            </el-footer>
          </el-container>
        </el-container>
      </el-container>
      `,
      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: `
        <router-link :to="{name:'Home'}">首页</router-link><br><br>
        <router-link :to="{name:'pinia'}">pinia</router-link><br><br>
        <router-link :to="{name:'h-test'}">h的演示</router-link><br><br>
        <router-link :to="{name:'jsx-test'}">jsx的演示</router-link><br><br>
      `,
      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 文件:

    <div>
      测试pinia的状态<br>
      {{ test }}<br>
      <el-button type="" @click="test.increment()">修改</el-button>
    </div>
    

    这样一个简单的项目结构就搭建起来了。

    小结

    本篇仅为过渡,并不是说正式项目要用这种方式开发,因为缺点也是很明显的。

    当然也是有一些优点:

    • 可以更充分的利用CDN,缓存vue.js这类的变化频率低的 js 文件,只需要更新业务相关的代码即可。
    • 如果CDN不卡的话,加载速度可以更快。
    • 可以利用CDN的资源,缓解自己服务器的压力。
    • 项目可以分模块开发,稳定且基础的模块可以打包、发布到CDN里面使用。

    源码和演示

    补充

    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)
          }
        })
      })
    }
    

    相关文章

      网友评论

        本文标题:从 jQuery 到 Vue3 的快捷通道

        本文链接:https://www.haomeiwen.com/subject/znyzyrtx.html