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

目录

一、效果图

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了。

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Talk预告 | 浙江大学特聘研究员廖依伊:面向自动驾驶仿真平台的神经渲染

本期为TechBeat人工智能社区第477期线上Talk&#xff01; 北京时间3月1日(周三)20:00&#xff0c;浙江大学信电学院特聘研究员——廖依伊的Talk将准时在TechBeat人工智能社区开播&#xff01; 她与大家分享的主题是: “面向自动驾驶仿真平台的神经渲染”&#xff0c;届时将探…

Vue.js 2.0 实例

构造器 每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的&#xff1a; var vm new Vue({// 选项 }) 虽然没有完全遵循 MVVM 模式&#xff0c; Vue 的设计无疑受到了它的启发。因此在文档中经常会使用 vm 这个变量名表示 Vue 实例。 在实例化 Vue 时&…

爱智EdgerOS之深入解析在爱智应用中如何使用Socket.IO轻松实现双向通信

一、什么是 Socket.IO&#xff1f; Socket.IO 是一个基于事件通信的实时应用程序框架&#xff0c;它在即时通讯、通知和消息推送&#xff0c;实时分析等场景中有广泛的应用。Socket.IO 包括两个部分&#xff1a; 在 Server 端的模块&#xff08;JSRE 已提供了 socket.io 模块&…

密码和生物识别技术可以阻止不良行为者

网络安全漏洞是一个持续的威胁&#xff0c;而且只会越来越严重。2021 年&#xff0c;45% 的美国公司遭受了与凭证泄露相关的数据泄露&#xff0c;4200 万人因身份盗用和相关欺诈遭受了超过 500 亿美元的总价值损失&#xff0c;并且在过去五年中&#xff0c;超过5 亿个凭证和密码…

AI绘画王炸功能Control Net安装教程

原文&#xff1a;AI绘画王炸功能Control Net安装教程 - 知乎 AI绘画&#xff0c;最近两大王炸功能出圈了。 一个就是超真实超细节的美女图片&#xff0c;已经快和照片无异了&#xff0c;甚至有人用AI绘画的“女仆照片”开始招募游艇会了&#xff0c;具体教程可以查看Lora这篇…

多元时间序列 | GRU门控循环单元多变量时间序列预测(Matlab完整程序)

多元时间序列 | GRU门控循环单元多变量时间序列预测(Matlab完整程序) 目录 多元时间序列 | GRU门控循环单元多变量时间序列预测(Matlab完整程序)预测结果评价指标基本介绍程序设计参考资料预测结果 评价指标 训练集数据的R2为:0.98197 测试集数据的R2为:0.97913 训练集数…

Nacos配置管理

Nacos配置管理1 Nacos配置管理1.1 统一配置管理1.1.1 在nacos中添加配置文件1.1.2 从微服务拉取配置1.2 配置热更新1.2.1 方式一1.2.2 方式二1.3 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&am…

Minikube安装、运行

1.Minikube是什么 本地的k8s集群&#xff0c;方便开发者学习k8s。 2.安装的前提条件 2个CPU货以上。2G内存或以上。20G磁盘或以上。可以链接互联网。安装docker&#xff08;官网说或者一个虚拟环境&#xff0c;这个不考虑&#xff09;。 3.官网地址 minikube start | minik…

进程状态初始

目录 &#xff1a; 1.状态的认识 2.具体状态的学习 3.验证 R S T Z&#xff08;引出孤儿进程&#xff09;状态 4.前台、后台运行程序 -------------------------------------------------------------------------------------------------------------- 1.状态的认识 进程…

前列腺癌论文笔记

名词解释 MRF: 磁共振指纹打印技术( MR Fingerprinting)是近几年发展起来的最新磁共振技术&#xff0c;以一种全新的方法对数据进行采集、后处理和实现可视化。 MRF使用一种伪随机采集方法&#xff0c;取代了过去为获得个体感兴趣的参数特征而使用重复系列数据的采集方法&…

