首页开发

首先开发首页(home 页面),页面 UI 效果图如图12-4所示。

image 2024 02 26 17 11 20 147
Figure 1. 图12-4 首页效果图

在 view 下新建 home.vue 组件,其核心代码如下:

setup(){
    let nowplayList = ref([]) // 正在热映
    let recentplayList = ref([])// 最近热映
    let rankList = ref([])// 榜单
    // 将数据进行分组
    let toArray = (data)=>{
        let n = 10 // 10个一组
        let len = data.length
        let num = len % n == 0 ? len/n : Math.floor(len/n)+1
        let res = []
        for (var i = 0 ; i < num ; i++) {
            res.push(data.slice(i*n,i*n+n))// 构造2维数组
        }
        return res
    }
    // 请求数据
    onMounted(async () => {
        ...
    });
    return {
        nowplayList,
        recentplayList,
        rankList
    }
}

其主要业务逻辑如下:

  • 定义响应式对象来存储页面所需要的数据。

  • 在 onMounted 方法中请求后台接口,获取数据并赋值。

  • 对数据进行加工,例如最近热映的电影需要 10 个一组,以方便渲染。

轮播翻页组件

在 components 下创建 slider.vue 组件,其核心代码如下:

<div class="scoll-wrap">
    <div class="scroll-content" ref="scrollContent">
      <slot></slot> // 插槽
    </div>
    <div class="control">
      <div class="left" @click="prePage"></div>
      <div class="right" @click="nextPage"></div>
    </div>
</div>
setup(props, context) {
    const {proxy} = getCurrentInstance() // 获取上下文对象
    let translateX = 0
    const unit = 675 // (115 + 10 + 10)*5 宽度+左右边距
    const prePage = () => {
      translateX = translateX - unit
      if (translateX <= 0) { // 当翻页到最左边时,不可再翻
        translateX = 0
      }

      proxy.$refs.scrollContent.style.transform = 'translateX(-' + translateX + 'px)' // 利用translateX设置位移
    }
    const nextPage = () => {
      translateX = translateX + unit
      let maxwidth = proxy.$refs.scrollContent.clientWidth // 获取框体宽度
      if (translateX >= maxwidth) { // 当翻页到最右边时,不可再翻
        translateX = Math.max(maxwidth - unit, translateX - unit)
      }

      proxy.$refs.scrollContent.style.transform = 'translateX(-' + translateX + 'px)' // 利用 translateX 设置位移
    }

    return {
      prePage,
      nextPage
    };
},

其主要业务逻辑如下:

  • 利用插槽 <slot> 将子组件的内容展示出来。

  • 添加两个翻页按钮,绑定事件进行切换翻页操作。

  • 利用 CSS 3 的 transform:translateX 属性结合过渡动画进行位移操作,并判断临界条件。

搜索框组件

搜索框作为常驻在页面顶部的组件,属于公共组件,所以在公共组件 components 目录下新建 navheader 组件,其核心代码如下:

<div class="nav-wapper">
    <div class="nav-header">
      <div class="nav-logo" @click="$router.push('/')"></div>
      <div class="nav-search">
        <input id="inp" placeholder="搜索电影、电视剧、综艺、影人" v-model.trim="searchText"/>
        <div class="search-btn" @click="goSearch"></div>
      </div>
      <div v-if="user.nickname" class="nickname">
        {{ user.nickname }},<a>退出</a>
      </div>
      <div class="nickname" v-else @click="$router.push('/login')">
        请登陆
      </div>
    </div>
</div>
  setup(props, context) {
    const store = Vuex.useStore()
    const router = useRoute()
    // 从 Vuex 的 store 中获取用户数据
    const user = computed(() => store.state.userInfo);
    const searchText = ref('');

    watchEffect(() => { // 接收 url 参数上的搜索词数据
      searchText.value = router.query.searchText
    })

    return {
      user,
      searchText
    }
  },

其主要业务逻辑如下:

  • 搜索框 input 和用户登录入口界面的内容。

  • 搜索框 input 的数据需要借助 watchEffect 方法动态地从 Vue Router 的 searchText 参数上获取。

  • 通过 Vuex 的 store 中的 userInfo 数据判断用户是否登录,从而展示不同的逻辑。