Scenic Spot Details Module

Search page preliminary implementation and jump

Create search. vue in the views folder

<template> <! -- Search page --><div class="page-search">
      <! - the title -- -- >
      <van-nav-bar title="Search for attractions" />
      <! -- Search box -->
      <van-search
        v-model="value"
        show-action
        label="Attraction"
        placeholder="Please enter your search terms"
        @search="onSearch"
      >
        <template #action>
          <div @click="onSearch">search</div>
        </template>
      </van-search>
      <! List -- - >
      <div class="sight-list">
        <SightItem v-for="item in dataList"
          :key="item.id"
          :item="item"/>
      </div>
      <! - page - >
      <van-pagination v-model="currentPage" :total-items="totalItems" :items-per-page="perPage" />
      <! - the footer - >
      <TripFooter/>
  </div>
</template>
<script>
import SightItem from '@/components/common/ListSight'
import TripFooter from '@/components/common/Footer'
export default {
  data () {
    return {
      // Name of scenic spot
      sightName: ' '.// List of attractions
      dataList: [].// Total number of records
      totalItems: 0.// Current page number
      currentPage: 1.// The size of data per page
      perPage: 5}},components: {
    SightItem,
    TripFooter
  },
  methods: {
    onSearch () {
      console.log('onSearch')}}}</script>

Copy the code

Set the routing

The router under index. Js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '.. /views/Home.vue'
import Search from '.. /views/Search.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/'.name: 'Home'.component: Home
  },
  {
    path: '/search'.name: 'Search'.component: Search
  }
]

const router = new VueRouter({
  routes
})

export default router

Copy the code

Set the forward footer. vue of the route

<template> <! Bottom navigation --><div>
    <van-tabbar v-model="active" route>
      <van-tabbar-item name="home" icon="wap-home-o" :to="{name: 'Home'}">Home page</van-tabbar-item>
      <van-tabbar-item name="search" icon="search" :to="{name: 'Search'}">search</van-tabbar-item>
      <van-tabbar-item name="mine" icon="user-o">my</van-tabbar-item>
    </van-tabbar>
  </div>
</template>
<script>
export default {
  data () {
    return {
      active: 'home'}}}</script>

Copy the code

Remove unnecessary content from app.vue

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<style lang="less">
@import "./assets/style/common.less";
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983; }}}</style>

Copy the code

Effect:

Click the search button to jump to the search page

Attractions Details Page

Create the Sight folder under the Views folder

Create five new VUE files

List of sightList.vue

Sightdeatail.vue

Sightinfo.vue

The list of sightcomments.vue

Sightimage.vue picture under sightimage.sightimage.vue

Contents are for the time being

<template>
  <div class="page-sight-info"></div>
</template>
Copy the code

Add the routing

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '.. /views/Home.vue'
import Search from '.. /views/Search.vue'
import SightList from '.. /views/sight/SightList.vue'
import SightDeatail from '.. /views/sight/SightDeatail.vue'
import SightInfo from '.. /views/sight/SightInfo.vue'
import SightComment from '.. /views/sight/SightComment.vue'
import SightImage from '.. /views/sight/SightImage.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/'.name: 'Home'.component: Home
  },
  {
    path: '/search'.name: 'Search'.component: Search
  },
  // List of attractions
  {
    path: '/search/list'.name: 'SightList'.component: SightList
  },
  // Attractions details
  {
    path: '/sight/detail/:id'.name: 'SightDeatail'.component: SightDeatail
  },
  // Attractions introduction
  {
    path: '/sight/info/:id'.name: 'SightInfo'.component: SightInfo
  },
  // List of comments
  {
    path: '/sight/comment/:id'.name: 'SightComment'.component: SightComment
  },
  // The image below the scenic spot
  {
    path: '/sight/image/:id'.name: 'SightImage'.component: SightImage
  }
]

const router = new VueRouter({
  routes
})

