微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)

一、歌曲搜索

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第1张图片

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第2张图片

1. 界面数据获取

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第3张图片

<view class="searchContainer">
    
    <view class="header">
        <view class="searchInput">
            <text class="iconfont icon-search1 searchIcon">text>
            <input type="text" placeholder="{
      {placeholderContent}}" placeholder-class="placeholder" />
        view>
        <text class="cancel">取消text>
    view>

    
    <view class="hotContainer">
        <text class="title">热搜榜text>
        
        <view class="hotList">
            <view class="hotItem" wx:for="{
      {hotList}}" wx:key="searchWord">
                <text class="order">{
    {index + 1}}text>
                <text>{
    {item.searchWord}}text>
                <image wx:if="{
      {item.iconUrl}}" src="{
      {item.iconUrl}}" class="iconImg">image>
            view>
        view>
    view>
view>

.searchContainer{
     
    padding: 0 20rpx;
}

.header{
     
    display: flex;
    height: 60rpx;
    line-height: 60rpx;
    padding: 10rpx 0;
}
.searchInput{
     
    flex: 1;
    background: rgba(237,237,237,0.5);
    border-radius: 30rpx;
}

.cancel{
     
    width: 100rpx;
    text-align: center;
}

.searchIcon{
     
    position: absolute;
    left: 15rpx;
}

.searchInput input{
     
    margin-left: 50rpx;
    height: 60rpx;
}

.placeholder{
     
    /*color: #d43c33;*/
    font-size: 28rpx;
}

/* 热搜榜的样式*/
.hotContainer .title{
     
    font-size: 28rpx;
    height: 80rpx;
    line-height: 80rpx;
    border-bottom: 1rpx solid #eeeeee;
}

.hotList{
     
    display: flex;
    flex-wrap: wrap;
}

.hotItem{
     
    width: 50%;
    height: 80rpx;
    line-height: 80rpx;
    font-size: 26rpx;
}

.hotItem .order{
     
    margin: 0 10rpx;
}

.hotItem .iconImg{
     
    width: 35rpx;
    height: 20rpx;
    margin-left: 10rpx;
}
  // 获取初始化的数据
  async getInitData() {
     
    let placeholderData = await request("/search/default");
    let hotListData = await request("/search/hot/detail");
    this.setData({
     
      placeholderContent:placeholderData.data.showKeyword,
      hotList:hotListData.data
    });
  },

2. 模糊匹配

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第4张图片
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第5张图片

数据节流:每0.3 秒发一次请求

let isSend = true; // 函数节流使用


  // 表单项数据发生变化时的回调
   handleInputChange(event) {
     
    console.log(event)
    this.setData({
     
      searchContent: event.detail.value.trim()
    });
     if(isSend === false){
     
       return;
     }
     isSend = false;
    // 知识点:函数节流
    setTimeout(()=>{
     
      // 发请求获取关键字模糊匹配数据
      this.getSearchList();
      isSend = true;
    },300);
  },
  
  // 获取搜索数据的功能函数
  async getSearchList() {
     
    if(!this.data.searchContent){
     
      this.setData({
     
        searchList:[]
      })
      return;
    }
    let searchListData = await request("/search", {
     keywords: this.data.searchContent, limit: 10});
    this.setData({
     
      searchList: searchListData.result.songs
    });
  },

3. 歌曲搜索

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第6张图片

    
    <block wx:if="{
      {searchList.length}}">
        <view class="showSearchContent">
            <view class="searchContent">搜索内容:{
    {searchContent}}view>
            <view class="searchList">
                <view class="searchItem" wx:for="{
      {searchList}}" wx:key="id">
                    <text class="iconfont icon-search1">text>
                    <text class="content">{
    {item.name}}text>
                view>
            view>
        view>
    block>

    
    <block wx:else>
        <view class="hotContainer">
            <text class="title">热搜榜text>
            
            <view class="hotList">
                <view class="hotItem" wx:for="{
      {hotList}}" wx:key="searchWord">
                    <text class="order">{
    {index + 1}}text>
                    <text>{
    {item.searchWord}}text>
                    <image wx:if="{
      {item.iconUrl}}" src="{
      {item.iconUrl}}" class="iconImg">image>
                view>
            view>
        view>
    block>
/* 热搜榜的样式*/
.hotContainer .title{
     
    font-size: 28rpx;
    height: 80rpx;
    line-height: 80rpx;
    border-bottom: 1rpx solid #eeeeee;
}

