构建第一个Vue项目

之前的文章已经提到了,如何配置Vue的开发环境了,现在开始做一个简单的项目,主要就是介绍怎么使用组件、路由以及通信等,大家就不要吐槽UI和样式的问题。

     

这是我的src目录,component是放公用组件的,page是页面,static是放静态资源文件

 

首先先来看看main.js

我们需要在这里引入我们需要用到的组件和库

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'   /* 这里是引入vue文件 */
import App from './App'  /* 这里是引入同目录下的App.vue模块 */
import router from './router'  /* 这里是引入vue的路由 */

import VueResource from 'vue-resource'
Vue.use(VueResource)

/* eslint-disable no-new */
new Vue({
  el: '#app',  /* 定义作用范围就是index.html里的id为app的范围内 */
  router,    /* 引入路由 */
  components: { App },  /* 注册引入的组件App.vue */
  template: '<App/>'   /* 给Vue实例初始一个App组件作为template 相当于默认组件 */
})

 

我们先来做头部的导航栏,创建一个headerNav.vue

<template lang="html">
  <div class="header">
    <span class="back-btn" @click="goBack()">←</span>
    <h6 class="header-name" v-text="hName"></h6>
  </div>
</template>
<script>
export default {
  return {
    hName:'首页',
  },
  methods:{
    goBack(){
      history.back(-1);
    }
  },
  
}
</script>
<style lang="css" scoped>/*  scoped的意思是这里的样式只对当前页面有效不会影响其他页面,还有可以设置lang="scss"就是支持css预编译,也就是支持sass或者less  */
.header{ width: 100%; height: 2rem; padding: 0 2.6rem; position: fixed; left: 0; top: 0; background-color: #42b983; color: #ffffff; } .header-name { width: 80%; margin: 0 10%; text-align: center; line-height: 2rem; font-size: .8rem; } .back-btn{ display: inline-block; position: absolute; top: 0; left: 0; width: 2.6rem; height: 2rem; line-height: 2rem; font-size: 1.1rem; text-align: center; }
</style>

 

有头就要有尾,footerNav.vue

<template lang="html">
  <div class="footer">
    <ul class="footer-con b2 ui-transition">
      <li class="g1">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
  </div>
</template>
<script>
export default {
  data(){
    
  },
}
</script>
<style lang="css">
  .footer { height: 2rem; width: 100%; position: fixed; bottom: 0; left: 0; background-color: #fff; } .footer::before{ content: ''; display: block; position: absolute;top: 0;left: 0; width: 100%;height: 1px; background: #e0e0e0; } .footer-con li { float: left; width: 25%; height: 2rem; line-height: 2rem; font-size: .8rem; text-align: center; -webkit-transition: ease 0.25s; -moz-transition: ease 0.25s; -ms-transition: ease 0.25s; -o-transition: ease 0.25s; transition: ease 0.25s; } .footer-con li:active { background-color: rgb(248, 248, 248); } .footer-con:after { content: ''; display: block; clear: both; width: 0; height: 0; }
</style>

 

接下来就是App.vue

<template lang="html">
  <div class="container">
    <!--  引入的header组件 -->
    <headerNav></headerNav>
    <div class="content">
      <router-view></router-view>  <!-- 这里是展示来自路由页面数据的 -->
    </div>
    <!--  引入的footer组件 -->
    <footerNav></footerNav>
  </div>
</template>
<script>
/* 引用组件 */
import headerNav from "@/components/headerNav";
import footerNav from "@/components/footerNav";

export default {
  data() {
    /* 这里是数据,注意数据一定要放data中然后用return返回 */
    return {
    };
  },
  components: {
    headerNav,
    footerNav,
  },
  mounted(){},
};
</script>

<style lang="css">
blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}html{overflow-y:scroll}body{font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;font-size:14px;-webkit-font-smoothing:antialiased;background-color:#fff;position:relative}ul,ol{list-style:none}a{text-decoration:none;}em{font-style:normal}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;outline:0 none} a{color: inherit} .clear::after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.clear{*zoom:1} .ui-transition { -webkit-transition: ease 0.35s; -moz-transition: ease 0.35s; -ms-transition: ease 0.35s; -o-transition: ease 0.35s; transition: ease 0.35s; } .b1{color: #646262;}.b2{color: #555454;} .o1{color: #f16f47;} .r1{color: rgb(233, 10, 103)} .g1{color: #42b983} .bl{color: #2c3e50;} body{background-color: rgba(233, 233, 233, .5);} .container { width: 100%; padding: 2rem 0; position: relative; }
</style>

现在应该就能看到一个只有头尾,中间空白的页面

所以我们要开始丰富内容,movieList.vue

<template lang="html">
  <ul class="cont-ul clear">
    <li class="cont-li b1" v-for="item in movieList">
      <div class="img-con">
        <img class="movie-img" :src="item.images.large">
      </div>
      <div class="movie-msg clear">
        <p class="movie-name">{{item.title}}</p>
        <p class="movie-price r1">
        <span>评分 </span>{{item.rating.average}}</p>
      </div>
    </li>
  </ul>
</template>

<script>

export default {
  data() {
    return {
      movieList: [],
    };
  },
  mounted() {
    // 这个是vue的钩子函数,当new Vue()实例创建完毕后执行的函数,关于vue的生命周期,可以去官网查看详情
    // 这里我用的是豆瓣的一个公共接口
    this.$http
      .jsonp("https://api.douban.com/v2/movie/top250?count=10")
      .then(res => {
        this.movieList = res.data.subjects;
        res = null;
      })
      .catch(error => {
        console.log("http error:" + error);
      });
  },
};
</script>

<style lang="css" scoped>
.cont-ul { padding: 0.5rem 0.5rem 0 0.5rem; } .cont-li { margin-bottom: 0.4rem; width: calc(50% - 0.2rem); float: left; overflow: hidden; border-radius: 4px; background: #ffffff; box-shadow: 1px 1px 4px rgba(131, 131, 131, 0.5); } .cont-li:nth-child(2n-1) { margin-right: 0.4rem; } .img-con { height: 12rem; overflow: hidden; } .movie-img { float: left; width: 100%; } .movie-msg { width: 100%; padding: 0.3rem 0.5rem; } .movie-name { line-height: 1.2rem; font-size: 0.8rem; } .movie-price { text-align: right; line-height: 1rem; font-size: 0.7rem; font-weight: 400; } .movie-price span { font-size: 0.5rem; }
</style>

 

好了,现在我们就把第一个页面做出来了,很简单对吧。接下来就是详情页了,但是在这之前我们还需要定义跳转方式,详细请看我另一篇文章→ Vue 路由跳转方式 和 路由跳转时传参

下面就是修改后的movieList.vue,增加了goToInfo的跳转方法

<template lang="html">
  <ul class="cont-ul clear">
    <li class="cont-li b1" v-for="item in movieList" @click="goToInfo(item)">
        <div class="img-con">
          <img class="movie-img" :src="item.images.large">
        </div>
        <div class="movie-msg clear">
          <p class="movie-name">{{item.title}}</p>
          <p class="movie-price r1">
            <span>评分 </span>{{item.rating.average}}</p>
        </div>
    </li>
  </ul>
</template>

<script>

export default {
  data() {
    return {
      movieList: [],
    };
  },
  mounted() {
    // 这个是vue的钩子函数,当new Vue()实例创建完毕后执行的函数,关于vue的生命周期,可以去官网查看详情
    // 这里我用的是豆瓣的一个公共接口
    this.$http
      .jsonp("https://api.douban.com/v2/movie/top250?count=10")
      .then(res => {
        this.movieList = res.data.subjects;
        console.log(res.data.subjects);
        res = null;
      })
      .catch(error => {
        console.log("http error" + error);
      });
  },
  methods:{
    goToInfo(info){
      //这里因为我想把整个对象传给详情页,所以使用的是session
      sessionStorage.setItem('movieInfo',JSON.stringify(info));
      this.$router.push({
        path:'/movieInfo',  //路径
        name:'movieInfo', //配置路由时的name
      });
    }
  }
};
</script>

其实正常来说,我们应该是在movieList.vue 通过路由query的方式把id传给详情页,但是因为没有接口的原因所以我用了session

 

然后就是详情页了,movieInfo.vue

<template lang="html">
    <div class="info-con" v-if="info">
        <img class="movie-img" :src="info.images.large">
        <p class="movie-name">{{info.title}}<span>{{' ('+info.year+')'}}</span></p>
        <p>
          类型:
          <span v-for="genre in info.genres">{{genre+' / '}}</span>
        </p>
        <p class="o1">评分:{{info.rating.average}}</p>
    </div>
</template>

<script>

export default {
  data() {
    return {
        info:'',
    };
  },
  mounted() {
    let info = sessionStorage.getItem('movieInfo')||0;
    if(info){
      this.info = JSON.parse(info);
    }
  }
};
</script>

<style lang="css" scoped>
.info-con { padding: 1rem; margin: 1rem; border-radius: 8px; background: #ffffff; box-shadow: 1px 1px 6px rgba(131, 131, 131, 0.5); overflow: hidden; } .info-con img{ width: 100%; } .info-con .movie-name { margin-top: .5rem; text-align: left; line-height: 2rem; font-size: .9rem; font-weight: 400; } .movie-name span{color: grey;font-size: .8rem;}
</style>

在运行之前,我们还需要在router文件夹下的index.js文件里配置好路由

import Vue from 'vue'
import Router from 'vue-router' /* 引用vue路由模块,并赋值给变量Router */

import movieList from '@/page/movieList.vue'
import movieInfo from '@/page/movieInfo.vue'

Vue.use(Router) /* 使用路由 */

export default new Router({
  routes: [ /* 进行路由配置,规定“/”引入到组件 */
    {
      path: '/',//默认页面
      name: 'movieList',
      component: movieList  /* 注册组件 */
    },
    {
      path: '/movieList',
      name: 'movieList',
      component: movieList
    },
    {
      path: '/movieInfo',
      name: 'movieInfo',
      component: movieInfo
    }
  ]
})

现在在控制台输入 npm run dev 我们就可以看到整个效果了

 

但是我们希望头尾的导航栏能根据我们的页面显示不同的信息,这时候就需要用到通信功能了,详情→ Vue组件通信

首先我们在movieList.vue 的mounted里给App.vue传一个title和footer的index

mounted() {
    this.$emit('setNav',['豆瓣评分Top250电影',1]);

    // 这个是vue的钩子函数,当new Vue()实例创建完毕后执行的函数
    this.$http
      .jsonp("https://api.douban.com/v2/movie/top250?count=10")
      .then(res => {
        this.movieList = res.data.subjects;
        res = null;
      })
      .catch(error => {
        console.log("http error" + error);
      });
  }

 

同样的在movieInfo.vue 的mounted里也给App.vue传当前的电影名和footer的index

mounted() {
    let info = sessionStorage.getItem('movieInfo')||0;
    if(info){
      this.info = JSON.parse(info);
    }
    this.$emit('setNav',[this.info.title,2]);
  }

 

然后在App.vue里通过setNav函数接受子组件的参数,并把这两个参数传递给headerNav和footerNav

<template lang="html">
  <div class="container">
    <!--  引入的header组件 -->
    <headerNav :navTitle="navTitle"></headerNav>
    
    <div class="content">
      <router-view v-on:setNav="setNav"></router-view>  <!-- 这里是展示来自路由页面数据的 -->
    </div>

    <!--  引入的footer组件 -->
    <footerNav :nowTab="nowTab"></footerNav>
  </div>
</template>
<script>
/* 引用组件 */
import headerNav from "@/components/headerNav";
import footerNav from "@/components/footerNav";

export default {
  data() {
    /* 这里是数据,注意数据一定要放data中然后用return返回 */
    return {
      navTitle:'',
      nowTab:1,
    };
  },
  components: {
    headerNav,
    footerNav,
  },
  mounted(){},
  methods:{
    setNav(seterArr){
      this.navTitle = seterArr[0];
      this.nowTab = seterArr[1];
    }
  }
};
</script>

 

然后headerNav和footerNav只需要通过props接收就行了

<template lang="html">
  <div class="header">
    <span class="back-btn" @click="goBack()">←</span>
    <h6 class="header-name" v-text="navTitle"></h6>
  </div>
</template>
<script>
export default {
  props: {navTitle:String},
  methods:{
    goBack(){
      history.back(-1);
    }
  },
}
</script>
<template lang="html">
  <div class="footer">
    <ul class="footer-con b2 ui-transition">
      <router-link to="/movieList">
        <li :class="{g1:nowTab==1}">1</li>
      </router-link>
        
        <li :class="{g1:nowTab==2}">2</li>
        <li :class="{g1:nowTab==3}">3</li>
        <li :class="{g1:nowTab==4}">4</li>
    </ul>
  </div>
</template>
<script>
export default {
  props: {nowTab:Number},
}
</script>

这里我会给底部导航栏根据nowTab设置class以显示不同的颜色

 

到这里这个简单的项目就完成了,应该没有漏掉什么东西,如果不能成功的跑起来,欢迎评论问我。

 

 

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
要生成一个好看的 Vue 项目,可以遵循以下步骤: 1. 使用 Vue CLI 创建项目 Vue CLI 是一个官方的脚手架工具,可以帮助我们快速创建一个基于 Vue项目。你可以使用以下命令安装 Vue CLI: ``` npm install -g @vue/cli ``` 然后使用以下命令创建项目: ``` vue create my-project ``` 2. 选择适合自己的 UI 组件库 在 Vue 项目中,UI 组件库可以帮助我们快速构建出漂亮的页面。目前比较流行的 UI 组件库有 Element UI、Ant Design VueVuetify 等。你可以根据自己的需求选择一个适合自己的 UI 组件库。 以 Element UI 为例,你可以使用以下命令安装 Element UI: ``` npm install element-ui -S ``` 然后在 main.js 中引入 Element UI: ```javascript import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) ``` 3. 设计好看的页面 在设计页面时,我们可以借助一些设计工具来提高效率。比如 Sketch、Figma、Adobe XD 等工具。在设计时,可以参考一些现有的 UI 设计风格和规范,比如 Material Design、Ant Design 等。 4. 使用 CSS 预处理器 CSS 预处理器可以帮助我们更方便地编写 CSS,并且可以使我们的样式更加易于维护。目前比较流行的 CSS 预处理器有 Sass、Less 和 Stylus。你可以根据自己的习惯选择一个。 以 Sass 为例,你可以使用以下命令安装 Sass: ``` npm install node-sass sass-loader -D ``` 然后在 vue.config.js 中配置: ```javascript module.exports = { css: { loaderOptions: { sass: { prependData: `@import "@/styles/_variables.scss";` } } } } ``` 5. 优化性能 在大型 Vue 项目中,优化性能是非常重要的。我们可以采用以下一些方法来优化性能: - 使用路由懒加载 - 使用组件懒加载 - 使用 CDN 加载第三方库 - 开启 Gzip 压缩 - 开启 Webpack 的 Tree Shaking 特性 以上是生成一个好看的 Vue 项目的一些基本步骤,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值