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

一、歌曲搜索

在这里插入图片描述

在这里插入图片描述

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>

.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. 模糊匹配

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

数据节流:每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. 歌曲搜索

在这里插入图片描述

    <!--  搜索内容展示  -->
    <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. 历史纪录

在这里插入图片描述

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");
        }
      }
    })
  },


二、自定义模板使用

模板 文档

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

在这里插入图片描述

实例

模板:

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

在这里插入图片描述


三、获取用户登录凭证(唯一标识 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);
});

前端:

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

四、分包

分包加载

在这里插入图片描述

4.1 常规分包

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

在这里插入图片描述

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

在这里插入图片描述

2. 配置 app.json

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

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

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

4.2 独立分包

独立分包

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

3. 分包预加载

分包预加载

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

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

加载主包:

在这里插入图片描述


五、开发完成

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45021180/article/details/113254731