.hotList{
     
    display: flex;
    flex-wrap: wrap;
}

.hotItem{
     
    width: 50%;
    height: 80rpx;
    line-height: 80rpx;
    font-size: 26rpx;
}

.hotItem .order{
     
    margin: 0 10rpx;
}

.hotItem .iconImg{
     
    width: 35rpx;
    height: 20rpx;
    margin-left: 10rpx;
}


/* 搜索内容展示 */
.searchContent{
     
    color: #d43c43;
    height: 80rpx;
    line-height: 80rpx;
    font-size: 24rpx;
    border-bottom: 1rpx solid #d43c43;
}

.searchItem{
     
    height: 80rpx;
    line-height: 80rpx;
    display: flex;
}

.searchItem .content{
     
    flex: 1;
    margin-left: 20rpx;
    border-bottom: 1rpx solid #eee;
    font-size: 26rpx;
}

4. 历史纪录

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第7张图片

wx.showModal(Object object)

 
 <view class="history" wx:if="{
      {historyList.length}}">
     <view class="title">历史view>
     <view class="historyItem" wx:for="{
      {historyList}}" wx:key="{
      {item}}">{
    {item}}view>
     
     <text class="iconfont icon-shanchu delete" bindtap="deleteSearchHistory">text>
 view>
 
 <view class="hotContainer">
     <text class="title">热搜榜text>
     
     <view class="hotList">
         <view class="hotItem" wx:for="{
      {hotList}}" wx:key="searchWord">
             <text class="order">{
    {index + 1}}text>
             <text>{
    {item.searchWord}}text>
             <image wx:if="{
      {item.iconUrl}}" src="{
      {item.iconUrl}}" class="iconImg">image>
         view>
     view>
 view>
/* 搜索历史样式 */
.history{
     
    position: relative;
    display: flex;
    flex-wrap: wrap;
    margin: 20rpx 0;
}

.history .title{
     
    font-size: 28rpx;
    height: 50rpx;
    line-height: 50rpx;
}

.history .historyItem{
     
    font-size: 26rpx;
    height: 50rpx;
    line-height: 50rpx;
    background: #ededed;
    margin-left: 20rpx;
    padding: 0 30rpx;
    border-radius: 20rpx;
    margin-bottom: 20rpx;
}

.history .delete{
     
    position: absolute;
    bottom: 10rpx;
    right: 15rpx;
    font-size: 36rpx;
}

  data: {
     
    placeholderContent:"", // placeholder 的内容
    hotList:[],  // 热搜榜数据
    searchContent:"" , // 用户输入的表单项数据
    searchList:[],  // 关键字迷糊匹配的数据
    historyList:[], // 搜索历史纪录
  },

  onLoad: function (options) {
     
    // 获取初始化数据
    this.getInitData();
    // 获取历史纪录
    this.getSearchHistory();
  },
 // 获取初始化的数据
  async getInitData() {
     
    let placeholderData = await request("/search/default");
    let hotListData = await request("/search/hot/detail");
    this.setData({
     
      placeholderContent:placeholderData.data.showKeyword,
      hotList:hotListData.data
    });
  },

  // 表单项数据发生变化时的回调
   handleInputChange(event) {
     
    this.setData({
     
      searchContent: event.detail.value.trim()
    });
     if(isSend === false){
     
       return;
     }
     isSend = false;
    // 知识点:函数节流
    setTimeout( ()=>{
     
      // 发请求获取关键字模糊匹配数据
     this.getSearchList();
      isSend = true;
    },300);
  },

  // 获取搜索数据的功能函数
  async getSearchList() {
     
    if(!this.data.searchContent){
     
      this.setData({
     
        searchList:[]
      })
      return;
    }
    let {
     searchContent,historyList} = this.data;
    let searchListData = await request("/search", {
     keywords: searchContent, limit: 10});
    this.setData({
     
      searchList: searchListData.result.songs
    });

    // 将搜索的关键字添加到搜索纪录中
    if(historyList.indexOf(searchContent) !== -1){
      // 已存在 删除
      historyList.splice(historyList.indexOf(searchContent));
    }
    historyList.unshift(searchContent); // 添加到前面
    this.setData({
     
      historyList:historyList
    });
    // 存在本地
    wx.setStorageSync("searchHistory",historyList);
  },

  // 获取本地历史纪录的功能函数
  getSearchHistory(){
     
    let historyList = wx.getStorageSync("searchHistory");
    if(historyList){
     
      this.setData({
     
        historyList:historyList
      })
    }
  },

  // 清空搜索内容回调
  clearSearchContent(event){
     
    this.setData({
     
      searchContent:"",
      searchList:[]
    })
  },

  // 删除搜索的历史纪录回调
  deleteSearchHistory(event){
     
    wx.showModal({
     
      content:"确定删除吗?",
      success:(res)=>{
     
        if(res.confirm){
     
          // 清空data中的 historyList
          this.setData({
     
            historyList:[]
          })
          // 移除本地的历史数据
          wx.removeStorageSync("searchHistory");
        }
      }
    })
  },