python零基础实现基于旋转特征的自监督学习(二)——在resnet18模型下应用自监督学习

系列文章目录 基于旋转特征的自监督学习&#xff08;一&#xff09;——算法思路解析以及数据集读取 基于旋转特征的自监督学习&#xff08;二&#xff09;——在resnet18模型下应用自监督学习 模型搭建与训练系列文章目录前言resNet18Residualresnet_blockresNet18select_mod…

apache配置与应用

构建虚拟 Web 主机 apache虚拟web主机指在同一台服务器运行多个web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务器&#xff0c;因此被称为web主机&#xff0c;可以充分利用服务器的硬件资源&#xff0c;大大降低网站的构建成本 http服务支持三种虚拟主机类型 …

Spring Cloud之Consul服务治理实战

目录 1、Consul是什么 1.1概念 1.2 Consul下载 1.3 Consul启动 2、Consul使用场景 3、Consul优势 4、Consul架构及原理 4.1 整体架构图 4.2 通讯机制 4.3 健康检测 4.4如何保证数据一致性 5、搭建Consul环境 5.1 本地Consul搭建 5.2 集群Consul搭建 5.2.1 安装C…

VUE使用el-ui的form表单输入框批量搜索<VUE专栏三>

针对form表单的输入框单号批量查询&#xff0c;这里用换行符进行分割&#xff0c;注意v-model不要使用.trim 前端代码&#xff1a; <el-form-item label"SKU编码:" prop"prodNumbers"><el-input type"textarea" :rows"4" pla…

Spring 之依赖注入底层原理

Spring 框架作为 Java 开发中最流行的框架之一&#xff0c;其核心特性之一就是依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;。在Spring中&#xff0c;依赖注入是通过 IOC 容器&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;来实现…

电动牙刷语音芯片,音乐播放ic选型?

牙医认为每天刷牙两次对于口腔健康至关重要。但是有些人会因为不良的刷牙习惯而受害&#xff0c;比如刷牙时间不够长。而刷牙不当会导致牙齿出现问题&#xff0c;例如蛀牙、污渍和口臭。 为了保护牙齿健康&#xff0c;很多家庭开始尝试使用电动牙刷。电动牙刷通过嗡嗡地振动消…

springboot2.7及springboot3中自动配置的变化

大家在面试中问到springboot如何实现的自动配置 诶&#xff0c;不要傻背错八股了&#xff0c;以往 入口类上的SpringBootApplication注解引入EnableAutoConfiguration&#xff0c;再 Import({AutoConfigurationImportSelector.class}) &#xff0c;其中代码实现根据META-INF/sp…

实战案例|聚焦攻击面管理,腾讯安全威胁情报守护头部券商资产安全

金融“活水”润泽千行百业&#xff0c;对金融客户来说&#xff0c;由于业务场景存在特殊性和复杂性&#xff0c;网络安全必然是一场“持久战”。如何在事前做好安全部署&#xff0c;构建威胁情报分析的防护体系至为重要&#xff0c;实现更为精准、高效的动态防御。 客户名片 …

Java实现打印杨辉三角形,向左、右偏的平行四边形这三个图形代码程序

目录 前言 一、打印杨辉三角形 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 二、向左偏的平行四边形 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 三、向右偏的平行四边形 1.1运行流程&#xff08;思想&#xff09; 1.2代…

一个评测模型+10个问题,摸清盘古、通义千问、文心一言、ChatGPT的“家底”!...

‍数据智能产业创新服务媒体——聚焦数智 改变商业毫无疑问&#xff0c;全球已经在进行大模型的军备竞赛了&#xff0c;“有头有脸”的科技巨头都不会缺席。昨天阿里巴巴内测了通义千问&#xff0c;今天华为公布了盘古大模型的最新进展。不久前百度公布了文心一言、360也公布了…