目录

前言

目的

思路

代码实现

1. 首先设计主页UI界面

2. 封装核心解析歌曲代码

3. 下载音乐到本地

4. 将界面居中,禁止修改窗口大小,等待关闭/退出指令

完整源码

运行效果

使用过程

菜单栏

打包的exe

总结


前言

本节将升级34. 实战:基于某api实现歌曲检索与下载(附完整源代码),也将基于api实现视频解析播放的功能,并且还实现了用户UI界面,可以用pyinstaller等库导出exe来永久保存可执行文件。

博主已经成功导出可执行文件,包括上一节的视频解析软件也已经导出。需要的小伙伴可以私信我或者评论区留言,我分享给你~


目的

实现一个VIP音乐解析系统,要求能够通过关键字检索需要的歌曲,并且设计用户界面,进行直观的交互行为,下载到本地同目录下的Download文件夹中。


思路

使用tkinter库设计UI界面并把各组件封装起来,核心功能仍然是34节所讲过的代码部分,传送门在这里,想要了解核心功能的跳转:34. 实战:基于某api实现歌曲检索与下载(附完整源代码)

接下来是详细思路:

1. 首先设计主页UI界面

2. 封装核心解析歌曲代码

3. 下载音乐到本地

4. 将界面居中,禁止修改窗口大小,等待关闭/退出指令


代码实现

先导包

import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as mes_box
import PySimpleGUI as sg
from tkinter import ttk
from retrying import retry

1. 首先设计主页UI界面

    def __init__(self, weight=1000, height=600):self.ui_weight = weightself.ui_height = heightself.title = "Vector的音乐解析器"self.ui_root = tk.Tk(className=self.title)self.ui_url = tk.StringVar()self.ui_var = tk.IntVar()self.ui_var.set(1)self.show_result = Noneself.song_num = Noneself.response_data = Noneself.song_url = Noneself.song_name = Noneself.song_author = Nonedef set_ui(self):"""设置简易UI界面:return:"""# Frame空间frame_1 = tk.Frame(self.ui_root)frame_2 = tk.Frame(self.ui_root)frame_3 = tk.Frame(self.ui_root)frame_4 = tk.Frame(self.ui_root)# ui界面中菜单设计ui_menu = tk.Menu(self.ui_root)self.ui_root.config(menu=ui_menu)file_menu = tk.Menu(ui_menu, tearoff=0)ui_menu.add_cascade(label='菜单', menu=file_menu)file_menu.add_command(label='使用说明', command=lambda: webbrowser.open('www.baidu.com'))file_menu.add_command(label='关于作者', command=lambda: webbrowser.open('https://blog.csdn.net/m0_59180666?spm=1010.2135.3001.5343'))file_menu.add_command(label='退出', command=self.ui_root.quit)# 控件内容设置choice_passageway = tk.Label(frame_1, text='请选择音乐搜索通道:', padx=10, pady=10)passageway_button_1 = tk.Radiobutton(frame_1, text='酷我', variable=self.ui_var, value=1, width=10, height=3)passageway_button_2 = tk.Radiobutton(frame_1, text='网易云', variable=self.ui_var, value=2, width=10, height=3)passageway_button_3 = tk.Radiobutton(frame_1, text='QQ音乐', variable=self.ui_var, value=3, width=10, height=3)passageway_button_4 = tk.Radiobutton(frame_1, text='酷狗', variable=self.ui_var, value=4, width=10, height=3)input_link = tk.Label(frame_2, text="请输入搜索关键词:")entry_style = tk.Entry(frame_2, textvariable=self.ui_url, highlightcolor='Fuchsia', highlightthickness=1,width=35)label2 = tk.Label(frame_2, text=" ")play_button = tk.Button(frame_2, text="搜索", font=('楷体', 11), fg='Purple', width=2, height=1,command=self.get_KuWoMusic)label3 = tk.Label(frame_2, text=" ")# 表格样式columns = ("序号", "歌手", "歌曲", "专辑")self.show_result = ttk.Treeview(frame_3, height=20, show="headings", columns=columns)# 下载download_button = tk.Button(frame_4, text="下载", font=('楷体', 11), fg='Purple', width=6, height=1, padx=5,pady=5, command=self.download_music)# 控件布局frame_1.pack()frame_2.pack()frame_3.pack()frame_4.pack()choice_passageway.grid(row=0, column=0)passageway_button_1.grid(row=0, column=1)passageway_button_2.grid(row=0, column=2)passageway_button_3.grid(row=0, column=3)passageway_button_4.grid(row=0, column=4)input_link.grid(row=0, column=0)entry_style.grid(row=0, column=1)label2.grid(row=0, column=2)play_button.grid(row=0, column=3, ipadx=10, ipady=10)label3.grid(row=0, column=4)self.show_result.grid(row=0, column=4)download_button.grid(row=0, column=5)# 设置表头self.show_result.heading("序号", text="序号")self.show_result.heading("歌手", text="歌手")self.show_result.heading("歌曲", text="歌曲")self.show_result.heading("专辑", text="专辑")# 设置列self.show_result.column("序号", width=100, anchor='center')self.show_result.column("歌手", width=200, anchor='center')self.show_result.column("歌曲", width=200, anchor='center')self.show_result.column("专辑", width=300, anchor='center')# 鼠标点击self.show_result.bind('<ButtonRelease-1>', self.get_song_url)

2. 封装核心解析歌曲代码

    @retry(stop_max_attempt_number=5)def get_KuWoMusic(self):"""获取qq音乐:return:"""# 清空treeview表格数据for item in self.show_result.get_children():self.show_result.delete(item)headers = {'accept': 'application/json, text/plain, */*','accept - encoding': 'gzip, deflate','accept - language': 'zh - CN, zh;q = 0.9','cache - control': 'no - cache','Connection': 'keep-alive','csrf': 'HH3GHIQ0RYM','Referer': 'http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6','User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/99.0.4844.51 Safari/537.36','Cookie': '_ga=GA1.2.218753071.1648798611; _gid=GA1.2.144187149.1648798611; _gat=1; ''Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1648798611; ''Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1648798611; kw_token=HH3GHIQ0RYM'}search_input = self.ui_url.get()if len(search_input) > 0:search_url = 'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?'search_data = {'key': search_input,'pn': '1','rn': '80','httpsStatus': '1','reqId': '858597c1-b18e-11ec-83e4-9d53d2ff08ff'}try:self.response_data = requests.get(search_url, params=search_data, headers=headers, timeout=20).json()songs_data = self.response_data['data']['list']if int(self.response_data['data']['total']) <= 0:mes_box.showerror(title='错误', message='搜索: {} 不存在.'.format(search_input))else:for i in range(len(songs_data)):self.show_result.insert('', i, values=(i + 1, songs_data[i]['artist'], songs_data[i]['name'],songs_data[i]['album']))except TimeoutError:mes_box.showerror(title='错误', message='搜索超时,请重新输入后再搜索!')else:mes_box.showerror(title='错误', message='未输入需查询的歌曲或歌手,请输入后搜索!')def get_song_url(self, event):"""获取下载歌曲的地址:return:"""# treeview中的左键单击for item in self.show_result.selection():item_text = self.show_result.item(item, "values")# 获取self.song_num = int(item_text[0])# 获取下载歌曲的地址if self.song_num is not None:songs_data = self.response_data['data']['list']songs_req_id = self.response_data['reqId']song_rid = songs_data[self.song_num - 1]['rid']music_url = 'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={}&type=convert_url3' \'&httpsStatus=1&reqId={}' \.format(song_rid, songs_req_id)response_data = requests.get(music_url).json()self.song_url = response_data['data'].get('url')self.song_name = songs_data[self.song_num - 1]['name']self.song_author = songs_data[self.song_num - 1]['artist']else:mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择')

