某条

92 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

一。要求

制作头条页面,并通过 Vue 完成数据初始化,实现 axios 请求数据并绑定新闻数据、点击新闻列表跳转到

详情页、利用路由功能传递每一条新闻对应 id 并在详情页展示。根据提供的图片、文本等素材,通过 vue-cli

脚手架工具完成项目搭建,并根据页面创建对应组件,还原页面效果。

(1)、在 components 目录下创建 Header.vue 组件、News.vue 组件;

2)、在 src 目录先新建 page 文件夹,在 page 文件夹下新建 Home.vue 组件、Detail.vue 组件;

3)、img 文件夹(提供)、data 文件夹(提供)放在 static 目录下;

1.App组件

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

 <script>
      export default {
        name: "App",
      components: {},
     };
    </script>

  <style>
   * {
           margin: 0;
     padding: 0;
                     list-style: none;
         box-sizing: border-box;

   }

  </style>
  
  

2.Home组件

                           <template>
  <div class="home">
      <Header />
         <News />
<router-view></router-view>
       </div>
   </template>

   <script>
 import Header from "../components/Header.vue";
      import News from "../components/News.vue";

  export default {
     components: { Header, News },

  };
   </script>

  <style>
 </style>
 
 
 

3.Header组件

                                     <template>
<div class="header">
           <div class="top">
   <div><img src="../../public/image/index/message.png" /></div>
  <div class="top_a">
    <p><img src="/image/index/wap_logo.png" /></p>
    <p><img src="../../public/image/index/titlebar_refresh.png" /></p>
  </div>

  <div><img src="/image/index/search_normal.png" /></div>
</div>
</div>
 </template>

  <script>
  export default {};
  </script>

  <style scoped >
   .top {
 display: flex;
 width: 100vw;
background: #cf3b3f;
     height: 3.125rem;
justify-content: space-around;
      align-items: center;
 }
 .top > div {
 height: 3.125rem;
display: flex;
 align-items: center;
  }
 .top_a p:nth-of-type(1) img {
   width: 4.375rem;
   height: 1.5rem;
 }
   .top_a p:nth-of-type(2) img {
  width: 1.125rem;
   height: 1.125rem;
   margin-left: 5px;

     }
   img {
   width: 1.5rem;
   height: 24px;
   }
        </style>
        
        

4.News组件

(1)、新建 News.vue 组件之后,在 Home.vue 组件中引入新闻列表组件使用

2)、使用 npm 安装 axios 库,并使用 get 方法请求 data 文件中的 data.json 中的数据;

3)、分析 data.json 中的数据,并利用 HTML+CSS 进行页面布局,使用 v-for 遍历解析数据并展示;

4)、使用 router-link 包裹每一条新闻列表,动态绑定 to 属性跳转到详情页面,并且传递每一条新闻

列表对应的 id 值

                  <template>
     <div class="news">
        <router-link
  
  v-for="(item, index) in list"
  :key="item.id"
  :to="`/news/${item.id}`"
>
  <div class="news_aa">
    <div class="content">
      <div>{{ item.title }}</div>
      <div class="news_a">
        <p>置顶</p>
        <p>{{ item.from }}</p>
        <p>{{ item.commentLength }}</p>
      </div>
    </div>
    <div>
      <img v-show="item.img !== ''" :src="item.img" alt="" />
    </div>
  </div>
</router-link>

<router-view></router-view>
   </div>
   </template>

    <script>
   import axios from "axios";
    export default {
     data() {
        return {
  list: [],
  number: 0,
};
     },
       mounted() {
this.loadlist();
   },
     methods: {
  async loadlist() {
  let { data } = await axios.get("/data/data.json");
  this.list = data;
  console.log(this.list);
},
 },
   };
       </script>

   <style scoped>
   .news_aa div:nth-of-type(2) {
    display: flex;
   }

  .news_aa {
    display: flex;
    justify-content: space-between;
     border-bottom: 1px solid #ccc;
    margin: 0 0.3125rem;
    align-items: center;
    padding: 0.3125rem;
   }

  img {
    width: 7.5rem;
   }
   .content div:nth-of-type(1) {
   margin-bottom: 0.3125rem;
           }
.news p {
   font-size: 12px;
            margin-right: 0.3125rem;
     color: #ccc;
          }
   .news_a p:nth-of-type(1) {
    color: red;
    border: 1px solid red;
     border-radius: 0.3125rem;
  }
  a {
     text-decoration: none;
     color: black;
    }
     </style>
     
     
     

5。Detail组件

(1)、Detail.vue 组件需要在 router 文件夹下注册使用,路由的配置中的 path 需要设置为'/detail/:id',这

样才能接收列表组件传递的每一条新闻的 id

2)、利用 HTML+CSS 进行页面布局,先根据列表页的数据和详情页截图把详情页布局出来

3)、页面数据可以直接把提供的 data.json 导入到详情页中,拿到所有的数据之后,利用列表页传递

的 id,调用 filter 方法,把对应的那条新闻筛选出来进行数据绑定到页面中去进行展示

         <template>
   <div class="tail">
 <div v-for="(item, index) in lists" :key="index">
  <h2>{{ item.title }}</h2>
  <div class="top">
    <div>
      <img src="../../public/image/datails/author.jpg" alt="" />
    </div>
    <div class="contents">
      <div>
        {{ item.from }}
      </div>
      <div class="from_a">
        <p>
          {{ item.time | filterTime }}
        </p>
        <p>{{ item.commentLength }}评论</p>
        <p>关注</p>
      </div>
    </div>
  </div>
  <div class="content_a" v-html="item.content"></div>
</div>
</div>
    </template>
  
  <script>
   import axios from "axios";
         export default {
    props: ["id"],
     data() {
       return {
  lists: [],
     };
    },
    mounted() {
axios.get("/data/data.json").then(({ data }) => {
  this.lists = data.filter((r) => r.id == this.id);
//   let a=data.find(r=>r.id==this.id)
//   console.log(a);
});
        },
      filters: {
         filterTime(val) {
  let froms = +new Date(val);
  let tows = +new Date();
  let date = (tows - froms) / 1000;
  let ye = (date / 60 / 60 ).toFixed(2) + "小时前";
  return ye;
},
 },
};
  </script>

   <style scoped>
  .tail {
margin: 0 14px;
    text-align: left;
   }
   img {
    width: 20px;
      height: 20px;
border-radius: 50%;
      }
     .top {
     display: flex;
   height: 3.4375rem;
    align-items: center;
 }
   .from_a {
    display: flex;
   align-items: center;
   }
  .contents {
      margin-left: 8px;
      }
   .contents > div:nth-of-type(1) {
     font-size: 14px;
    font-weight: bold;
    }
  .contents > div:nth-of-type(2) p {
    font-size: 12px;
     margin-right: 10px;
  }
    .contents > div:nth-of-type(2) p:nth-of-type(1) {
    color: #ccc;
   }
  .contents > div:nth-of-type(2) p:nth-of-type(2) {
       color: red;
    }
   .contents > div:nth-of-type(2) p:nth-of-type(3) {
    color: white;
    background: red;
    padding: 4px 10px;
    }
</style>

6.路由配置

                     import Vue from "vue";

  import VueRouter from "vue-router";

   Vue.use(VueRouter);

   let routes = [
            {
path: "/",
name: "home",
component: () => import("../page/Home.vue"),
     },

       {
path: "/news/:id",
name: "news",
props: true,
component: () => import("../page/Detail.vue"),
props: true,
 },
  ];
const router = new VueRouter({
  routes,
});

 export default router;