当前位置:   article > 正文

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

网易云搜索功能微信小程序

一、歌曲搜索

在这里插入图片描述

在这里插入图片描述

1. 界面数据获取

在这里插入图片描述

<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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
.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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  // 获取初始化的数据
  async getInitData() {
    let placeholderData = await request("/search/default");
    let hotListData = await request("/search/hot/detail");
    this.setData({
      placeholderContent:placeholderData.data.showKeyword,
      hotList:hotListData.data
    });
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2. 模糊匹配

在这里插入图片描述
在这里插入图片描述

数据节流:每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
    });
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

3. 歌曲搜索

在这里插入图片描述

    <!--  搜索内容展示  -->
    <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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
/* 热搜榜的样式*/
.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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

4. 历史纪录

在这里插入图片描述

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
/* 搜索历史样式 */
.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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  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");
        }
      }
    })
  },

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

二、自定义模板使用

模板 文档

引用 文档
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

实例

模板:

myTemplate.wxml

<!-- 定义 模板 -->
<template name="myTmp">
    <view>
        <view class="title">这是我自定义的模板</view>
        <view>
            <view class="userName">用户名:{{username}}</view>
            <view class="age">年龄:{{age}}</view>
        </view>
    </view>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

myTemplate.wxss

.title{
    font-size: 80rpx;
    color: red;
}
  • 1
  • 2
  • 3
  • 4

引用:

other.wxml

<import src="/template/myTemplate/myTemplate"/>
<view class="otherContainer">
    <!--  测试使用模板  -->
    <view>测试使用模板如下:</view>
    <template is="myTmp" data="{{...person}}"/>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

other.wxss

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

other.js

  data: {
    person:{
      username:"nzs",
      age:22
    }
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述


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

获取登录凭证(code)
在这里插入图片描述

登录流程时序

在这里插入图片描述

服务器端:

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);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

前端:

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

四、分包

分包加载

在这里插入图片描述

4.1 常规分包

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

2. 配置 app.json

  "subpackages": [
    {
      "root": "songPackage",
      "pages": [
        "pages/recommendSong/recommendSong",
        "pages/songDetail/songDetail"
      ]
    },
    {
      "root": "otherPackage",
      "pages": [
        "pages/other/other"
      ]
    }
  ]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

4. 完成
在这里插入图片描述

4.2 独立分包

独立分包

在这里插入图片描述
在这里插入图片描述

3. 分包预加载

分包预加载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  "preloadRule": {
    "pages/index/index": {
      "packages": ["songPackage","other"]
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5

加载主包:

在这里插入图片描述


五、开发完成

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/616315
推荐阅读
相关标签