export default router

Copy the code

Modify component jump

The A tag of ListSight. Vue in the common folder

<template>
  <router-link class="sight-item"
    :to="{ name: 'SightDeatail', params: { id: item.id }}">
    <img :src="item.main_img" alt="">
    <div class="right">
        <h5>{{ item.name }}</h5>
        <van-rate v-model="item.score" readonly/>
        <div class="tips">Ment_count} {{item.com} people comment on | 100% satisfaction</div>
        <div class="tips light">{{ item.province }} - {{ item.city }}</div>
        <div class="line-price">¥{{item.min_price}</div>
    </div>
  </router-link>
</template>
<script>
export default {
  props: ['item']}</script>
<style lang="less">
.sight-item {
  display: flex;
  margin-top: 10px;
  border-bottom: 1px solid #f6f6f6;
  img {
    width: 100px;
    height: 100px;
  }
  h5 {
    color: # 212121;
    font-size: 14px;
    padding: 5px 0;
    margin: 0;
  }
  .right {
    text-align: left;
    flex-grow: 1;
    text-align: left;
    justify-content: left;
    padding-left: 5px;
    position: relative;
  }
  .line-price {
    position: absolute;
    right: 10px;
    top: 20px;
    display: inline-block;
    color: #f50;
    font-size: 16px;
    font-weight: bold;
  }
  .tips {
    font-size: 12px;
    color: # 666;
  &.light {
    color: # 999; }}}</style>

Copy the code

Hot.vue

<template>
    <div class="home-hot-box">
        <! Navigation -- - >
        <van-cell
          icon="/static/home/hot/fire.png"
          title="Top recommendations"
          title-style="text-align:left"
          value="The Whole list."
          is-link
          :to="{name: 'SightList', Query: {name:' SightList'}}" />
        <! List -- - >
        <div class="box-main">
          <router-link class="hot-item"
            v-for="item in dataList"
            :key="item.id"
            :to="{ name: 'SightDeatail', params: { id: item.id }}">
              <div class="img">
                  <span></span>
                  <img :src="item.main_img" alt="">
              </div>
              <h5 class="van-ellipsis">{{ item.name }}</h5>
              <div class="line-price">
                  <span class="price">${{item. Min_price}}</span>since</div>
          </router-link>
        </div>
    </div>
</template>
<script>
import { ajax } from '@/utils/ajax'
import { SightApis } from '@/utils/apis'
export default {
  data () {
    return {
      dataList: []}},methods: {
    getDataList () {
      ajax.get(SightApis.sightListUrl, {
        params: {
          is_hot: 1
        }
      }).then(({ data }) = > {
        this.dataList = data.objects
      })
    }
  },
  created () {
    // Query interface data
    this.getDataList()
  }
}
</script>
<style lang="less">
.home-hot-box {
  padding: 0 10px;
  .van-cell {
    padding: 10px 0;
  }
  .box-main {
    width: 100%;
    display: flex;
    padding-top: 10px;
    overflow-x: scroll;
  }
  .hot-item {
    display: flex;
    flex-direction: column;
    width: 100px;
    margin-right: 10px;
    padding-bottom: 10px;

    .img {
      position: relative;

      span {
        position: absolute;
        left: 0;
        top: 0;
        display: inline-block;
        width: 42px;
        height: 20px;
        z-index: 10;
      }

      img {
        width: 100px;
        height: 100px; }}h5 {
      color: # 212121;
      padding: 2px 0;
      font-size: 12px;
      margin: 0;
    }

    .line-price {
      color: # 212121;
      font-size: 12px;
      .price {
        color: #f50;
        font-size: 13px; }} &:nth-child(1) .img span {
      background: url(/static/home/hot/top1.png) no-repeat;
      background-size: 100% auto;
    }
    &:nth-child(2) .img span {
      background: url(/static/home/hot/top2.png) no-repeat;
      background-size: 100% auto;
    }
    &:nth-child(3) .img span {
      background: url(/static/home/hot/top3.png) no-repeat;
      background-size: 100%auto; }}}</style>

Copy the code

Fine.vue

<template> <! -- Selected scenic spots --><div class="home-fine-box">
      <! Navigation -- - >
        <van-cell
          icon="location-o"
          title="Selected Attractions"
          title-style="text-align:left"
          value="The Whole list."
          is-link
          :to="{name: 'SightList', Query: {name:' SightList'}}"/>
        <! List -- - >
        <div class="box-main">
          <SightItem v-for="item in dataList"
          :key="item.id"
          :item="item"/>
        </div>
    </div>
</template>
<script>
import { ajax } from '@/utils/ajax'
import { SightApis } from '@/utils/apis'
import SightItem from '@/components/common/ListSight'
export default {
  components: {
    SightItem
  },
  data () {
    return {
      dataList: []}},methods: {
    getDataList () {
      ajax.get(SightApis.sightListUrl, {
        params: {
          is_top: 1
        }
      }).then(({ data }) = > {
        this.dataList = data.objects
      })
    }
  },
  created () {
    this.getDataList()
  }
}
</script>
<style lang="less">
.home-fine-box {
  padding: 0 10px;
  .van-cell {
    padding: 10px 0;
  }
  .box-main {
    padding-bottom: 50px; }}</style>

Copy the code

Effect of jump

Click on popular recommendations or selected attractions

Write a comment list component

Under Components

Create a New Sight folder

New CommentItem. Vue

<template> <! -- Each item on the comment list --><div class="comment-item-box">
    <div class="cmt-header">
      <div class="rate">
        <van-rate v-model="value"
        allow-half
        readonly
        void-icon="star"
        void-color="#eee"/>
      </div>
      <div class="user">* * * * * 2020-02-02</div>
    </div>
    <div class="cmt-content">
      <p>Comment on the content</p>
    </div>
    <! -- Image list -->
    <div class="cmt-imgs" @click="show=true">
      <van-image width="100" height="100" src="https://img.yzcdn.cn/vant/cat.jpeg"/>
    </div>
    <van-image-preview v-model="show" :images="images" @change="onChange">
      <template v-slot:index>Page {{index+1}}</template>
    </van-image-preview>
  </div>
</template>
<script>
export default {
  data () {
    return {
      show: false.index: 0.images: [
        'https://img.yzcdn.cn/vant/apple-1.jpg'.'https://img.yzcdn.cn/vant/apple-2.jpg'].value: 4.5}},methods: {
    onChange (index) {
      this.index = index
    }
  }
}
</script>
<style lang="less">
.comment-item-box {
  padding: 5px 10px;
  border-bottom: 1px solid #f6f6f6;

  .cmt-header {
    display: flex;
    justify-content: space-between;

    .user {
      font-size: 12px; }}.cmt-content {
    color: # 616161;
    padding: 5px 0;
    text-align: left;
    font-size: 12px;
    line-height: 2.0;
  }
  .cmt-imgs {
    padding: 5px;
    text-align: left;
    margin-right: 5px; }}</style>

Copy the code

Compile site details page content

SightDeatail.vue

<template> <! -- Details of scenic spots --><div class="pafe-sight-detail">
    <! -- Page header -->
    <van-nav-bar
    left-text="Return"
    left-arrow
    fixed
    @click-left="goBack"
    />
    <! A larger -- - >
    <div class="sight-banner">
      <van-image src="/static/home/hot/h1_max.jpg" width="100%" height="100%"/>
      <div class="tips">
        <router-link class="pic-sts" :to="{name: 'SightImage', params: {id: 123}}">
          <van-icon name="video-o" />
          <span>10 images</span>
        </router-link>
        <div class="title">Attractions title</div>
      </div>
    </div>
    <! -- Rating, scenic spot introduction -->
    <div class="sight-info">
      <div class="left">
        <div class="info-title">
          <strong>5 points</strong>
          <small>great</small>
        </div>
        <div class="info-tips">50 comments</div>
        <van-icon name="arrow" />
      </div>
      <div class="right">
        <div class="info-title">
          <span>Scenic spots</span>
        </div>
        <div class="info-tips">Opening hours, tips</div>
        <van-icon name="arrow" />
      </div>
    </div>
    <! -- Address information -->
    <van-cell title=Panyu Dadao, Panyu District, Guangdong City, Guangdong Province, China icon="location-o"
      is-link
      :title-style="{'text-align': 'left'}">
      <template #right-icon>
        <van-icon name="arrow" />
      </template>
    </van-cell>
    <! -- Ticket list -->
    <div class="sight-ticket">
      <van-cell title="Tickets" icon="bookmark-o" title-style="text-align:left"/>
      <div class="ticket-item" v-for="i in 5" :key="i">
        <div class="left">
          <div class="title">adult</div>
          <div class="tips">
            <van-icon name="clock-o" />
            <span>Reservations can be made before 7 o 'clock</span>
          </div>
          <div class="tags">
            <van-tag mark type="primary">Label 1</van-tag>
          </div>
        </div>
        <div class="right">
          <div class="price">
            <span>RMB</span>
            <strong>65</strong>
          </div>
          <router-link to="#">
            <van-button type="warning" size="small">reservation</van-button>
          </router-link>
        </div>
      </div>
    </div>
    <! -- User comments -->
    <div class="sight-comment">
      <van-cell title="Hot comments" icon="comment-o" title-style="text-align:left"/>
      <CommentItem/>
      <router-link class="link-more" :to="{name: 'SightComment', params: {id}}">To view more</router-link>
    </div>
  </div>
</template>
<script>
// Comment item component
import CommentItem from '@/components/sight/CommentItem'
export default {
  data () {
    return {
      id: ' '}},components: {
    CommentItem
  },
  methods: {
    goBack () {
      this.$router.go(-1)
    }
  },
  created () {
    this.id = this.$$route.params.id
  }
}
</script>
<style lang="less">
.pafe-sight-detail {
  .van-nav-bar {
    background-color: transparent; } // Large view of scenic spot.sight-banner{
    position: relative;
    .tips {
      position: absolute;
      left: 10px;
      bottom: 10px;
      font-size: 16px;
      color: #fff;

      .pic-sts {
        color: #fff;
        border-radius: 30px;
        font-size: 14px;
        background-color: rgba(0.0.0.0.4); }}} // Rating, scenic spot introduction.sight-info {
    display: flex;
    background-color: #fff;
    border-bottom: 1px solid #f6f6f6;

    & > div {
      flex: 1;
      position: relative;
    }
    .right {
      border-left: 1px solid #f6f6f6;
    }
    .info-title {
      text-align: left;
      padding: 5px 10px;
      strong {
        color: #ff8300; }}.info-tips {
      color: # 999;
      font-size: 12px;
      text-align: left;
      padding: 5px 10px;
    }
    .van-icon {
      position: absolute;
      right: 5px;
      top: 5px; }} // Ticket list.sight-ticket {
    margin-top: 10px;
    background-color: #fff;

    .ticket-item {
      display: flex;
      border-bottom: 1px solid #f6f6f6;
      padding-bottom: 10px;

      .left {
        flex: 1;
        text-align: left;
        padding: 5px 10px;

        .title {
          padding: 5px 0;
        }
        .tips {
          font-size: 12px; }}.right {
        width: 100px;
        .price {
          color: #ff9800;
          strong {
            font-size: 20px; }}}}} // List of comments.sight-comment {
    margin-top: 10px;
    background-color: #fff; } // See more.link-more {
    display: block;
    color: # 666;
    padding: 10px; }}</style>

Copy the code

Effect: