Vue学习基础版汇总-项目构建V7.0.0

vue项目构建之头条

一、初始化项目

1.1、创建项目

  • 【构建】创建项目命令
vue create toutiao
  • 【组件】选择手动安装组件,如下:
    Vue学习基础版汇总-项目构建V7.0.0_第1张图片

  • 【选择】选择安装的组件,如下:
    Vue学习基础版汇总-项目构建V7.0.0_第2张图片

  • 【vue版本】选择2.0(目前项目版本为2.0的)

  • 【路由模式】选择路由模式,目前选择#开头的(因为#开头的代表hash值的路由,适配各种浏览器)
    Vue学习基础版汇总-项目构建V7.0.0_第3张图片

  • 【样式处理器】选择Less
    Vue学习基础版汇总-项目构建V7.0.0_第4张图片

  • 【语法规范】选择ESLint的标准规范
    Vue学习基础版汇总-项目构建V7.0.0_第5张图片

  • 【格式】选择检查格式配置:选择保存时检查格式,如下:
    Vue学习基础版汇总-项目构建V7.0.0_第6张图片

  • 【配置】选择配置文件保存方式:选择独立存储,如下:
    Vue学习基础版汇总-项目构建V7.0.0_第7张图片

  • 【记录】是否保存此次创建项目作为模板记录,可选可不选
    Vue学习基础版汇总-项目构建V7.0.0_第8张图片

1.2、安装和配置组件库

  • 【组件库】安装本次项目需要的vue组件库,Vant组件库
  • 【官网】
vant-contrib.gitee.io/vant/#/zh-CN/theme
  • 【安装】安装Vant库,从官网拿到适合当前项目的命令执行即可:

    npm i vant@latest-v2
    
  • 【配置】在项目中配置vant组件库,根据官网选择最合适的配置方式,目前项目选择第三种:导入所有

    • 在项目main.js中新增如下配置:
    • Vant 支持一次性导入所有组件,引入所有组件会增加代码包体积,因此不推荐这种做法。
    import Vue from 'vue';
    import Vant from 'vant';
    import 'vant/lib/index.css';
    //给vue安装vant插件
    Vue.use(Vant);
    
  • 【使用】此时可以再官网选择想使用的组件直接在vue页面中引入:

<van-button type="primary">主要按钮van-button>
<van-button type="success">成功按钮van-button>
<van-button type="default">默认按钮van-button>
<van-button type="warning">警告按钮van-button>
<van-button type="danger">危险按钮van-button>

1.3、安装axios包

  • 【安装】发送请求的包,命令如下:
npm i axios -S
  • 【配置】配置全局的请求模块,操作步骤如下:

    • 【创建】创建utils模块,新建request.js用于配置全局的请求路径,配置第一个请求路径内容如下:
    // 导入axios包
    import axios from 'axios'
    
    // 创建请求实例
    const request = axios.create({
      // 指定请求的根路径
      baseURL: 'https://www.escook.cn'
    })
    
    // 暴露实例request
    export default request
    

二、封装统一request

2.1、创建request文件

  • 【创建】在src目录下:新建utils包,在utils包内新建request.js文件
  • 【配置】编写request内容,配置axios请求和api地址,如下:
// 导入axios包
import axios from 'axios'
// 创建请求实例
const request = axios.create({
  // 指定请求的根路径
  baseURL: 'http://127.0.0.1:8081'
})
// 暴露实例request
export default request

2.2、创建统一API模块

  • 【创建】在src目录下:新建api包,在api包内新建各模块的api的独立js文件
    • 例如建立:文章模块api的js:articleAPI.js
  • 【配置】编写文章模块js的内容,编写一个api接口内容如下:
// 文章相关的 API 接口,都封装到这个模块中
// 导入request对象
import request from '@/utils/request.js'
// 向外按需输出一个API 接口
export const getArticleListAPI = function (page, limit) {
  console.log('调用了 getArticleListAPI 函数')
  return request.get('/article/getArticle', {
    params: {
      pageIndex: page,
      pageSize: limit
    }
  })    
}
  • 【使用】在vue组件中使用api接口,如下:
