從 jQuery 到 Vue3 的快捷通道

来源:https://www.cnblogs.com/jyk/archive/2022/05/01/16212215.html
-Advertisement-
Play Games

當初使用 jQuery 做了幾個簡單的項目,算是有一點點瞭解,現在學習Vue3,發現了一個可以快速轉換思維的通道 —— 使用CDN的方式模擬 Vite 建立的項目! CDN方式 jQuery的使用非常方便,用 script 引入 js文件即可,然後找到DOM即可開始操作。 而 Vue3 也支持直接用 ...


當初使用 jQuery 做了幾個簡單的項目,算是有一點點瞭解,現在學習Vue3,發現了一個可以快速轉換思維的通道 —— 使用CDN的方式模擬 Vite 建立的項目!

CDN方式

jQuery的使用非常方便,用 script 引入 js文件即可,然後找到DOM即可開始操作。
而 Vue3 也支持直接用 script 引入的方式,然後使用插值的方式綁定數據,我們來看一下使用方法:

  • 引入 vue.js
  <head>
    <meta charset="UTF-8" />
    <!--載入 vue3 -->
    <script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
    <!--載入 element-plus -->
    <script src="https://unpkg.com/[email protected]/dist/index.full.js"></script>
    <link href="https://unpkg.com/[email protected]/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/[email protected]/dist/axios.min.js"></script>
    <!--載入 vue3 -->
    <script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
    <!--載入 vue-router -->
    <script src="https://unpkg.com/[email protected]/dist/vue-router.global.js"></script>
    <!--載入 pinia -->
    <script src="https://unpkg.com/[email protected]/lib/index.iife.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/pinia.iife.js"></script>
    <!--載入 element-plus -->
    <script src="https://unpkg.com/[email protected]/dist/index.full.js"></script>
    <link href="https://unpkg.com/[email protected]/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)
      }
    })
  })
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在幾年前windows10系統就註意到,藍牙耳機連接windows電腦後會出現兩個模式,一個是Hands-free AG Audio(即免提模式,以下簡稱Hands-free),一個是stereo(立體聲模式),並且發現只有Hands-free模式才能使用耳機的麥克風,但是音質會差好多,stereo ...
  • 簡介 container_of(ptr, type, member)是內核中的經典函數之一。該函數的作用是:根據結構體中一個成員的地址,找到結構體的地址。這個函數是內核實現面向對象的基礎設施,且最近在學習中經常見到這個函數,於是筆者在內核中查看了該函數的實現,故在此記錄。本文原本是為了展示conta ...
  • CentOS7 安裝MYSQL5.7 [詳細過程] YUM 安裝 1.從mysql官網獲取 yum 倉庫 [[email protected] tmp]# wget 'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm' 2. ...
  • 導讀: 本次分享的內容為圖深度學習在自然語言處理領域的方法與應用,主要內容和素材都來自於我們Graph4NLP團隊的一篇調研文章:Graph Neural Networks for Natural Language Processing:A Survery,以及我們團隊所開發的Graph4NLP的p ...
  • MapReduce Hadoop中將數據切分成塊存在HDFS不同的DataNode中,如果想彙總,按照常規想法就是,移動數據到統計程式:先把數據讀取到一個程式中,再進行彙總。 但是HDFS存的數據量非常大時,對彙總程式所在的伺服器將產生巨大壓力,並且網路IO也十分消耗資源。 為瞭解決這種問題,Map ...
  • 許可權表 MySQL 伺服器通過許可權表來控制用戶對資料庫的訪問,由 mysql_install_db 腳本初始化,MySQL 會根據這些許可權表的內容為每個用戶賦予相應的許可權 1. user 表 user 表是 MySQL 最重要的一個許可權表,有 49 個欄位,這些欄位可以分成四類: 範圍列:包括 Ho ...
  • 終於算是順利進入vue了,確實也只有學了過後才知道,之前三過vue而不學,確實是對的,現在進來了一點都不後悔,ajax、node.js、promise、webpack、git等等確實是除了三大基礎外還需要額外學的。 終於能夠一窺vue的真容了,學了這麼久,說實話一直都忍著,不去觸碰這一條線,就想留著 ...
  • 鉤子函數 說明 beforeCreate 在實例初始化之後,數據觀測和watch/event事件配置之前被調用 created 在實例創建完成後被立即調用,在這一步,實例已經完成數據觀測、屬性和方法的運算,以及watch/event事件回調。掛載階段還未開始,$el屬性尚不可用。多用於初始化數據或方 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文將以 C# 語言來實現一個簡單的布隆過濾器,為簡化說明,設計得很簡單,僅供學習使用。 感謝@時總百忙之中的指導。 布隆過濾器簡介 布隆過濾器(Bloom filter)是一種特殊的 Hash Table,能夠以較小的存儲空間較快地判斷出數據是否存在。常用於允許一定誤判率的數據過濾及防止緩存 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 「簡單有價值的事情長期堅持做」 這是成功最簡單,但也最難學的秘訣。不經過訓練,人很難意識到時間複利的威力。 仙劍奇俠傳的「十里坡劍神」和金庸群俠傳的「十級野球拳」,就是簡單的事情持之以恆反覆做,最後就有巨大的威力 唐家三少成為網文收入第一,最重要的一步是十四年從未斷日更 這樣的案例很多,一開始可能成 ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“我愛加班”。 面試開始,直入正題。 面試官: 看你簡歷上面寫著精通MySQL,我先問你事務的特性是什麼? 老生常談,這個還有誰不會背的嗎? 我: ...
  • 基礎知識 python是一門腳本語言,它是解釋執行的。 python使用縮進做為語法,而且python2環境下同一個py文件中不能同時存在tab和空格縮進,否則會出錯,建議在IDE中顯示縮進符。 python在聲明變數時不寫數據類型,可以type(xx)來獲取欄位的類型,然後可以int(),list ...
  • 為什麼要多線程下載 俗話說要以終為始,那麼我們首先要明確多線程下載的目標是什麼,不外乎是為了更快的下載文件。那麼問題來了,多線程下載文件相比於單線程是不是更快? 對於這個問題可以看下圖。 橫坐標是線程數,縱坐標是使用對應線程數下載對應文件時花費的時間,藍橙綠代表下載文件的大小,每個線程下載對應文件2 ...
  • 詳細講解python爬蟲代碼,爬微博搜索結果的博文數據。 爬取欄位: 頁碼、微博id、微博bid、微博作者、發佈時間、微博內容、轉發數、評論數、點贊數。 爬蟲技術: 1、requests 發送請求 2、datetime 時間格式轉換 3、jsonpath 快速解析json數據 4、re 正則表達式提... ...
  • 背景: 一般我們可以用HashMap做本地緩存,但是HashMap功能比較弱,不支持Key過期,不支持數據範圍查找等。故在此實現了一個簡易的本地緩存,取名叫fastmap。 功能: 1.支持數據過期 2.支持等值查找 3.支持範圍查找 4.支持key排序 實現思路: 1.等值查找採用HashMap2 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 本章是系列文章的第八章,用著色演算法進行寄存器的分配過程。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 寄存器分配 寄存器分配是為程式處理的值找到存儲位置的問題 這些值可以存放到寄存器,也可以存放在記憶體中 寄存器更快,但數量有限 記憶體很多,但 ...