vue实现好看的相册、图片网站

news2024/10/6 1:45:56

目录

一、效果图

1.项目访问地址

2.画虫官方效果图:

3.作者实现的效果图:

二、代码实现

1.项目结构截图

2.路由配置代码:

3. 头部+底部+主页面内容显示容器的代码

4.首页,即标签页的代码

三、项目启动说明

四、总结

 


一、效果图

仿照画虫的标签、摄影师和标签详情图片列表分别写了几个完整的页面,同时搭了整个网站的基础布局框架,仿照还原度1比1来实现,以下分别是画虫官方效果图和作者demo效果图。

1.项目访问地址

作者demo预览:点击访问

官方画虫:点击访问 

 

2.画虫官方效果图:

标签: 

标签图片列表:

 

 摄影师列表:

 

 3.作者实现的效果图:

 

 

二、代码实现

1.项目结构截图

components为登录注册组件窗口,page为网站布局实现,头部+底部+主页面内容显示容器,views存放具体功能页面,router为路由配置。

2.路由配置代码:

import Vue from 'vue'
import Router from 'vue-router'
import Layout from '@/page/index/index';
Vue.use(Router);


export const constantRoutes = [
    {
      path: '/index',
      component: Layout,
      redirect: '/explore',
      children: [{
        path: 'explore',
        name: '主页',
        component: () =>
          import( /* webpackChunkName: "views" */ '@/views/home/index'),
        children:[
          {
            path: '/explore',
            name: '首页-标签列表',
            component: () => import( '@/views/home/explore/index')
          },
          {
            path: '/photographer',
            name: '首页-摄影师列表',
            component: () => import( '@/views/home/photographer/index')
          }
        ]
      }]
    },
    {
      path: '/',
      name: '主页',
      redirect: '/index'
    },
    {
      path: '/tags',
      component: Layout,
      children: [{
        path: '',
        name: '标签',
        component: () =>
          import( /* webpackChunkName: "views" */ '@/views/tags/index'),
      }]
    },
  ];

const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({
    y: 0
  }),
  routes: constantRoutes
})

const router = createRouter()

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router

3. 头部+底部+主页面内容显示容器的代码

头部代码:

<template>
  <header class=" ">
    <nav class="nav-wide">
      <div class="nav-left">
        <a @click="homePage">
          <i class="nav-logo"></i>
        </a>
        <ul class="supnav-list">
          <li class="supnav-item"><a target="_blank" rel="noopener" class="">视频素材</a></li>
          <li class="supnav-item"><a class="" @click="homePage">首页</a></li>
          <li class="supnav-item"><a class="">社区</a></li>
          <li class="supnav-item"><a class="">活动</a></li>
          <li class="supnav-item"><a class="video_enter ">短视频</a><i class="subnav-red-tip-video" style="display: inline;"></i></li>
          <li class="supnav-item subnav-trigger tuchong_stock_enter_list">
            <a class="">发现<i class="supnav-red-tip"></i></a>
            <ul class="subnav-list">
              <li @click="homePage"><a>标签</a></li>
              <li><a>摄影师</a></li>
              <li><a>影像频道</a></li>
              <li><a>教程</a></li>
              <li><a>器材</a></li>
              <li class="tuchong_stock_enter"><a>正版图片下载</a><i class="subnav-red-tip" style="display: inline;"></i></li>
            </ul>
          </li>
          <li class="supnav-item subnav-trigger">
            <a class="">更多</a>
            <ul class="subnav-list">
              <li><a>创意图库</a></li>
              <li><a>下载APP</a></li>
              <li><a>商务合作</a></li>
            </ul>
          </li>
        </ul>
      </div>
      <div class="nav-right">
        <!-- <div class="nav-search">
            <i class="icon-search J-search-btn"></i>
            <form action="https://tuchong.com/search/all/" method="get">
                <input required class="search-input" type="text" name="query" placeholder="搜索" autocomplete="off">
            </form>
        </div> -->
        <!-- 非登录状态 -->
        <a class="nav-login login-trigger" @click="openLoginModal">登录</a>
        <a class="nav-register register-trigger" @click="openRegisterModal">注册</a>
      </div>
    </nav>

    <login-modal ref="loginModal"></login-modal>
    <register-modal ref="registerModal"></register-modal>
  </header>
</template>

<script>
  import { mapGetters } from 'vuex';
  import loginModal from "../../components/login_modal.vue";
  import registerModal from "../../components/register_modal.vue";

  export default {
    components: {
      loginModal,
      registerModal
    },
    data() {
      return {
        input: ''
      };
    },
    mounted() {
    },
    methods: {
      homePage(){
        this.$router.push({path: '/index'});
      },
      openLoginModal(){
        this.$refs.loginModal.openModal();
      },
      openRegisterModal(){
        this.$refs.registerModal.openModal();
      }
    }
  };