//----------------第一步:
// 按需导入 API 接口
import { getArticleListAPI } from '@/api/articleAPI.js'
//----------------第二步:
 // 在需要的地方使用导入的api接口:传入入参,得到返回值
const { data: result } = await getArticleListAPI(this.page, this.limit)
console.log(result.data)

三、自定义less样式文件

3.1、覆盖Vant组件样式

  • 【第一步】在src目录下新建theme.less文件
  • 【第二步】在vue.config.js中引入样式文件,引入方式如下:
//--------第一步:引入文件-----------------------
// webpack 在进行打包的时候,底层用到了node.js
// 因此,在vue.config.js配置文件中,可以导入并使用node.js中的核心模块
const path = require('path')
const themePath = path.join(__dirname, './src/theme.less')
//--------第一步:加载样式文件-----------------------
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  css: {
    loaderOptions: {
      less: {
        // 若 less-loader 版本小于 6.0,请移除 lessOptions 这一级,直接配置选项。
        lessOptions: {
          modifyVars: {
            // 或者可以通过 less 文件覆盖(文件路径为绝对路径)
            hack: `true; @import "${themePath}";`
          }
        }
      }
    }
  }
})
  • 【第三步】编写需要覆盖的样式文件内容:

    //第一步:定义自己的值
    @blue:#035f46;
    @size:22px;
    //第二步:覆盖官方值
    @nav-bar-background-color:@blue;
    @nav-bar-arrow-size:@size;
    @nav-bar-title-font-size:@size;
    

四、项目实现功能

4.1、加载数据

  • 请求后端服务器得到数据展示,如下图:
    Vue学习基础版汇总-项目构建V7.0.0_第9张图片

4.2、下拉请求加载数据

  • 下拉页面向后端发送请求,加载最新数据,如下图:
    Vue学习基础版汇总-项目构建V7.0.0_第10张图片

4.3、上拉请求加载数据

  • 上拉页面向后端发送请求,加载数据,如下图:
    Vue学习基础版汇总-项目构建V7.0.0_第11张图片

五、核心代码

5.1、主页面代码

<template>
  <div class="home-container">
    
    <van-nav-bar title="有谱么"  :fixed="true"/>

    
    <van-pull-refresh v-model="isLoading" :disabled="finished" @refresh="onRefresh">
      
      <van-list :loading="loading" :finished="finished" finished-text="您撸到底了" @load="onLoad">
        
        
        <ArticleInfo v-for="item in artList" :key="item.artId"
                    :title="item.title"
                    :autName="item.autName"
                    :commCount="item.commCount"
                    :pubDate="item.pubDate"
                    :artType="item.type"
                    :images="item.images">
        ArticleInfo>
      van-list>
    van-pull-refresh>
  div>
template>

<script>
// 导入 request请求实例
// import request from '@/utils/request.js'
// 按需导入 API 接口
import { getArticleListAPI } from '@/api/articleAPI.js'
// 导入articleInfo组件
import ArticleInfo from '@/components/article/Article.vue'

