在Django+Vue3+GraphQL的Blog例子代碼中引入Element-Plus UI Framework

来源:https://www.cnblogs.com/magicduan/archive/2023/04/13/17315028.html
-Advertisement-
Play Games

Vue3的UI Framework中有Element-Plus、BalmUI、Quasar、PrimeVue、Ant Design Vue等UI Framework. Element-Plus是Element-UI的Vue3版,Element-UI的使用人數的基數較大,Github上的Star數也較 ...


Vue3的UI Framework中有Element-Plus、BalmUI、Quasar、PrimeVue、Ant Design Vue等UI Framework.

Element-Plus是Element-UI的Vue3版,Element-UI的使用人數的基數較大,Github上的Star數也較多,就選擇了Element-Plus作為這個Blog項目的UI Framework.

UI Framework的好處就是提供了相較裸Html+CSS開發起來更好看和方便一些.

Element-Plus在國內有鏡像站點,參看起來速度相對快一些. Element-Plus國內鏡像站點.

代碼可以從Github上取得https://github.com/magicduan/django_vue_graphql/releases/tag/base_0.2

配置Element-UI開發環境

如果在已有的項目中安裝的用包管理器安裝最方便了.

 npm install element-plus --save

由於對Element-Plus的組件的使用方法不是很熟練, 按照官網的說明我直接從Element-Plus提供的Vite的快速模版進行啟動.

https://github.com/element-plus/element-plus-vite-starter

從Github上下載代碼後展開,執行下列命令就可以啟動一個Element-Plus的Demo服務了.

npm install
npm run dev

按照前一篇Blog例子代碼, 修改vite.config.ts,加入埠配置,將Vue的埠設置為8080

