vite2-electron-douyin 基于vite2.x+electron模仿抖音短视频应用实例。

整合了vite2+electron跨端开发技术仿制抖音界面桌面版exe应用软件。基于Vite2.x+Electron12+Vant3+Swiper6+V3popup等技术开发实现,支持键盘上下键切换短视频、新开多窗口等功能。

技术栈

  • 编码/技术:vscode / vue3.0 + vuex4 + vue-router@4
  • 组件库:vant3 (有赞移动端vue3组件库)
  • 滑动组件:swiper^6.5.0
  • 弹窗组件:v3popup(基于vue3.0自定义弹层)
  • 打包工具:electron-builder
  • iconfont图标:阿里字体图标库

项目结构目录

项目整合了vite2和electron技术,实现跨平台开发应用。短视频|直播页面滑动切换效果,使用的是swiper组件来实现。

Electron主进程入口文件

使用vue-cli-plugin-electron-builder构建的项目,根目录会有一个background.js入口文件。

/**
 * 主进程配置文件
 */

'use strict'

import { app, protocol, BrowserWindow, globalShortcut } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
// import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'

import Windows from './module/windows'

const isDevelopment = process.env.NODE_ENV !== 'production'

protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true } }
])

async function createWindow() {
  let window = new Windows()

  window.listen()
  window.createWin({isMainWin: true, resize: false})
  window.createTray()
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    // try {
    //   await installExtension(VUEJS_DEVTOOLS)
    // } catch (e) {
    //   console.error('Vue Devtools failed to install:', e.toString())
    // }
  }
  createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit()
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
  }
}

渲染页面入口配置main.js

/**
 * 渲染进程页面配置
 */

import { createApp } from 'vue'
import App from './App.vue'

// 引入Router及Vuex
import Router from './router'
import Store from './store'

// 引入公用组件
import Plugins from './plugins'

import { winCfg, loadWin } from './module/actions'

// 引入Js
import '@/assets/js/fontSize'

// 引入公用样式
import '@/assets/fonts/iconfont.css'
import '@/assets/css/reset.css'
import '@/assets/css/layout.css'

loadWin().then(args => {
    winCfg.window = args

    createApp(App)
    .use(Router)
    .use(Store)
    .use(Plugins)
    .mount('#app')
})

Electron自定义拖拽区域+Tabbar组件

项目整体采用无边框模式 frame: false,css3中设置 -webkit-app-region: drag 即可实现自定义拖拽区域。

<WinBar bgcolor="transparent" transparent>
    <template #wbtn>
        <a class="wbtn" title="二维码名片" @click="isShowPersonalCard=true"><i class="iconfont icon-erweima"></i></a>
        <a class="wbtn" title="设置" @click="isShowSideMenu=true"><i class="iconfont icon-menu"></i></a>
    </template>
</WinBar>

<WinBar bgcolor="linear-gradient(to right, #36384a, #36384a)">
    <template #title>视频预览</template>
    <template #wbtn>
        <a class="wbtn" title="另存为" @click="handleDownLoad"><i class="iconfont icon-down"></i></a>
    </template>
</WinBar>

底部tabbar组件采用整屏透明效果。

<tabbar 
    bgcolor="linear-gradient(to bottom, transparent, rgba(0,0,0,.75))"
    color="rgba(245,255,235,.75)"
    activeColor="#fa367a"
    fixed
/>

Electron仿QQ托盘图标+闪烁

createTray() {
    const trayMenu = Menu.buildFromTemplate([
        {
            label: '我在线上', icon: path.join(__dirname, '../resource/icon-online.png'),
            click: () => null
        },
        {
            label: '隐身', icon: path.join(__dirname, '../resource/icon-invisible.png'),
            click: () => null
        },
        {type: 'separator'},
        {
            label: '关闭消息闪动', click: () => {
                this.flashTray(false)
            }
        },
        {type: 'separator'},
        {
            label: '显示窗口', click: () => {
                try {
                    for(let i in this.winLs) {
                        let win = this.getWin(i)
                        if(!win) return
                        if(win.isMinimized()) win.restore()
                        win.show()
                    }
                } catch (error) {
                    console.log(error)
                }
            }
        },
        {
            label: '退出', click: () => {
                try {
                    for(let i in this.winLs) {
                        let win = this.getWin(i)
                        if(win) win.webContents.send('win-logout')
                    }
                    app.quit()
                } catch (error) {
                    console.log(error)
                }
            }
        },
    ])
    this.tray = new Tray(this.trayIco1)
    this.tray.setContextMenu(trayMenu)
    this.tray.setToolTip(app.name)
}