export default {
  // 组件注册区
  components: {
    ArticleInfo
  },
  // 组件名称
  name: 'Home',
  // 数据区
  data () {
    return {
      // 当前页码
      page: 1,
      // 每页显示条数
      limit: 5,
      // 文章内容list
      artList: [],
      // 是否正在加载下一页数据 如果loading 为 true ,则不会反复触发load 事件
      // 当每次数据请求完毕后,一定要修改loading值为false
      loading: true,
      // 所有数据是否加载完毕了,如果没有更多数据了,一定要把finished改成true
      finished: false,
      // 定义是否刷新下拉
      isLoading: false

    }
  },
  created () {
    // vue被创建时执行
    this.initArticleList()
  },
  // 方法区
  methods: {
    // 【请求数据接口】 封装获取文庄列表数据
    async initArticleList (isRefresh) {
      // 发起get请求
      // const { data: res } = await request.get('/article/getArticle', {
      //   params: {
      //     pageIndex: this.page,
      //     pageSize: this.limit
      //   }
      // })
      // console.log(res.data)
      console.log('----------------------------')
      // 使用导入的api接口
      const { data: result } = await getArticleListAPI(this.page, this.limit)
      // console.log(result.data)
      // this.artList = result.data.list

      if (isRefresh) {
        // 下拉刷新-数据存储方式:this.artList = [新数据在前,旧数据在前]
        this.artList = [...result.data.list, ...this.artList]
        // 下拉刷新-设置下拉刷新值为 false
        this.isLoading = false
      } else {
        // 上拉刷新-
        // 如果是上拉加载更多数据,那么已经加载的所有数据都应该放到artList集合中,实现方式:
        // this.artList = [旧数据在前,新数据在后]   这种模式存储
        this.artList = [...this.artList, ...result.data.list]
        // 上拉刷新-第一次数据请求完毕,修改下拉加载状态为false,允许触发下拉加载事件
        this.loading = false
      }
      // 验证本次请求返回数据条数是否小于limit,是:则说明数据已经加载完毕,设置finished值为true
      if (result.data.list.length === 0) {
        console.log('数据已经全部加载···')
        this.finished = true
      }
      console.log(this.artList)
      console.log(this.loading)
    },
    // 【上拉页面加载数据】只要 onLoad 被调用,就应该请求下一页数据
    onLoad () {
      console.log('onLoad被触发了')
      // 触发页码值+1
      this.page++
      // 在调用一次数据请求接口
      this.initArticleList()
    },
    // 【下拉页面加载数据】下拉刷新处理函数
    onRefresh () {
      console.log('触发了下拉刷新onRefresh函数')
      // 下拉刷新-第一件事:页码++
      this.page++
      // 下拉刷新-第二件事:重新初始化数据接口
      this.initArticleList(true)
      console.log(this.isLoading)
    }
  }
}
script>

<style lang="less" scoped>
.home-container{
  padding: 46px 0px 50px 0px;
  // .van-nav-bar{
  //   background-color: #035f46;
  // }
  //修改标题字体颜色,直接覆盖不生效,则加/deep/ van-nav-bar__title
  /deep/ .van-nav-bar__title{
    color: white;
  }
}
style>

5.2、数据展示组件代码

<template>
  <div>
    <van-cell>
      
      <template #title>
        <div class="title-box">
          
          <span>{{ title }}span>
          
          <img :src="images[0]" alt="" class="thumb" v-if="artType === 1" />
        div>
        
        <div class="thumb-box" v-if="artType === 3">
          <img v-for="(item,i) in images" :key="i" :src="item" alt="" class="thumb">
        div>
      template>
      
      <template #label>
        <div class="label-box">
          <span>作者:{{autName}}    {{ commCount }} 评论    发布日期:{{pubDate}}span>
          
          <van-icon name="cross" />
        div>
      template>
    van-cell>
  div>
template>

<script>
export default {
  name: 'ArticleInfo',
  // 父组件传值到子组件使用自定义属性传值
  props: {
    // 标题
    title: {
      type: String,
      default: '1'
    },
    // 作者
    autName: {
      type: String,
      default: ''
    },
    // 评论数
    commCount: {
      type: [String, Number],
      default: ''
    },
    // 发布日期
    pubDate: {
      type: String,
      default: ''
    },
    // 文章类型 type
    artType: {
      type: [String, Number],
      default: ''
    },
    // 图片地址
    images: []
  }
}
script>

<style lang="less" scoped>
.label-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.thumb {
  // 矩形黄金比例:0.618
  width: 113px;
  height: 70px;
  background-color: #f8f8f8;
  object-fit: cover;
}

.title-box {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.thumb-box {
  display: flex;
  justify-content: space-between;
}
style>>

5.3、APP主页面架构

<template>
  <div>
      
      <router-view>router-view>
      
    <van-tabbar route>
      <van-tabbar-item icon="home-o" to="/">首页van-tabbar-item>
      <van-tabbar-item icon="user-o" to="/user">我的van-tabbar-item>
    van-tabbar>
  div>
template>

<script>
export default {
  name: 'App'
}
script>
<style lang="less" scoped>
style>

六、源码地址如下

https://download.csdn.net/download/qq_42445425/85676928
  • 使用VScode打开运行:npm run serve 即可运行

你可能感兴趣的:(Web-Douglas,vue.js,学习,javascript)