二、自定义模板使用

模板 文档

引用 文档
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第8张图片
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第9张图片

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第10张图片

实例

模板:

myTemplate.wxml


<template name="myTmp">
    <view>
        <view class="title">这是我自定义的模板view>
        <view>
            <view class="userName">用户名:{
    {username}}view>
            <view class="age">年龄:{
    {age}}view>
        view>
    view>
template>

myTemplate.wxss

.title{
     
    font-size: 80rpx;
    color: red;
}

引用:

other.wxml

<import src="/template/myTemplate/myTemplate"/>
<view class="otherContainer">
    
    <view>测试使用模板如下:view>
    <template is="myTmp" data="{
      {...person}}"/>
view>

other.wxss

/* 引入模板样式 */
@import "/template/myTemplate/myTemplate.wxss";

other.js

  data: {
     
    person:{
     
      username:"nzs",
      age:22
    }
  },

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第11张图片


三、获取用户登录凭证(唯一标识 openId)

获取登录凭证(code)
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第12张图片

登录流程时序

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第13张图片

服务器端:

github上:fly 和 jsonwebtoken库
npm install flyio
npm install jsonwebtoken

const Fly=require("flyio/src/node");
const jwt = require('jsonwebtoken');
const fly=new Fly;



// 注册获取用户唯一标识的接口
app.use('/getOpenId', async (req, res, next) => {
     
  let code = req.query.code;
  let appId = 'wx810e8b1fde386fde';
  let appSecret = '8bb909649da12002fba7a47f5ac3791b';
  let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${
       appId}&secret=${
       appSecret}&js_code=${
       code}&grant_type=authorization_code`
  // 发请求给微信服务器获取openId
  let result = await fly.get(url);
  let openId = JSON.parse(result.data).openid;
   console.log('openId', openId);
   // 自定义登录态
   let person = {
     
     username: 'nzs',
     age: 18,
     openId
   }
   // 对用户的数据进行加密,生成token返回给客户端
  let token = jwt.sign(person, 'atguigu');
  console.log(token);
  // 验证身份,反编译token
  let result2 = jwt.verify(token, 'atguigu');
  console.log(result2);
  res.send(token);
});

前端:

  // 获取用户唯一标识的回调
  handleGetOpenId(event) {
     
    // 1. 获取登录凭证
    wx.login({
     
      success: async (res) => {
     
        let code = res.code;
        // 2. 将登录的凭证发送给服务器
        let result = await request("/getOpenId", {
     code});
        console.log(result)
      }
    })
  },

四、分包

分包加载

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第14张图片

4.1 常规分包

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第15张图片
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第16张图片

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第17张图片

1. 创建文件夹,移动相应的文件

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第18张图片

2. 配置 app.json

  "subpackages": [
    {
     
      "root": "songPackage",
      "pages": [
        "pages/recommendSong/recommendSong",
        "pages/songDetail/songDetail"
      ]
    },
    {
     
      "root": "otherPackage",
      "pages": [
        "pages/other/other"
      ]
    }
  ]

3. 修改由于分包导致的路径错误

4. 完成
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第19张图片

4.2 独立分包

独立分包

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第20张图片
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第21张图片

3. 分包预加载

分包预加载

微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第22张图片
在这里插入图片描述
微信小程序【网易云音乐实战】(第六篇 歌曲搜索、自定义模板、分包)_第23张图片

  "preloadRule": {
     
    "pages/index/index": {
     
      "packages": ["songPackage","other"]
    }
  }

加载主包:

在这里插入图片描述


五、开发完成

你可能感兴趣的:(微信小程序开发,小程序)