3. 下载音乐到本地

    def download_music(self):"""下载音乐:return:"""if not os.path.exists('./Download'):os.mkdir("./Download/")if self.song_num is not None:song_name = self.song_name + '--' + self.song_author + ".mp3"try:save_path = os.path.join('./3_Download/{}'.format(song_name)) \.replace('\\', '/')true_path = os.path.abspath(save_path)resp = requests.get(self.song_url)with open(save_path, 'wb') as file:file.write(resp.content)mes_box.showinfo(title='下载成功', message='歌曲:%s,保存地址为%s' % (self.song_name, true_path))except Exception:mes_box.showerror(title='错误', message='未找到存放歌曲的文件夹')else:mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择后下载')def progress_bar(self, file_size):"""任务加载进度条:return:"""layout = [[sg.Text('任务完成进度')],[sg.ProgressBar(file_size, orientation='h', size=(40, 20), key='progressbar')],[sg.Cancel()]]# window只需将自定义的布局加载出来即可 第一个参数是窗口标题。window = sg.Window('机器人执行进度', layout)# 根据key值获取到进度条_progress_bar = window['progressbar']for i in range(file_size):  # 循环event, values = window.read(timeout=10)if event == 'Cancel' or event is None:break_progress_bar.UpdateBar(i + 1)

4. 将界面居中,禁止修改窗口大小,等待关闭/退出指令

    def ui_center(self):"""UI界面窗口设置:居中"""ws = self.ui_root.winfo_screenwidth()hs = self.ui_root.winfo_screenheight()x = int((ws / 2) - (self.ui_weight / 2))y = int((hs / 2) - (self.ui_height / 2))self.ui_root.geometry('{}x{}+{}+{}'.format(self.ui_weight, self.ui_height, x, y))def loop(self):"""函数说明:loop等待用户事件"""self.ui_root.resizable(False, False)  # 禁止修改窗口大小self.ui_center()  # 窗口居中self.set_ui()self.ui_root.mainloop()if __name__ == '__main__':a = SetUI()a.loop()

完整源码