</script>

<style scoped>
  header {
    position: relative;
    min-width: 100%;
    height: 60px;
    margin: 0 auto;
    background-color: #000;
    font-weight: 500;
    z-index: 4;
  }
  header .nav-wide {
    min-width: 800px;
    /*max-width: 1880px;*/
    padding: 0 40px;
    margin: 0 auto;
  }
  header .nav-wide:after {
    display: block;
    clear: both;
    content: "";
    visibility: hidden;
    height: 0;
  }
  header .nav-wide .nav-left {
    float: left;
    height: 60px;
    font-size: 0;
  }
  .supnav-list .supnav-item>a:hover {
    color: #c99a05;
  }
  a {
    text-decoration: none;
    cursor: pointer;
    color: inherit;
  }
  header .nav-logo {
    display: inline-block;
    height: 22px;
    width: 80px;
    margin: 19px 0;
    background-image: url("../../../public/img/logo.png");
    -moz-background-size: 100% 100%;
    background-size: 100% 100%;
  }
  .nav-left .supnav-list {
    margin-left: 24px;
  }
  .supnav-list {
    display: inline-block;
    vertical-align: top;
    line-height: 1;
    font-size: 0;
  }
  ul, li, p {
    padding: 0;
    margin: 0;
    list-style: none;
  }
  .supnav-list .supnav-item {
    position: relative;
    display: inline-block;
    vertical-align: top;
    font-size: 14px;
  }
  ul, li, p {
    padding: 0;
    margin: 0;
    list-style: none;
  }
  .supnav-list .supnav-item a {
    display: block;
    line-height: 60px;
    color: #fff;
    font-weight: 500;
  }
  .nav-left .supnav-item>a {
    position: relative;
    padding: 0 12px;
    letter-spacing: 2px;
  }

  a {
    text-decoration: none;
    cursor: pointer;
    color: inherit;
  }
  .supnav-list .subnav-list {
    position: absolute;
    top: 59px;
    z-index: 1;
    left: 50%;
    display: none;
    width: 130px;
    margin-top: 1px;
    margin-left: -65px;
    line-height: 1;
    opacity: 0;
    -webkit-transition: opacity .5s ease;
    -moz-transition: opacity .5s ease;
    transition: opacity .5s ease;
    border-top: 10px solid rgba(0,0,0,0);
  }
  .supnav-list .subnav-list li:first-child {
    padding-top: 10px;
  }
  .supnav-list .subnav-list li {
    position: relative;
    background-color: #222;
  }
  .supnav-list .subnav-list li a {
    display: block;
    height: 40px;
    line-height: 40px;
    color: #fff;
    text-align: center;
  }
  .supnav-list .subnav-list li:last-child {
    padding-bottom: 10px;
  }
  header .nav-wide .nav-right {
    float: right;
    height: 60px;
    font-size: 0;
  }
  .nav-register, .nav-login {
    display: inline-block;
    margin-top: 12px;
    margin-left: 30px;
    height: 36px;
    line-height: 36px;
    color: #fff;
    font-size: 14px;
  }
  .nav-register {
    width: 100px;
    text-align: center;
    background-color: #c99a05;
  }
  .nav-register, .nav-login {
    display: inline-block;
    margin-top: 12px;
    margin-left: 30px;
    height: 36px;
    line-height: 36px;
    color: #fff;
    font-size: 14px;
  }
  header .nav-wide:after {
    display: block;
    clear: both;
    content: "";
    visibility: hidden;
    height: 0;
  }
  .supnav-list .subnav-list li::after {
    content: attr(data-count);
    position: absolute;
    left: 69px;
    top: 7px;
    padding: 0 4px;
    -webkit-border-radius: 7px;
    -moz-border-radius: 7px;
    border-radius: 7px;
    font-size: 12px;
    color: #fff;
    background-color: #e60905;
    line-height: 14px;
  }
  .supnav-list .subnav-list:after {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    width: 100%;
    height: 1px;
  }
  .nav-left .supnav-item i {
    display: none;
    position: absolute;
    top: 18px;
    right: 8px;
    width: 6px;
    height: 6px;
    -webkit-border-radius: 100%;
    -moz-border-radius: 100%;
    border-radius: 100%;
    background: red;
  }
  .supnav-list .subnav-trigger:hover .subnav-list {
    display: block;
    opacity: 1;
  }
  .supnav-list .subnav-list li a:hover {
    color: #c99a05;
  }
</style>

布局整合代码:

<template>
  <div class="page-scroll" style="width: 100%;height: 100%;overflow: auto;background: #f5f7f9;">
    <top></top>
    <router-view></router-view>
    <foot></foot>
    <el-backtop target=".page-scroll" :bottom="100">
      <div
        style="{
        height: 100%;
        width: 100%;
        background-color: gray;
        box-shadow: 0 0 6px rgba(0,0,0, .12);
        text-align: center;
        line-height: 40px;
        color: #FFFFFF;
      }"
      >
        UP
      </div>
    </el-backtop>
  </div>
</template>

<script>
  import top from "../top/index.vue";
  import foot from "../foot/index.vue";

  export default {
      components: {
        top,
        foot
      },
      name: "index",
      data() {
        return {
        };
      },
      mounted() {
      },
      methods: {
      }
    };
</script>

<style>
</style>

4.首页,即标签页的代码

<template>
  <main>
    <div class="container">
      <nav class="secondary-nav">
        <ul class="nav-list">
          <li v-for="(item,index) in menus" :key="index" :class="item.path===path?'active':''" @click="selTab(item)">
            <a target="_self" class="subnav-text">
              {{item.name}}
            </a>
          </li>
        </ul>
      </nav>
      <router-view></router-view>
    </div>
  </main>
</template>

<script>
  export default {
    data() {
      return {
        path:'/explore',
        menus: [
          {name:'标签',path:'/explore'},
          {name:'摄影师',path:'/photographer'},
          {name:'影像频道',path:'/videoChannel'},
          {name:'教程',path:'/course'},
          {name:'器材',path:'/equipment'}
        ]
      };
    },
    mounted() {
      let that = this;
      setInterval(function(){
        that.path = that.$router.currentRoute.path;
      },1000)
    },
    methods: {
      selTab(item){//标签切换
        this.path = item.path;
        this.$router.push({path: item.path});
      },
    }
  };
</script>

三、项目启动说明

项目是传统vue项目,实现需要安装node js,然后依次成功执行

npm install

npm run dev

顺利的话就这么简单,当然,遇到问题,直接call me(私聊作者获取帮助,作者一直在帮助了很多的小伙伴)

四、总结

第一步暂时到这里,关注作者,及时了解更多好项目!如果你也有好的案例,欢迎分享出来,说不定下一个demo就ta了。

还是那句话,获取源码或如需帮助,通过博客后面名片+作者即可!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android---MVC/MVP/MVVM的演进

目录 一个文件打天下 一个文件--->MVC MVC--->MVP MVP--->MVVM 6大设计原则 完整demo 我们通过"#字棋"游戏来展现MVC-->MVP-->MVVM 之间的演进 一个文件打天下 数据、视图以及逻辑都放在一个 class 里面。而一个 class 里最多 500 行代码&…

springboot 密码加密

首先介绍一下jasypt的使用方法 版本对应的坑 使用的时候还是遇到一个坑&#xff0c;就是jasypt的版本与spring boot版本存在对应情况。可以看到jasypt是区分java7和java8的&#xff0c;也存在依赖spring版本的情况。 自己尝试了一下 在使用jasypt-spring-boot-starter的前提…

优思学院|职场达人有什么晋升秘诀?

作为职场人士&#xff0c;升职晋升是我们一直追求的目标。然而&#xff0c;在职场中&#xff0c;竞争是激烈的&#xff0c;只有那些真正做到了突出表现和积极进取的人才能获得晋升机会。这里将分享七个职场达人的晋升秘诀&#xff0c;希望对那些正在寻找升职机会的人有所帮助。…

Python圈的普罗米修斯——一套近乎完善的监控系统

文章目录前言一、怎么采集监控数据&#xff1f;二、采集的数据结构与指标类型2.1 数据结构2.2 指标类型2.3 实例概念2.4.数据可视化2.5.应用前景总结前言 普罗米修斯(Prometheus)是一个SoundCloud公司开源的监控系统。当年&#xff0c;由于SoundCloud公司生产了太多的服务&…

SQL综合查询下

SQL综合查询下 目录SQL综合查询下18、查询所有人都选修了的课程号与课程名题目代码题解19、SQL查询&#xff1a;查询没有参加选课的学生。题目代码20、SQL查询&#xff1a;统计各门课程选修人数&#xff0c;要求输出课程代号&#xff0c;课程名&#xff0c;有成绩人数&#xff…

Express使用

文章目录Express 使用概述下载Express简单使用Express 生成器安装生成器使用基本路由使用路由获取请求数据获取路由参数处理请求体设置响应方式一&#xff1a;兼容http模块方式二&#xff1a;express的响应方法其他响应中间件简介全局中间件路由中间件静态资源中间件Router简介…

SkyWalking服务应用

文章目录SkyWalking服务应用案例准备案例实施1.部署Elasticsearch服务2.部署SkyWalking OAP服务3.部署SkyWalking UI服务4.搭建并启动应用商城服务SkyWalking服务应用 案例准备 节点规划 IP主机名节点192.168.100.10node-1Skywalking实验节点192.168.100.20mall商城搭建节点…

