赞
踩
与之前的不同之处在于,本次选择自动创建Router,如下:
注:发现在src目录下新增views文件夹。views文件夹和components文件夹都是存放vue页面文件的。区别在于凡是通过router/index.js路由文件引入的.vue文件放入view文件夹,其余放入components文件夹。
组件库地址:vant-contrib.gitee.io/vant/#/zh-CN/theme
执行npm i vant -S
推荐采用方式一引入组件,但是方式一过于麻烦,一般采用方式三。一次性引入vant的所有组件,导致打包的体积大,后期解决该问题。
将上述代码添加至main.js中
将下面代码复制至App.vue中,页面效果实现如上,说明组件引入成功。
- <van-button type="primary">主要按钮</van-button>
- <van-button type="info">信息按钮</van-button>
- <van-button type="default">默认按钮</van-button>
- <van-button type="warning">警告按钮</van-button>
- <van-button type="danger">危险按钮</van-button>
分别在views文件夹下新建Home和User文件夹,并建立对应的vue文件。
如上,App.vue中添加占位符和Tabbar。
- <template>
- <div>
- <router-view></router-view>
- <van-tabbar route>
- <van-tabbar-item to="/" icon="home-o">首页</van-tabbar-item>
- <van-tabbar-item to="/user" icon="user-o">我的</van-tabbar-item>
- </van-tabbar>
- </div>
- </template>
-
- <script>
- export default {
- name: 'App'
- }
- </script>
-
- <style lang="less" scoped>
-
- </style>
并在index.js中添加路由:
- import Vue from 'vue'
- import VueRouter from 'vue-router'
- import Home from '@/views/Home/Home.vue'
- import User from '@/views/User/User.vue'
-
- Vue.use(VueRouter)
-
- const routes = [
- { path: '/', component: Home },
- { path: '/user', component: User }
- ]
-
- const router = new VueRouter({
- routes
- })
-
- export default router
主要存在问题如下:
(1)导航栏固定,这里是通过fixed参数设置
(2)底下的h1字体会被顶部的导航栏和底部的Tabbar标签栏挡住,这里需要设置padding。padding的设置为顺时针,上,右,下,左
(3)样式设置采用审查元素查看,若不生效,可加/deep/
- <template>
- <div class="home-container">
- <van-nav-bar title="头条" fixed/>
- <h1>aaa</h1>
- <h1>bbb</h1>
- </div>
- </template>
-
- <script>
- export default {
- name: 'Home'
- }
- </script>
-
- <style lang="less" scoped>
- .home-container {
- padding: 46px 0 50px 0;
- .van-nav-bar {
- background-color: #007bff;
- }
- /deep/ .van-nav-bar__title {
- color: aliceblue;
- }
- }
- </style>
npm i axios -S安装
src目录下新建utils文件夹,并在utils文件夹下新建request.js文件,代码如下:
- import axios from 'axios'
- const request = axios.create({
- baseURL: 'https://www.escook.cn'
- })
-
- export default request
Home.vue中引入request.js文件,并定义方法发起axios请求,并在created方法中调用axios请求的方法。
- <template>
- <div class="home-container">
- <van-nav-bar title="头条" fixed/>
- </div>
- </template>
-
- <script>
- import request from '@/utils/request.js'
-
- export default {
- name: 'Home',
- data() {
- return {
- // 页码值
- page: 1,
- // 每页展示的数据条数
- limit: 10
- }
- },
- created() {
- this.initArticleList()
- },
- methods: {
- async initArticleList() {
- const { data: res } = await request.get('/articles', {
- params: {
- _page: this.page,
- _limit: this.limit
- }
- })
- console.log(res, res)
- }
- }
- }
- </script>
-
- <style lang="less" scoped>
- .home-container {
- padding: 46px 0 50px 0;
- .van-nav-bar {
- background-color: #007bff;
- }
- /deep/ .van-nav-bar__title {
- color: aliceblue;
- }
- }
- </style>
如上,若在我的页面也想调用axios请求'/articles'获取相关数据,则又需要在User.vue重新写一次axios.get....。为了提高可用性,创建API接口:
(1)在src下新建api文件夹,并在api文件夹下新建articleAPI.js文件。articleAPI.js代码如下:
- // 文章相关的接口,都封装到这个模块中
- import request from '@/utils/request.js'
-
- // 向外导出一个API函数
- export const getArticleListAPI = function(_page, _limit) {
- return request.get('/articles', {
- params: {
- _page,
- _limit
- }
- })
- }
(2)在Home.vue中引入articleAPI.js中的getArticleListAPI方法,并调用,代码如下:
注:方法引入时两侧需要加大括号
(1)在src/components文件夹下新建Article文件夹,并在其下新建ArticleInfo.vue组件。
- <template>
- <div>
- <van-cell>
- <!-- 标题区域的插槽 -->
- <template #title>
- <div class="title-box">
- <!-- 标题 -->
- <span>{{ title }}</span>
- <!-- 单张图片 -->
- <img :src="cover.images[0]" alt="" class="thumb" v-if="cover.type === 1">
- </div>
- <!-- 三张图片 -->
- <div class="thumb-box" v-if="cover.type === 3">
- <img :src="item" alt="" class="thumb" v-for="(item, index) in cover.images" :key="index">
- </div>
- </template>
- <!-- label区域的插槽 -->
- <template #label>
- <div class="label-box">
- <span>作者 {{ author }} {{ cmbCount }} 评论 发布日期 {{ time }}</span>
- <!-- 关闭按钮 -->
- <van-icon name="cross"></van-icon>
- </div>
- </template>
- </van-cell>
- </div>
- </template>
-
- <script>
- export default {
- name: 'ArticleInfo',
- props: {
- // 标题
- title: {
- type: String,
- default: ''
- },
- // 作者
- author: {
- type: String,
- default: ''
- },
- // 评论数
- cmbCount: {
- // 通过数组的形式,当前属性定义为多个可能的类型
- type: [String, Number],
- default: 0
- },
- // 发布时间
- time: {
- type: String,
- default: ''
- },
- // 封面的信息对象
- cover: {
- type: Object,
- default: function() {
- return { type: 0 }
- }
- }
- }
- }
- </script>
-
- <style lang="less" scoped>
- .label-box {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .thumb {
- 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>
(2)Home.vue中引入并使用ArticleInfo.vue组件
注:主要涉及的是props值的传递。
tips:(1)props值类型可设置为数组,定义为多个可能的类型
(2)父组件在设置属性值时,若原变量名为小驼峰式,最好修改为全部小写,中间加-。如下:
借助vant中展示组件中的List列表实现上拉加载更多的功能
(1)使用van-list包裹<ArticleInfo>
(2)data中声明:loading(默认true)、finished(默认false)两个属性
(3)onLoad方法定义(page++、请求数据)
(4)修改initArticleList方法(数据拼接、loading属性设置、finished属性设置)
修改后的Home.vue代码如下:
- <template>
- <div class="home-container">
- <van-nav-bar title="头条" fixed/>
- <van-list
- v-model="loading"
- :finished="finished"
- finished-text="没有更多了"
- @load="onLoad"
- >
- <ArticleInfo
- v-for="item in articleList"
- :key="item.art_id" :title="item.title"
- :author="item.aut_name"
- :cmbCount="item.comm_count"
- :time="item.pubdate"
- :cover="item.cover">
- </ArticleInfo>
- </van-list>
- </div>
- </template>
-
- <script>
- import { getArticleListAPI } from '@/api/articleAPI.js'
- import ArticleInfo from '@/components/Article/ArticleInfo.vue'
-
- export default {
- name: 'Home',
- components: {
- ArticleInfo
- },
- data() {
- return {
- // 页码值
- page: 1,
- // 每页展示的数据条数
- limit: 10,
- // 文章列表
- articleList: [],
- // 是否正在加载下一页数据,loadding为true,则不会反复触发load事件
- // 当下一页数据请求回来后,要记得把loading改为false
- // 初始值设为true,可以防止首次进入页面时调用load事件
- loading: true,
- // 所有数据是否加载完成
- finished: false
- }
- },
- created() {
- this.initArticleList()
- },
- methods: {
- async initArticleList() {
- const { data: res } = await getArticleListAPI(this.page, this.limit)
- // this.articleList=[旧数据,新数据]
- this.articleList = [...this.articleList, ...res]
- this.loading = false
-
- if (res.length === 0) {
- // 无下一页数据,finished设置为true
- this.finished = true
- }
- },
- onLoad() {
- console.log('ok')
- // 页码值加1
- this.page++
- // 重新请求数据
- this.initArticleList()
- }
- }
- }
- </script>
- <style lang="less" scoped>
- .home-container {
- padding: 46px 0 50px 0;
- .van-nav-bar {
- background-color: #007bff;
- }
- /deep/ .van-nav-bar__title {
- color: aliceblue;
- }
- }
- </style>
借助vant中展示组件中的List列表实现下拉刷新更多的功能.
(1)使用van-pull-refresh包裹van-list。并将其disabled属性设置为finished。也就是说当加载完成时,设置下拉刷新不可用
(2)data中定义refreshing属性,初始值设置为false
(3)定义onRefresh方法(page++、请求数据)
(4)修改initArticleList方法。(添加isRefresh入参、判断是下拉刷新还是上拉加载更多。前者是新数据在前,后者是新数据在后)
修改后的Home.vue如下:
- <template>
- <div class="home-container">
- <van-nav-bar title="头条" fixed/>
- <van-pull-refresh v-model="refreshing" :disabled="finished" @refresh="onRefresh">
- <van-list
- v-model="loading"
- :finished="finished"
- finished-text="没有更多了"
- @load="onLoad"
- >
- <ArticleInfo
- v-for="item in articleList"
- :key="item.art_id" :title="item.title"
- :author="item.aut_name"
- :cmbCount="item.comm_count"
- :time="item.pubdate"
- :cover="item.cover">
- </ArticleInfo>
- </van-list>
- </van-pull-refresh>
- </div>
- </template>
-
- <script>
- import { getArticleListAPI } from '@/api/articleAPI.js'
- import ArticleInfo from '@/components/Article/ArticleInfo.vue'
-
- export default {
- name: 'Home',
- components: {
- ArticleInfo
- },
- data() {
- return {
- // 页码值
- page: 1,
- // 每页展示的数据条数
- limit: 10,
- // 文章列表
- articleList: [],
- // 是否正在加载下一页数据,loading为true,则不会反复触发load事件
- // 当下一页数据请求回来后,要记得把loading改为false
- // 初始值设为true,可以防止首次进入页面时调用load事件
- loading: true,
- // 所有数据是否加载完成
- finished: false,
- // 是否正在加载下一页数据,refreshing为true,则不会反复触发onRefresh事件
- refreshing: false
- }
- },
- created() {
- this.initArticleList()
- },
- methods: {
- async initArticleList(isRefresh) {
- console.log('------')
- console.log(this.page)
- const { data: res } = await getArticleListAPI(this.page, this.limit)
- // isRefresh为true,证明是下拉刷新,新数据在前
- if (isRefresh) {
- // this.articleList=[新数据, 旧数据]
- this.articleList = [...res, ...this.articleList]
- this.loading = false
- } else {
- // this.articleList=[旧数据,新数据]
- this.articleList = [...this.articleList, ...res]
- this.loading = false
- }
-
- if (res.length === 0) {
- // 无下一页数据,finished设置为true
- this.finished = true
- }
- },
- onLoad() {
- // 页码值加1
- this.page++
- // 重新请求数据
- this.initArticleList(true)
- },
- onRefresh() {
- // 页码值加1
- this.page++
- // 重新请求数据
- this.initArticleList()
- }
- }
- }
- </script>
- <style lang="less" scoped>
- .home-container {
- padding: 46px 0 50px 0;
- .van-nav-bar {
- background-color: #007bff;
- }
- /deep/ .van-nav-bar__title {
- color: aliceblue;
- }
- }
- </style>
至此,购物车项目首页开发完成。
项目完整链接Headline | 黑马头条 - 移动端
背景:一个组件在多个页面需要引入,如NavBar 导航栏默认背景颜色为白色,如果要修改颜色,则每个页面都需要重复修改。为了解决该问题,提出定制主题的思路。
定制主题时,需要引入组件对应的 Less 样式文件,修改的是main.js文件。注释原引入index.css文件的行,修改引入文件为index.less文件。
- // import 'vant/lib/index.css'
- // 引入全部样式
- import 'vant/lib/index.less'
本项目为 vue-cli 搭建的项目,在 vue.config.js
中进行配置。根目录下新建 vue.config.js文件。
- // vue.config.js
- module.exports = {
- css: {
- loaderOptions: {
- less: {
- // 若 less-loader 版本小于 6.0,请移除 lessOptions 这一级,直接配置选项。
- lessOptions: {
- modifyVars: {
- // 直接覆盖变量
- 'text-color': '#111',
- 'border-color': '#eee',
- // 或者可以通过 less 文件覆盖(文件路径为绝对路径)
- hack: `true; @import "your-less-file-path.less";`,
- },
- },
- },
- },
- },
- };
less版本号查看:package.json搜索less-loader.查看发现小于6.0,移除
lessOptions 这一级
- // vue.config.js
- module.exports = {
- css: {
- loaderOptions: {
- less: {
- modifyVars: {
- // 直接覆盖变量
- // 'text-color': '#111',
- // 'border-color': '#eee',
- // 或者可以通过 less 文件覆盖(文件路径为绝对路径)
- // hack: 'true; @import "your-less-file-path.less";'
- }
- }
- }
- }
- }
查看vue官网,发现NavBar样式变量中控制背景颜色的变量如下:
方式一:直接覆盖变量。 修改vue.config.js的样式变量:(不采用该方式)
- // vue.config.js
- module.exports = {
- css: {
- loaderOptions: {
- less: {
- modifyVars: {
- // 直接覆盖变量
- 'nav-bar-background-color': 'red'
- }
- }
- }
- }
- }
修改后生效,以后NavBar默认颜色为红色。该方法的缺陷在于每次修改完都需要执行npm run serve重启服务器。采用方式二避免该问题。
方式二:新建theme.less文件,并在vue.config.js
中引入。(采用)
(1)在src下新建theme.less文件,并在文件中设置背景颜色和字体颜色
- @blue: #007bff;
-
- @nav-bar-background-color: @blue;
- @nav-bar-title-text-color: #ecf0f3;
(2)vue.config.js中引入
theme.less文件,如下:
- // vue.config.js
- const path = require('path')
- const themePath = path.join(__dirname, './src/theme.less')
- module.exports = {
- css: {
- loaderOptions: {
- less: {
- modifyVars: {
- // 或者可以通过 less 文件覆盖(文件路径为绝对路径)
- hack: `true; @import "${themePath}";`
- }
- }
- }
- }
- }
则通过修改theme.less文件保存后样式直接生效,不需再重启服务器。
vue.config.js
相关配置(1)publicPath设置为'/'或者''。打包后(npm run build)的dist/index.html支持file协议打开,也就是双击本地文件打开。默认是仅支持http协议的。
浏览器输入:D:/vueworkspace/toutiao/dist/index.html可直接访问。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。