# Created at UESTC
# Author: Vector Kun
# Time: 2023/1/29 11:07import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as mes_box
import PySimpleGUI as sg
from tkinter import ttk
from retrying import retryclass SetUI(object):"""音乐弹框界面"""def __init__(self, weight=1000, height=600):self.ui_weight = weightself.ui_height = heightself.title = "Vector的音乐解析器"self.ui_root = tk.Tk(className=self.title)self.ui_url = tk.StringVar()self.ui_var = tk.IntVar()self.ui_var.set(1)self.show_result = Noneself.song_num = Noneself.response_data = Noneself.song_url = Noneself.song_name = Noneself.song_author = Nonedef set_ui(self):"""设置简易UI界面:return:"""# Frame空间frame_1 = tk.Frame(self.ui_root)frame_2 = tk.Frame(self.ui_root)frame_3 = tk.Frame(self.ui_root)frame_4 = tk.Frame(self.ui_root)# ui界面中菜单设计ui_menu = tk.Menu(self.ui_root)self.ui_root.config(menu=ui_menu)file_menu = tk.Menu(ui_menu, tearoff=0)ui_menu.add_cascade(label='菜单', menu=file_menu)file_menu.add_command(label='使用说明', command=lambda: webbrowser.open('www.baidu.com'))file_menu.add_command(label='关于作者', command=lambda: webbrowser.open('https://blog.csdn.net/m0_59180666?spm=1010.2135.3001.5343'))file_menu.add_command(label='退出', command=self.ui_root.quit)# 控件内容设置choice_passageway = tk.Label(frame_1, text='请选择音乐搜索通道:', padx=10, pady=10)passageway_button_1 = tk.Radiobutton(frame_1, text='酷我', variable=self.ui_var, value=1, width=10, height=3)passageway_button_2 = tk.Radiobutton(frame_1, text='网易云', variable=self.ui_var, value=2, width=10, height=3)passageway_button_3 = tk.Radiobutton(frame_1, text='QQ音乐', variable=self.ui_var, value=3, width=10, height=3)passageway_button_4 = tk.Radiobutton(frame_1, text='酷狗', variable=self.ui_var, value=4, width=10, height=3)input_link = tk.Label(frame_2, text="请输入搜索关键词:")entry_style = tk.Entry(frame_2, textvariable=self.ui_url, highlightcolor='Fuchsia', highlightthickness=1,width=35)label2 = tk.Label(frame_2, text=" ")play_button = tk.Button(frame_2, text="搜索", font=('楷体', 11), fg='Purple', width=2, height=1,command=self.get_KuWoMusic)label3 = tk.Label(frame_2, text=" ")# 表格样式columns = ("序号", "歌手", "歌曲", "专辑")self.show_result = ttk.Treeview(frame_3, height=20, show="headings", columns=columns)# 下载download_button = tk.Button(frame_4, text="下载", font=('楷体', 11), fg='Purple', width=6, height=1, padx=5,pady=5, command=self.download_music)# 控件布局frame_1.pack()frame_2.pack()frame_3.pack()frame_4.pack()choice_passageway.grid(row=0, column=0)passageway_button_1.grid(row=0, column=1)passageway_button_2.grid(row=0, column=2)passageway_button_3.grid(row=0, column=3)passageway_button_4.grid(row=0, column=4)input_link.grid(row=0, column=0)entry_style.grid(row=0, column=1)label2.grid(row=0, column=2)play_button.grid(row=0, column=3, ipadx=10, ipady=10)label3.grid(row=0, column=4)self.show_result.grid(row=0, column=4)download_button.grid(row=0, column=5)# 设置表头self.show_result.heading("序号", text="序号")self.show_result.heading("歌手", text="歌手")self.show_result.heading("歌曲", text="歌曲")self.show_result.heading("专辑", text="专辑")# 设置列self.show_result.column("序号", width=100, anchor='center')self.show_result.column("歌手", width=200, anchor='center')self.show_result.column("歌曲", width=200, anchor='center')self.show_result.column("专辑", width=300, anchor='center')# 鼠标点击self.show_result.bind('<ButtonRelease-1>', self.get_song_url)@retry(stop_max_attempt_number=5)def get_KuWoMusic(self):"""获取qq音乐:return:"""# 清空treeview表格数据for item in self.show_result.get_children():self.show_result.delete(item)headers = {'accept': 'application/json, text/plain, */*','accept - encoding': 'gzip, deflate','accept - language': 'zh - CN, zh;q = 0.9','cache - control': 'no - cache','Connection': 'keep-alive','csrf': 'HH3GHIQ0RYM','Referer': 'http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6','User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/99.0.4844.51 Safari/537.36','Cookie': '_ga=GA1.2.218753071.1648798611; _gid=GA1.2.144187149.1648798611; _gat=1; ''Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1648798611; ''Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1648798611; kw_token=HH3GHIQ0RYM'}search_input = self.ui_url.get()if len(search_input) > 0:search_url = 'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?'search_data = {'key': search_input,'pn': '1','rn': '80','httpsStatus': '1','reqId': '858597c1-b18e-11ec-83e4-9d53d2ff08ff'}try:self.response_data = requests.get(search_url, params=search_data, headers=headers, timeout=20).json()songs_data = self.response_data['data']['list']if int(self.response_data['data']['total']) <= 0:mes_box.showerror(title='错误', message='搜索: {} 不存在.'.format(search_input))else:for i in range(len(songs_data)):self.show_result.insert('', i, values=(i + 1, songs_data[i]['artist'], songs_data[i]['name'],songs_data[i]['album']))except TimeoutError:mes_box.showerror(title='错误', message='搜索超时,请重新输入后再搜索!')else:mes_box.showerror(title='错误', message='未输入需查询的歌曲或歌手,请输入后搜索!')def get_song_url(self, event):"""获取下载歌曲的地址:return:"""# treeview中的左键单击for item in self.show_result.selection():item_text = self.show_result.item(item, "values")# 获取self.song_num = int(item_text[0])# 获取下载歌曲的地址if self.song_num is not None:songs_data = self.response_data['data']['list']songs_req_id = self.response_data['reqId']song_rid = songs_data[self.song_num - 1]['rid']music_url = 'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={}&type=convert_url3' \'&httpsStatus=1&reqId={}' \.format(song_rid, songs_req_id)response_data = requests.get(music_url).json()self.song_url = response_data['data'].get('url')self.song_name = songs_data[self.song_num - 1]['name']self.song_author = songs_data[self.song_num - 1]['artist']else:mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择')def download_music(self):"""下载音乐:return:"""if not os.path.exists('./Download'):os.mkdir("./Download/")if self.song_num is not None:song_name = self.song_name + '--' + self.song_author + ".mp3"try:save_path = os.path.join('./3_Download/{}'.format(song_name)) \.replace('\\', '/')true_path = os.path.abspath(save_path)resp = requests.get(self.song_url)with open(save_path, 'wb') as file:file.write(resp.content)mes_box.showinfo(title='下载成功', message='歌曲:%s,保存地址为%s' % (self.song_name, true_path))except Exception:mes_box.showerror(title='错误', message='未找到存放歌曲的文件夹')else:mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择后下载')def progress_bar(self, file_size):"""任务加载进度条:return:"""layout = [[sg.Text('任务完成进度')],[sg.ProgressBar(file_size, orientation='h', size=(40, 20), key='progressbar')],[sg.Cancel()]]# window只需将自定义的布局加载出来即可 第一个参数是窗口标题。window = sg.Window('机器人执行进度', layout)# 根据key值获取到进度条_progress_bar = window['progressbar']for i in range(file_size):  # 循环event, values = window.read(timeout=10)if event == 'Cancel' or event is None:break_progress_bar.UpdateBar(i + 1)def ui_center(self):"""UI界面窗口设置:居中"""ws = self.ui_root.winfo_screenwidth()hs = self.ui_root.winfo_screenheight()x = int((ws / 2) - (self.ui_weight / 2))y = int((hs / 2) - (self.ui_height / 2))self.ui_root.geometry('{}x{}+{}+{}'.format(self.ui_weight, self.ui_height, x, y))def loop(self):"""函数说明:loop等待用户事件"""self.ui_root.resizable(False, False)  # 禁止修改窗口大小self.ui_center()  # 窗口居中self.set_ui()self.ui_root.mainloop()if __name__ == '__main__':a = SetUI()a.loop()