【毕业设计】基于程序化生成和音频检测的生态仿真与3D内容生成系统----程序化生成地形算法设计

2 程序化生成地形算法设计 2.1 地形曲线的生成 2.1.1 初始化高度场 struct Make2DGridPrimitive : INode {virtual void apply() override {size_t nx get_input<NumericObject>("nx")->get<int>();nx std::max(nx, (size_t)1);size_t ny has_in…

适配器详解

目录 1、适配器简介 2、函数对象适配器 ​编辑 3、函数指针作为适配器 ptr_fun ​编辑 4、类中的成员函数作为适配器 mem_fun_ref 5、取反适配器 5.1、not1 一元取反适配器 ​编辑 5.2、not2 二元取反适配器 1、适配器简介 适配器 为算法 提供接口目前的适配器最多能扩…

第一次习题总结

目录 求第K个数 求逆序对的数量 数的三次方根 一维前缀和 二维前缀和&#xff08;子矩阵的和&#xff09; 求第K个数 思路&#xff1a;用快速选择&#xff0c;时间复杂度为O(N) sl和sr是左边和右边数的个数&#xff0c;当k<sl&#xff0c;即倒数第K个数在左边范围内&#x…

【JY】减隔震设计思考:隔震篇

【写在前文】随着隔标颁布&#xff0c;国内外大大小小的地震的经历。越来越多的人重视减隔震分析和设计&#xff0c;也听到不少的疑惑声音&#xff0c;个人也有一点热点问题的感悟与大家分享。在个人看来&#xff1a;建筑减隔震&#xff1a;七分构造三分算&#xff01;特别注意…

[Netty源码] Netty轻量级对象池实现分析 (十三)

文章目录1.对象池技术介绍2.如何实现对象池3.Netty对象池实现分析3.1 Recycler3.2 Handler3.3 Stack3.4 WeakOrderQueue3.5 Link4.总结1.对象池技术介绍 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象, 类似线程池。对象池缓存了一些已经创建好的对象, 避免需要…

uni-app--》什么是uniapp?如何开发uniapp?

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

企业电子招投标采购系统源码——功能模块功能描述+数字化采购管理 采购招投标

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…

HTTP API接口设计规范

1. 所有请求使用POST方法 使用post&#xff0c;相对于get的query string&#xff0c;可以支持复杂类型的请求参数。例如日常项目中碰到get请求参数为数组类型的情况。 便于对请求和响应统一做签名、加密、日志等处理 2. URL规则 URL中只能含有英文&#xff0c;使用英文单词或…

Docker配置DL envs教程

Docker容器与镜像的区别 Docker镜像类似于虚拟镜像&#xff0c;是一个只读的文件&#xff0c;包括进程需要运行所需要的可执行文件、依赖软件、库文件、配置文件等等。 而容器则是基于镜像创建的进程&#xff0c;可以利用容器来运行应用。 总结来说&#xff0c;镜像只读&#…

贾俊平《统计学》第七章知识点总结及课后习题答案

一.考点归纳 参数估计的基本原理 1置信区间 &#xff08;1&#xff09;置信水平为95%的置信区间的含义&#xff1a;用某种方法构造的所有区间中有95%的区间包含总体参数的真值。&#xff08;2&#xff09;置信度愈高&#xff08;即估计的可靠性愈高&#xff09;&#xff0c;则…

ABeam News | ABeam Consulting 荣获『SAP AWARD OF EXCELLENCE 2023』奖项

ABeam Consulting株式会社&#xff08;总裁兼CEO 鸭居 达哉、东京都千代田区、以下简称为ABeam Consulting&#xff09;在SAP 日本株式会社&#xff08;董事长 铃木洋史、东京都千代田区、以下简称为SAP日本&#xff09;表彰优秀合作伙伴的颁奖『SAP AWARD OF EXCELLENCE 2023』…

c3p0报错java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

1. 问题由来 今天第一次学习到c3p0的时候&#xff0c;学习资料上使用的是0.9.1.2版本。 我偷懒使用的是0.9.2版本。但是运行的时候会报错&#xff1a; 网上搜索了一下这个错误&#xff0c;很多人说去安装mchange-commons-0.2.jar 这个包 但是我看学习资料上没有去另外安装这…

nodejs+vue 图书借阅管理系统

该系统的应用可以减少工作人员的劳动强度&#xff0c;提高工作效率与管理水平&#xff0c;具有很大的价值。它可以使图书这项借阅业务操作简单&#xff0c;成功率高&#xff0c;使网上图书管理系统的管理工作向一个新的层次迈进。本论文是以构建图书借阅为目标&#xff0c;使用…