用uni-app写一个简单的豆瓣电影微信小程序

如题,这个项目是用 uni-app 写的,只有一个列表页,没有详情页。

截图

首页

选择标签


搜索列表

封装api

./api/api

// 定义基本URL
const BASE_URL = 'https://movie.douban.com/j/';

// 封装请求
const request = (url, method, data) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: BASE_URL + url,
      method: method,
      data: data || {},
      header: {
        Accept: "application/json",
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      success(request) {
        resolve(request.data)
      },
      fail(error) {
        reject(error)
      },
      complete(res) {
        console.log('loading completed');
      }
    })
  })
}

// 扩展 promise 的 finally 方法
Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value => {
      P.resolve(callback()).then(() => value);
    },
    reason => {
      P.resolve(callback()).then( () => { throw reason });
    }
  );
}

// 导出接口
module.exports = {
  // 标签列表
  search_tags(params){
    return request('search_tags','get', params);
  },
  // 电影列表
  search_subjects(params){
    return request('search_subjects','get', params);
  },
  // 搜索列表
  subject_suggest(params){
    return request('subject_suggest','get', params);
  }
}
接口名 URL Method Params
获取标签列表 https://movie.douban.com/j/search_tags GET { type: ‘movie’, source: ‘index’ }
获取电影列表 https://movie.douban.com/j/search_subjects GET { type: ‘movie’, tag: ‘热门’, page_limit: 9, page_start: 0 }
搜索电影列表 https://movie.douban.com/j/subject_suggest GET { q: ‘沙’ }

只用到这三个接口。

列表都能找到接口,但是始终找不到详情的接口,豆瓣电影官网的详情页面是服务端渲染整个页面(目前为止),所以先不做详情页,原本也只是随便做的demo。

./pages/index/index 首页代码

<template>
  <view class="container">
    
    
    <view class="section">
      
      <SearchInput @search="getSubjectSuggest" />
      
      <uni-list v-if="suggest_list.length>0">
        <uni-list-item 
          v-for="item in suggest_list"
          :key="item.id"
          :title="item.title" 
          :note="item.sub_title" 
          :thumb="item.img"
          thumb-size="lg" 
          :rightText="item.year"
        ></uni-list-item>
      </uni-list>

      <view class="uni-list">
        <view class="uni-list-cell">
          <view class="uni-list-cell-left"> 当前选择 </view>
          <view class="uni-list-cell-db">
            <picker 
              @change="bindPickerChange" 
              :value="tags_key" 
              :range="tags"
            >
              <view class="uni-input">
                {{tags[tags_key]}}
              </view>
            </picker>
          </view>
        </view>
      </view>
      
    </view>
    
    
    
    <view>
      <scroll-view 
        :scroll-top="scrollTop" 
        scroll-y="true" 
        class="scroll-Y" 
        @scrolltoupper="upper" 
        @scrolltolower="lower"
        @scroll="scroll"
      >
        <uni-grid :column="3" :showBorder="false">
          <uni-grid-item 
            class="uni-grid-item"
            style="height: 200px;"
            v-for="item in list"
            :key="item.id"
          >
            <view class="uni-grid-item-view" @click="goDetail(item)">
              <image 
                style="width: 100%; height: 100px; background-color: #eee;" 
                mode="scaleToFill" 
                :src="item.cover"
                @error="imageError"
              ></image>
              <text class="">{{item.title}}</text>
              <uni-rate :size="10" :max="5" :value="item.rate/2" /> {{item.rate}}
            </view>
          </uni-grid-item>
        </uni-grid>
      </scroll-view>
    </view>
  </view>
</template>

<script>
  import { 
    search_tags,      // 标签列表
    search_subjects,  // 电影列表
    subject_suggest   // 搜索列表
  } from '../../api/api';
  import { SearchInput } from '../../components/SearchInput.vue';
  export default {
    name:'index',
	data() {
	  return {
        tags:[],
        tags_key: 0,
        scrollTop: 0,
        old: {
          scrollTop: 0
        },
        list: [],
        key: 0,
        page_start: 0,
        
        suggest_list: []
	  }
	},
    components:{
      SearchInput
    },
    async onShow() {
      wx.showLoading({
        title: 'Now Loading...',
      });
      this.page_start = 0;
      let res = await search_tags({
        type: 'movie',
        source: 'index'
      });
      console.log(JSON.stringify(res));
      this.tags = res.tags;
      this.search_subjects();
      wx.hideLoading();
      
    },
	methods: {
      inject(e){
        console.log(e);
      },
      setActive(){ 
        
      },
      
      // 改变标签
      bindPickerChange(e) {
        console.log('picker发送选择改变,携带值为', e.detail.value);
        this.tags_key = e.detail.value;
        this.page_start = 0;
        this.search_subjects();
      },
      upper(e) {
        console.log(e)
      },
      lower(e) {
        console.log(e)
      },
      scroll(e) {
        console.log(e)
        this.old.scrollTop = e.detail.scrollTop
      },
      imageError(e) {
        console.error('image发生error事件,携带值为' + e.detail.errMsg)
      },
      
      // 跳转到详情页
      goDetail(item){
        console.log(uni.navigateTo);
        uni.navigateTo({
          url: `/pages/detail/detail?id=${item.id}`
        });
      },
      
      // 获取搜索建议列表
      async getSubjectSuggest(q){
        let res = await subject_suggest({q});
        console.log(JSON.stringify(res));
        this.suggest_list = res;
      },
      
      // 获取电影列表
      async search_subjects(){
        let res = await search_subjects({
          type: 'movie',
          tag: this.tags[this.tags_key],
          page_limit: 9,
          page_start: this.page_start++
        });
        console.log(JSON.stringify(res));
        this.list = res.subjects;
      }
	}
  }
</script>

<style lang="scss" scoped>
  $rem: 37.5;
  .container {
		padding: 20rem/$rem;
		font-size: 16rem/$rem;
    
    .section{
      margin-bottom: 30rem/$rem;
    }
    .uni-grid-item{
      .uni-grid-item-view{
        padding: 5rem/$rem;
      }
    }
  }
</style>

./components/SearchInput 用到了一个搜索框组件

<template>
  <view>
    <uni-search-bar @confirm="search" @input="input"></uni-search-bar>
  </view>
</template>

<script>
  export default {
    name: "SearchInput",
    data() {
      return {
        
      };
    },
    async onShow() {
      
    },
    methods:{
      search(val){
        console.log(val);
        this.$emit('search',val.value);
      },
      input(val){
        console.log(val);
        if(val===''){
          this.$emit('search','');
        }
      }
    }
  }
</script>

只是这么多内容,可以把自己的 AppId 放到 manifest.json 中。也可以扩展内容,做一个电视剧列表,相关接口在豆瓣电影官网都能找到。

项目地址:https://codechina.csdn.net/sonicwater1/uni-app-demo

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>