运行效果

使用过程

菜单栏

打包的exe


总结

本文实现了一个VIP音乐解析系统,能够通过关键字检索需要的歌曲,并且设计了用户界面,可以进行直观的交互行为,也能将目标歌曲下载到本地同目录下的Download文件夹中。

40. 实战:基于tkinter实现用户UI界面——对34小节的VIP音乐解析系统的全面升级(附源码)相关推荐

  1. 【Android-Service】基于MVP的音乐播放器demo实现思路(附源码)

    最近在学习service相关的内容,在该部分的学习过程中,根据学习视频中的内容进行了总结归纳,以下是音乐播放器demo的开发思路,具体步骤及源码: 有关MVP框架的内容可看: link. 实现效果: ...

  2. vue代码生成器可视化界面_手把手教你基于SqlSugar4编写一个可视化代码生成器(生成实体,以SqlServer为例,文末附源码)...

    在开发过程中免不了创建实体类,字段少的表可以手动编写,但是字段多还用手动创建的话不免有些浪费时间,假如一张表有100多个字段,手写有些不现实. 这时我们会借助一些工具,如:动软代码生成器.各种ORM框 ...

  3. 基于Matlab在以地球为中心的场景中模拟和跟踪航路飞机仿真(附源码)

    目录 一.创建航路空中交通方案 二.定义飞机模型和轨迹 三.沿路线添加监控站 四.可视化场景 五.定义中央雷达跟踪器和跟踪热熔器 六.使用雷达和 ADS-B 跟踪飞行 七.分析结果 八.总结 九.程序 ...

  4. 基于matlab仿真相控天线阵列在波束成形MIMO-OFDM系统中的使用(附源码)

    一.前言 本例显示了相控阵在采用波束成形的MIMO-OFDM通信系统中的使用.它使用通信工具箱和相控阵系统工具箱中的组件,对组成发射器和前端接收器组件的辐射元件进行建模,用于MIMO-OFDM通信系统 ...

  5. 基于STM32 + 超详细对新手全面解析讲解SPI协议(附源码)

    前言        本次我们学习一下STM32的一个基本外设 --- SPI,全程参考手册讲解,讲述SPI的工作模式和作用,让大家快速掌握和了解SPI通讯协议.本篇博客大部分是自己收集和整理,借鉴了很 ...

  6. 基于matlab使用主动声纳系统进行水下目标检测(附源码)

    一.前言 此示例演示如何模拟具有两个目标的主动单基地声纳方案.声纳系统由各向同性投影仪阵列和单个水听器元件组成.投影仪阵列呈球形.反向散射信号由水听器接收.接收到的信号包括直接和多路径贡献. 二.水下 ...

  7. 基于 SpringBoot+Vue+Java 的智慧外贸系统(数据库,附源码,教程)

    1. 简介 本系统主要包括管理员,买家和商家三个角色组成:主要包括首页.个人中心.买家管理.商家管理.商品分类管理.商品信息管理.商品预订管理.关单信息管理.送仓申请管理.运单信息管理.出口发票管理. ...

  8. Python图像识别实战(一):实现按数量随机抽取图像复制到另一文件夹(附源码和实现效果)

    前面我介绍了可视化的一些方法以及机器学习在预测方面的应用,分为分类问题(预测值是离散型)和回归问题(预测值是连续型)(具体见之前的文章). 从本期开始,我将做一个关于图像识别的系列文章,让读者慢慢理解 ...

  9. 【Python实战】WIFI密码小工具,甩万能钥匙十条街,WIFI任意连哦~(附源码)

    前言 不会吧不会吧,流量都这么便宜了不会还有人在蹭别人家WIFI吧? 但是也可以理解哈,试问谁还没有经历过这种时光那?就算是我,也曾经有过蹲在别人家大门 口蹭WIFi的事儿.这都是成长道路中不可避免的 ...