export default defineConfig({
....
  server:{
    port:8080
  },
....

使用npm 安裝vue-router、apollo-client

npm install vue-router@4
npm install --save graphql graphql-tag @apollo/client
npm install --save @vue/apollo-composable

 

遷移代碼

由於是後安裝的vue-router,預設的vue-router 沒有設置, 建立與Frontend相同的目錄

src/router
src/views

將Blog項目中的Frontend中相關的代碼Copy進入對應目錄

src/router/index.ts
src/views/AllPosts.vue
src/views/AuthorView.vue
src/views/PostsByTag.vue
src/views/PostView.vue
src/componets/AuthorLink.vue
src/componets/PostLis.vue

修改頂部菜單BaseHeader.vue

Element-UI模版提供的是頂菜單+左工具欄的UI模版, src/compoments/layout/BaseHeader.vue 為頂部菜單, BaseSide.vue為左邊菜單.

這裡我們修改BaseHeader.vue,修改後菜單項為

MyBlog --> HomeView.vue
Posts 
   All Posts --> All Posts
   Add Post //將來實現
   Delete Post//將來實現
Tag ->根據Backend端的取得Tag的種類動態生成Tag菜單
HelloWord -->對應原Element-UI的Helloworld的例子

由於需要根據BackEnd端的Tag查詢結果動態生成Tag,我們為BaseHeader.vue加入Props :tagItems

Baseheader.vue代碼具體修改如下:

<script setup lang="ts" >
import { toggleDark } from '~/composables';
import { ref } from 'vue';
const props = defineProps({
  tagItems:{type:Array,required:true, default:[]}
})

const msg = ref("/hello/\"Hello Vue 3.0 + Element Plus + Vite\"")

</script>
<template>
  <el-menu class="el-menu-demo" mode="horizontal" :router= true>
    <el-menu-item index="/">My Blog</el-menu-item>
    <el-sub-menu index="2">
      <template #title>Posts</template>
      <el-menu-item index="/posts">All Posts</el-menu-item>
      <el-menu-item index="2-1">Add Post</el-menu-item>
      <el-menu-item index="2-2">Delete Post</el-menu-item>
      <el-sub-menu index="2-4">
        <template #title>...</template>
        <el-menu-item index="2-4-1">item one</el-menu-item>
        <el-menu-item index="2-4-2">item two</el-menu-item>
        <el-menu-item index="2-4-3">item three</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>

    <el-sub-menu v-if="tagItems.length" index="tags" >
      <template #title>Tags</template>
      <el-menu-item v-for="tagInfo in tagItems" :index="tagInfo.path">
        {{ tagInfo.name }}
      </el-menu-item>
    </el-sub-menu>
    <el-menu-item v-else :index="tags" disabled>Tags</el-menu-item>

    <el-menu-item :index="msg" >HelloVue</el-menu-item>

    <el-menu-item h="full" @click="toggleDark()">
      <button class="border-none w-full bg-transparent cursor-pointer" style="height: var(--ep-menu-item-height);">
        <i inline-flex i="dark:ep-moon ep-sunny" />
      </button>
    </el-menu-item>
  </el-menu>
</template>

 其中需要註意的幾點:

  • 將菜單項與vue-router結合起來,菜單項的index屬性為router/index.ts中設置的URL path, 需要設置el-menu
    :router= true
  • HelloWorld.vue 其中需要屬性msg,為了在菜單中進行配置,我們需要在index.ts中將HelloWord.vue的URL的prop設置為true
  
const router = createRouter({
...  
    {
      path: '/hello/:msg',
      name: 'HellowWorld',
      component: () => import("../components/HelloWorld.vue"),
      props: true  
    },
...

將HelloWorld.vue Component的Prop屬性作為參數來傳遞

修改App.vue

在App.vue中加入從Backend通過GraphQL取Tags的代碼, 將Tags數組傳遞給BaseHeader.vue,將<HelloWord .../>改為<routerview/>

<script setup lang="ts">
import HomeView from './views/HomeView.vue';
import HelloWorld from './components/HelloWorld.vue';
import gql from 'graphql-tag';
import { useQuery } from '@vue/apollo-composable';
import { computed } from '@vue/reactivity';

const {result,loading,error} =  useQuery(gql`
  query getTags{
    tags {
          name
    }
  }
`)

const tags = computed(()=>{
  let tagsArray = []
  if (result.value){
    result.value?.tags.forEach(tagName => {
      let tagInfo = {path:"/tag/"+tagName.name,name:tagName.name}
      tagsArray.push(tagInfo)
    });
  }
  return tagsArray

})

</script>
<template>
  <el-config-provider namespace="ep" >
    <BaseHeader :tagItems="tags"/>
    <div style="display: flex">
      <BaseSide />
      <div>
        <!-- <HelloWorld msg="Hello Vue 3.0 + Element Plus + Vite" @changeTags ='changTags'/>  -->
        <RouterView/> 
      </div>
    </div>
  </el-config-provider>
</template>

<style>
#app {
  text-align: center;
  color: var(--ep-text-color-primary);
}

.element-plus-logo {
  width: 50%;
}
</style>

在Backend中加入Tags的查詢

backend/blog/scheme/py

class Query(graphene.ObjectType):
    ....
    tags = graphene.List(TagType)
    .....
    def resolve_tags(root,info):
        return (
            models.Tag.objects.all()
        )

 

修改main.ts加入router,Apollo相關的代碼

import { DefaultApolloClient } from '@vue/apollo-composable'
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client/core'

// HTTP connection to the API
const httpLink = createHttpLink({
  uri: 'http://localhost:8000/graphql',
})

// Cache implementation
const cache = new InMemoryCache()

// Create the apollo client
const apolloClient = new ApolloClient({
  link: httpLink,
  cache,
})

const app = createApp({
    setup () {
      provide(DefaultApolloClient, apolloClient)
    },
  
    render: () => h(App),
  })

app.use(router)

 

至此blog相關的代碼遷移完成, 可以完成Posts List等操作了,但是頁面相對不太好看,下一步我們使用Element-UI的控制項進行對應改造即可.

使用Element-UI改造Posts等相關的Vue

在技術打通之後,UI的改造就是細心+審美的工作了,按照我自己的意思進行了修改,具體的修改就不贅述了,直接參考代碼即可.

 


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

-Advertisement-
Play Games
更多相關文章
  • 1、概念:docker是一個開源的應用容器引擎,docker可以讓開發者打包他們的應用以及依賴環境包到一個輕量級、可移值的容器中。然後發佈到任何流行的linux機器上。 安裝過程: 1、yum包更新到最新 yum update 2、安裝需要的軟體包 yum install -y yum-utils ...
  • 長字元串起因 項目裡面有一長串的加密字元串(最長的萬多個字元),需要拼接作為參數發送給第三方。 如果我們使用 枚舉 定義的話,idea 編譯的時候就會出現編譯報錯 Error: java:常量字元串過長 解決想法 網上還有一個說法,說是編譯器問題,修改 idea 工具的編譯為 eclipse 即可。 ...
  • 說下場景,我的程式在多線程場景下一個迴圈體中處理業務數據,其中需要調用一個外部http介面去獲取一些數據,程式總會在在本地執行一段時間後會拋出Address already in use: no further information錯誤。 這是大量併發場景下出現的問題,經過查閱原因是OkHttp的 ...
  • 文件操作 文件讀寫 語法:open(file, mode, encoding) 參數:file —— 文件所在位置(相對路徑、絕對路徑) mode —— 操作文件的模式 encoding —— 文件的編碼格式 相對路徑:基於目前的路徑獲取 絕對路徑:一個完整的路徑 操作文件的模式:r-讀 w-寫 a ...
  • 前言 做了個python的小項目,需要打包為桌面端的exe使用,結果一打包,體積直接上百兆了,研究了下,使用虛擬環境打出的包會更乾凈小巧。 安裝anaconda(用作python的虛擬環境管理工具) 安裝:https://repo.anaconda.com/archive/Anaconda3-202 ...
  • 判斷閏年 初始版本 year = input('請輸入一個年份:') while not year.isdigit(): year = input("抱歉,您的輸入有誤,請輸入一個整數:") year = int(year) if year % 400 == 0: print(year, "是閏年! ...
  • 在工作中,我們會將重要的文檔進行加密,並且設置用戶的訪問許可權,其他外部人員均無法打開,只有獲取該許可權的用戶才有資格打開文檔。此外,限制用戶的使用許可權,極大程度上阻止了那些有意要篡改、拷貝其中內容的人,提高文檔的安全性。與此同時,文檔加密的另一大作用是為了防止丟失,因為可能存在員工出差或離職時,將文檔 ...
  • 聲明 本文章中所有內容僅供學習交流使用,不用於其他任何目的,不提供完整代碼,抓包內容、敏感網址、數據介面等均已做脫敏處理,嚴禁用於商業用途和非法用途,否則由此產生的一切後果均與作者無關! 本文章未經許可禁止轉載,禁止任何修改後二次傳播,擅自使用本文講解的技術而導致的任何意外,作者均不負責,若有侵權, ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...