从0到1项目开发-仿bilibili手机端

·  阅读 347

项目背景

仿bilibili手机端项目,本项目可以巩固vue基础知识,包括vue项目搭建、vue组件相关的知识、路由、前后端接口联调等,本项目使用使用vue-cli4.x脚手架创建项目。

  • 技术栈包括:vue2.6 + vant + axios + vue-router + ES6
  • 使用vw单位实现自适应布局
  • vue路由采用history模式和懒加载的方式
  • 使用阿里妈妈矢量图标库(iconfont)
  • 开源接口 http://112.74.99.5:3000/web/api

主要功能如下:

1、项目环境搭建

本节主要介绍如何搭建vue项目,前提检查一下node和npm是否已经安装好了。

第一步:安装好node和npm以后,

 全局安装 npm install --global vue-cli
复制代码

第二步:在终端 cd命令进入项目空间目录,例如我的目录Highcopy-Blibili,输入如下命令

vue init webpack test  (test是我的项目名称)
复制代码

然后会出现如下模式一问一答,根据自己的需要选择yes或者no 安装成功后会出现如下提示 cd tset进入项目中 npm run dev此时项目已经可以跑起来了

2、注册页面

1.前期工作:

  • 首先去除项目中默认的内容,helloWorld
  • 在src下新建views文件,这里主要写各个功能模块页面,
  • 首先在views文件下创建Register文件,Register文件目录下新建Register.vue文件。这个文件中主要做注册页面的开发

在router文件夹下创建register.js文件文件,这里主要利用的是路由懒加载,当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

export default {
    name:'register',
    path:'/register',
    component:()=>import('@/views/Register/Register.vue')
}
复制代码

路由文件夹下的index.js中引入 register。

import Vue from 'vue'
import Router from 'vue-router'
import  register from './register'

Vue.use(Router)
const routes=[
  register
]
const router=new Router({
  mode: 'history',
  routes
})

export default router
复制代码

2.页面开发

注册页面如下所示:可以分为title头部、输入框、按钮三个部分。 注册页面和登陆页面的头部布局相似,可抽取为组件。

我们可以将头部分为三个部分,标题在中间,左右预留为后期加入其他功能,我们可以利用flex布局。

头部主要代码如下:

本项目主要使用vw实现自适应布局,我们可以借助vscode的「px-to-vw」插件自动转换px到vw

  <template>
    <div> 
        <van-field 
                v-model="content" 
                :label="label" 
                :placeholder="placeholder" 
                :type="type"/>
    </div>
</template>
<script>
export default {
    props:['label','placeholder','type'],
    data(){
        return{
            content:''
        }
    },
    watch:{
        content(){
            this.content=this.content.trim()  //去掉空格
            this.$emit('contentWatch',this.content)
        }
    }
}
</script>
<style>

</style>
复制代码

Register.vue代码如下

<template>
    <div class="register"> 
      <login-top middleTop="bilibili"></login-top>
       <login-text 
           style="margin:4.167vw 0"
          label="姓名"
          placeholder="请输入用户名"
          @contentWatch="res=>registerInfo.name=res"
       
       />
       <login-text label="账号"
         placeholder="请输入账号"
           @contentWatch="res=>registerInfo.username=res"
       />
       <login-text label="密码"
         placeholder="请输入密码"
         type="password"
           @contentWatch="res=>registerInfo.password=res"
       />
       <login-btn btntext="注册" @TextClick="registerSubmit"></login-btn>
    </div>
</template>
<script>
import LoginTop from '@/components/Login/LoginTop.vue'
import LoginText from '@/components/Login/LoginText.vue'
import LoginBtn from '@/components/Login/LoginBtn.vue'
export default {
    data(){
        return{
            registerInfo:{
                name:'',
                username:'',
                password:''
            }
        }
    },
    components:{
        LoginTop,
        LoginText,
        LoginBtn
    },
    methods:{
        async registerSubmit(){
            let {name,username,password}=this.registerInfo
            let rulg = /^.{4,16}$/
            if(/^.{1,10}$/.test(name)&&rulg.test(username)&&rulg.test(password)){
               const res=await this.$http.post('/register',this.registerInfo)
               console.log(res)
               if(res.data.code==200){
                   this.$msg.fail('注册成功')
                       // 把返回的id的token存储到本地,localStorage是HTML5新加的特性
                    localStorage.setItem('id',res.data.id)
                    localStorage.setItem('token',res.data.objtoken)
                    console.log(localStorage)
                    // 注册成功以后,跳转到登陆页面,this.$router可以访问路由实例
                    setTimeout(() => {
                        this.$router.push('/userinfo')
                    }, 2000)
               }else if(res.data.code==302){
                   this.$msg.fail(res.data.msg)
               }

            }else{
                this.$msg.fail('格式不正确!')
            }
        },
    }
}
</script>
<style >

</style>
复制代码

知识点总结:

1、单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

2、props props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

3、watch watch 监听data中的数据变化。

4、当子组件需要与父组件进行通信时,比如我们将输入框抽出组件,需要将输入框的值抛给父组件register进行注册接口调用

输入框子组件LoginText
 <van-field 
     v-model="content" 
    :label="label" 
    :placeholder="placeholder" 
    :type="type"/>
    
子组件抛出输入框的值,第二个参数来提供抛出去的值
this.$emit('contentWatch',this.content)

父组件监听子组件抛出的contentWatch事件
 <login-text label="账号"
    placeholder="请输入账号"
    @contentWatch="res=>registerInfo.username=res"
/>
复制代码

5、HTML5 History 模式 本文用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

// 创建路由实例,传routes配置,对象属性名和属性值一样可以省略属性值
const router=new Router({
  mode: 'history',
  routes   //(缩写) 相当于 routes: routes
})
复制代码

6、路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

3、登陆页面

登陆页面可以复用注册页面,简单修改一下页面,去掉姓名输入框,给账号输入框增加padding,接口修改为/login。即可,复用代码高达80%以上,这就是组件的优点。

--------未完待续-------------------

分类:
阅读
标签:
分类:
阅读
标签:
收藏成功!
已添加到「」, 点击更改