最新文章

  1. AI最佳论文都在这里了!(非常全,快领!)
  2. 企业研发人员配备比例_日本电产电动汽车马达研发基地落户大连
  3. VTK修炼之道53:图形基本操作进阶_多分辨率策略(模型细化的三种方法)
  4. 编译原理题练习题测试题
  5. SAP Hybris Commerce installer目录下的build.gradle
  6. 计算机中专专业是什么意思,计算机专业的中专与大专有什么不同?
  7. 保险条款精解(三) 撞车
  8. Mybatis如何调用oracle存储过程?入参为日期类型
  9. tp5分页不加载搜索参数
  10. pytorch torchvision.transforms.ToTensor
  11. Wannafly挑战赛27: D. 绿魔法师(莫比乌斯函数)
  12. 这是我的第一篇博文,请大家多多关照!~
  13. 电脑硬件知识学习_计算机的发展史,你对硬件知识了解多少,带大家了解一下....
  14. TransposonPSI——转座子分析的入门自学
  15. 人工智能ai算法_当AI算法脱轨时
  16. QT应用SQL数据库,简单全面的应用,增删改查。
  17. 计算机网络工程师试题及答案,计算机软考网络工程师自测试题及答案汇总
  18. FireFox插件开发--弃用NPAPI
  19. WebStream生成vue项目报错Error: The project seems to require yarn but it‘s not installed.
  20. 什么是鸟撞?该如何设计防鸟撞的建筑?#可持续设计

热门文章

  1. 大数据项目实战——基于某招聘网站进行数据采集及数据分析(四)
  2. kicad绿油开窗_KICAD新手答疑解惑专帖
  3. 佐佐吉牧:SEO算法变化与对策
  4. Kendall tau距离
  5. 电网中直流潮流Distribution Factor的计算,bus间有多条输电线
  6. Mysql高级教程思维导图
  7. DX SDK Jun10 安装失败解决方法
  8. 初三物理光学知识点总结_初二物理:“光学”知识点总结
  9. 赏析 | 那些刷屏朋友圈的H5案例们(Top15)
  10. layer-v2.4弹层组件使用示例