flashTray(true|false)  即可实现开启/停止闪烁效果。

Electron+Vue3弹窗组件

项目中使用到的弹窗效果,分为electron桌面端弹窗和vue3自定义弹窗组件两种实现方式。

createWin({
    title: '关于',
    route: '/about',
    width: 420,
    height: 320,
    resize: false,
    parent: winCfg.window.id,
    modal: true,
})
<v3-popup v-model="isShowLogoutSys" anim="footer" type="actionsheet"
    content="<span><i class='iconfont icon-info c-46b6ef'></i> 确定要退出当前账号吗?</span>"
    :btns="[
        {text: '退出登录', style: 'color:#fa367a;', click: logoutSys},
        {text: '取消', click: () => isShowLogoutSys=false},
    ]"
>
</v3-popup>

具体的实现方式,大家可以去看看下面这两篇文章,这里就不详细介绍了。

https://www.cnblogs.com/xiaoyan2017/p/14210820.html

https://www.cnblogs.com/xiaoyan2017/p/14403820.html

Vite2+Electron打包配置

在根目录新建一个electron-builder.json文件,用来配置一些electron打包参数。

/**
 * @Desc     vite2+electron打包配置
 * @Time     andy by 2021-03
 * @About    Q:282310962  wx:xy190310
 */

{
    "productName": "electron-douyin", //项目名称 打包生成exe的前缀名
    "appId": "com.example.electrondouyin", //包名
    "compression": "maximum", //store|normal|maximum 打包压缩情况(store速度较快)
    "artifactName": "${productName}-${version}-${platform}-${arch}.${ext}", //打包后安装包名称
    // "directories": {
    //     "output": "build", //输出文件夹(默认dist_electron)
    // },
    "asar": false, //asar打包
    // 拷贝静态资源目录到指定位置(如根目录下的static文件夹会拷贝至打包后的dist_electron/win-unpacked/resources/static目录)
    "extraResources": [
        {
            "from": "/static",
            "to": "static"
        },
    ],
    "nsis": {
        "oneClick": false, //一键安装
        "allowToChangeInstallationDirectory": true, //允许修改安装目录
        "perMachine": true, //是否开启安装时权限设置(此电脑或当前用户)
        "artifactName": "${productName}-${version}-${platform}-${arch}-setup.${ext}", //打包后安装包名称
        "deleteAppDataOnUninstall": true, //卸载时删除数据
        "createDesktopShortcut": true, //创建桌面图标
        "createStartMenuShortcut": true, //创建开始菜单图标
        "shortcutName": "ElectronDouYin", //桌面快捷键图标名称
    },
    "win": {
        "icon": "/static/shortcut.ico", //图标路径
    }
}

注意

  • 项目路径最好不要有中文,否则打包可能会报错。
  • 最好不要使用getCurrentInstance来操作router或store,打包会报错。
  • vite.js+electron构建的项目,在渲染进程中.vue页面,调用ipcRendererremote会报如下错误

 Uncaught TypeError: fs.existsSync is not a function 

可在webPreferences中配置preload来解决。

webPreferences: {
    contextIsolation: false,
    nodeIntegration: false, // 启用Node集成
    preload: path.join(__dirname, '../resource/preload.js'),
    webSecurity: false,
    enableRemoteModule: true, // 是否启用远程模块
}

ok,以上就是vite2+electron+vant3跨端仿抖音短视频的分享,希望大家喜欢哈!

最后附上一个Vue3+Electron跨平台聊天应用

https://blog.csdn.net/yanxinyun1990/article/details/114162969

 

Logo

前往低代码交流专区

更多推荐