a.vue基础入门项目实战——(项目初始化、修改根组件、首页页面、三要素基本搭建和json-server)实战01

目录

 

​ 百度网盘源代码

​ my-sz-one项目CLI创建

◆ 前提依赖构建

1、router-view

2、ajax(菜鸟教程)

3、typicode/json-server

4、json-server文章

 ◆ 基础项目构建

​ my-sz-one项目内容实现

◆ 首页三要素(header、content、footer)

➊ header

➋ content部分实现(包含detail、index)

◆ 语法小总结

v-for 

:class

 

➌ footer 略


 百度网盘源代码

https://pan.baidu.com/s/1t47o6mXfFDjLoDNod0Tk1w

 my-sz-one项目CLI创建

◆ 前提依赖构建

  • 1、router-view

npm install vue-router --save

npm install vue-resource --save

// Vue.use(VueResource)之后,从而在所有vue组件中使用this.$http.get/post...(.then请求完毕之后执行)


/*
export default {
	created: function() {
        // 带参数 -- this.$http.get('getList',{userId:123}).then(function(data) {
		this.$http.get('getList').then(function(data) {
			// 成功的回调
			console.log(data)
		}, function(error) {
			// 失败的回调
			console.log(error)
		})
	}, 
	......
*/

3、typicode/json-server

为了方便和后端调试,在前端设置rmokedata一个假的Restful数据,将前端所有的ajax数据放到一个文件里面

使用typicode/json-server步骤如下:

  1. 安装 
    npm install npm json-server --save 
    -- 或者 npm install -g json-server
  2. mokedata是适用于测试服,所以要在bulid文件夹的../build/webpack.dev.conf.js中添加
    // server.js
    const jsonServer = require('json-server')
    const server = jsonServer.create()
    const router = jsonServer.router('db.json')
    const middlewares = jsonServer.defaults()
    
    server.use(middlewares)
    server.use(router)
    server.listen(3000, () => {
      console.log('JSON Server is running')
    })
  3. 注意db.json和index.html同级别,此时执行npm run dev发现启动成功

  • 查看是否该项目下的json-server可用
  1. 1 如果已经配置了db.json的内容,然后在该项目(必须要有db.json文件)下执行
json-server --watch db.json

如下图所示:

则表示成功读取json信息我们就可以使用啦!!!使用json-server教程。

  • 4、json-server文章

  1. 上手玩一下 json-server(一)了解篇

  2. 学习vue-使用json-server模拟json数据

 ◆ 基础项目构建

  1. 1 创建实战项目(注意:千万不要配置语法检查
vue init webpack my-sz-one
  1. 2 基本页面搭建如下图所示

  • /src/components/layout.vue(注意:scope
<!-- layout.vue -->

<template>
	<div>
		<div class="app-header">header</div>
		<div class="app-content">content</div>
		<div class="app-footer">footer</div>
	</div>
</template>

<script>
</script>

<style scope>
</style>
  • /src/main.js

引入Layout组件,template: '<Layout>'直接渲染变成最外层,同时修改根组件为Layout { Layout }

/* main.js */

import Vue from 'vue'
import App from './App'
import router from './router'
import Layout from './components/layout'

Vue.config.productionTip = false


new Vue({
  el: '#app',
  router,
  components: { Layout },
  template: '<Layout>'
})
  • npm run dev 显示正确

 my-sz-one项目内容实现

◆ 首页三要素(header、content、footer)

➊ header

  • header部分搭建成如下,css和header部分大家直接粘贴就好

<!-- layout.vue -->

<template>
  <div>
    <div class="app-head">
      <div class="app-head-inner">
        <router-link :to="{path: '/'}">
          <img src="../assets/logo.png">
        </router-link>
        <div class="head-nav">
          <ul class="nav-list">
            <li> {{ username }}</li>
            <li v-if="username!== ''" class="nav-pile">|</li>
            <li v-if="username!== ''">退出</li>
            <li v-if="username=== ''" 
            <li class="nav-pile">|</li>
            <li v-if="username=== ''" 
            <li v-if="username=== ''">|</li>
            <li>关于</li>
          </ul>
        </div>  
      </div>
    </div>
    <div class="container">
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    </div>
    <div class="app-foot">
      <p>© 2016 fishenal MIT</p>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      isShowAboutDialog: false,
      isShowLogDialog: false,
      isShowRegDialog: false,
      username: ''
    }
  },
}
</script>

<style>
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
a {
  color: inherit;
  text-decoration: none;
}
body {
  background: #f0f2f5;
  font-family: "Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","Microsoft YaHei UI","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;
  font-size: 14px;
  color: #444;
}
.app-head {
  background: #363636;
  color: #b2b2b2;
  height: 90px;
  line-height: 90px;
  width: 100%;
}
.app-head-inner {
  width: 1200px;
  margin: 0 auto;
}
.head-logo {
  float: left;
}
.app-head-inner img {
  width: 50px;
  margin-top: 20px;
}
.head-nav {
  float: right;
}
.head-nav ul {
  overflow: hidden;
}
.head-nav li {
  cursor: pointer;
  float: left;
}
.nav-pile {
  padding: 0 10px;
}
.app-foot {
  text-align: center;
  height: 80px;
  width: 100%;
  line-height: 80px;
  background: #e3e4e8;
  clear: both;
  margin-top: 30px;
}
.container {
  width: 1200px;
  margin: 0 auto;
}
.hr {
  height: 1px;
  width: 100%;
  background: #ddd;
}
.button {
  background: #4fc08d;
  color: #fff;
  display: inline-block;
  padding: 10px 20px;
  cursor: pointer;
}
.button:hover {
  background: #4fc08d;
}
.g-form {

}
.g-form-line {
  padding: 15px 0;
}
.g-form-label {
  width: 100px;
  font-size: 16px;
  display: inline-block;
}
.g-form-input {
  display: inline-block;
}
.g-form-input input {
  height: 30px;
  width: 200px;
  line-height: 30px;
  vertical-align: middle;
  padding: 0 10px;
  border: 1px solid #ccc;
}
.g-form-btn {
  padding-left: 100px;
}
.g-form-error {
  color: red;
  padding-left: 15px;
}
</style>

➋ content部分实现(包含detail、index)

  1. 1 我们要用到router-view和ajax所以先要安装路由和vue-resource,则需要执行下面的命令:

npm install vue-router --save

npm install vue-resource --save

  1. 2 到main.js进行vue-router的配置(实例化VueRouter、router的Map、引入detail.vue、index.vue文件router根节点配置【如果在new Vue(已经有router则忽略最后一步)】)

......

import VueRouter from 'vue-router'

import VueResource from 'vue-resource'

Vue.use(VueRouter)

Vue.use(VueResource)

......

/* main.js */


import Vue from 'vue'
import Layout from './components/layout'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
/* 引入页面依赖 */
import IndexPage from './pages/index'
import DetailPage from './pages/detail'

Vue.use(VueRouter)
Vue.use(VueResource)

const router = new VueRouter({
	mode: 'history',
	routes: [{
		path: '/',
		component: IndexPage
	}, ]
})

new Vue({
	el: '#app',
	router,
	template: '<Layout/>',
	components: {
		Layout
	}
})
  1. 3 创建page目录,并且编写detail.vue、index.vue两个vue组件
  • Ⅰ /src/pages/index.vue
<template>
	<div>
		index.vue
	</div>
</template>

<script>
</script>

<style>
</style>
  •  index.vue(详细):key="key"
<template>
	<div class="index-wrap">
		<div class="index-left">
			<div class="index-left-block">
				<h2>全部产品</h2>

				<template v-for="product in productList">
					<h3>{{ product.title}}</h3>
					<ul>
						<li v-for="item in product.list">
							<a :href="item.url">{{ item.name }}</a>
							<span v-if="item.hot" class="hot-tag">HOT</span>
						</li>
					</ul>
					<div v-if="!product.last" class="hr"></div>
				</template>
			</div>
			<div class="index-left-block lastest-news">
				<h2>最新消息</h2>
				<ul>
					<li v-for="item in newsList">
						<a :href="item.url" class="new-item">{{ item.title }}</a>
					</li>
				</ul>
			</div>
		</div>
		<div class="index-right">
			
			<div class="index-board-list">
				<div class="index-board-item" v-for="(item, index) in boardList" :class="[{'line-last' : index % 2 !== 0}, 'index-board-' + item.id]">
					<div class="index-board-item-inner">
						<h2>{{ item.title }}</h2>
						<p>{{ item.description }}</p>
						<div class="index-board-button">
							<router-link class="button" :to="{path: 'detail/' + item.toKey}">立即购买</router-link>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				invTime: 2000,
				slides: [{
						src: require('../assets/slideShow/pic1.jpg'),
						title: 'xxx1',
						href: 'detail/analysis'
					},
					{
						src: require('../assets/slideShow/pic2.jpg'),
						title: 'xxx2',
						href: 'detail/count'
					},
					{
						src: require('../assets/slideShow/pic3.jpg'),
						title: 'xxx3',
						href: 'http://xxx.xxx.com'
					},
					{
						src: require('../assets/slideShow/pic4.jpg'),
						title: 'xxx4',
						href: 'detail/forecast'
					}
				],
				boardList: [{
						title: '开放产品',
						description: '开放产品是一款开放产品',
						id: 'car',
						toKey: 'analysis',
						saleout: false
					},
					{
						title: '品牌营销',
						description: '品牌营销帮助你的产品更好地找到定位',
						id: 'earth',
						toKey: 'count',
						saleout: false
					},
					{
						title: '使命必达',
						description: '使命必达快速迭代永远保持最前端的速度',
						id: 'loud',
						toKey: 'forecast',
						saleout: true
					},
					{
						title: '勇攀高峰',
						description: '帮你勇闯高峰,到达事业的顶峰',
						id: 'hill',
						toKey: 'publish',
						saleout: false
					}
				],
				newsList: [],
				productList: {
					pc: {
						title: 'PC产品',
						list: [{
								name: '数据统计',
								url: 'http://starcraft.com'
							},
							{
								name: '数据预测',
								url: 'http://warcraft.com'
							},
							{
								name: '流量分析',
								url: 'http://overwatch.com',
								hot: true
							},
							{
								name: '广告发布',
								url: 'http://hearstone.com'
							}
						]
					},
					app: {
						title: '手机应用类',
						last: true,
						list: [{
								name: '91助手',
								url: 'http://weixin.com'
							},
							{
								name: '产品助手',
								url: 'http://twitter.com',
								hot: true
							},
							{
								name: '智能地图',
								url: 'http://maps.com'
							},
							{
								name: '团队语音',
								url: 'http://phone.com'
							}
						]
					}
				}
			}
		}
	}
</script>


<style scoped="scoped">
	.index-wrap {
		width: 1200px;
		margin: 0 auto;
		overflow: hidden;
	}

	.index-left {
		float: left;
		width: 300px;
		text-align: left;
	}

	.index-right {
		float: left;
		width: 900px;
	}

	.index-left-block {
		margin: 15px;
		background: #fff;
		box-shadow: 0 0 1px #ddd;
	}

	.index-left-block .hr {
		margin-bottom: 20px;
	}

	.index-left-block h2 {
		background: #4fc08d;
		color: #fff;
		padding: 10px 15px;
		margin-bottom: 20px;
	}

	.index-left-block h3 {
		padding: 0 15px 5px 15px;
		font-weight: bold;
		color: #222;
	}

	.index-left-block ul {
		padding: 10px 15px;
	}

	.index-left-block li {
		padding: 5px;
	}

	.index-board-list {
		overflow: hidden;
	}

	.index-board-item {
		float: left;
		width: 400px;
		background: #fff;
		box-shadow: 0 0 1px #ddd;
		padding: 20px;
		margin-right: 20px;
		margin-bottom: 20px;
	}

	.index-board-item-inner {
		min-height: 125px;
		padding-left: 120px;
	}

	.index-board-car .index-board-item-inner {
		background: url(../assets/images/1.png) no-repeat;
	}

	.index-board-loud .index-board-item-inner {
		background: url(../assets/images/2.png) no-repeat;
	}

	.index-board-earth .index-board-item-inner {
		background: url(../assets/images/3.png) no-repeat;
	}

	.index-board-hill .index-board-item-inner {
		background: url(../assets/images/4.png) no-repeat;
	}

	.index-board-item h2 {
		font-size: 18px;
		font-weight: bold;
		color: #000;
		margin-bottom: 15px;
	}

	.line-last {
		margin-right: 0;
	}

	.index-board-button {
		margin-top: 20px;
	}

	.lastest-news {
		min-height: 512px;
	}

	.hot-tag {
		background: red;
		color: #fff;
	}

	.new-item {
		display: inline-block;
		width: 230px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
</style>
  • Ⅲ/src/pages/detail.vue
<template>
	<div>
		detail
	</div>
</template>

<script>
</script>

<style>
</style>
  •  detail.vue(详细)
<!-- detail.vue -->

<template>
	<div class="detail-wrap">
	    <div class="detail-left">
	      <div class="product-board">
	        <img :src="productIcon">
	        <ul>
	          <!-- <router-link v-for="item in products" :to="{ path: item.path }" tag="li" active-class="active">
	            {{ item.name }}
	          </router-link> -->
	        </ul>
	      </div>
	    </div>
	    <div class="detail-right">
	      <keep-alive>
	        <router-view></router-view>
	      </keep-alive>
	    </div>
	  </div>
</template>


<script>
export default {
  data () {
    return {
      products: [
        {
          name: '数据统计',
          path: 'count',
          icon: require('../assets/images/1.png'),
          active: false
        },
        {
          name: '数据预测',
          path: 'forecast',
          active: false
        },
        {
          name: '流量分析',
          path: 'analysis',
          active: false
        },
        {
          name: '广告发布',
          path: 'publish',
          active: false
        }
      ],
      imgMap: {
        '/detail/count': require("../assets/images/1.png"),
        '/detail/forecast': require("../assets/images/2.png"),
        '/detail/analysis': require("../assets/images/3.png"),
        '/detail/publish': require("../assets/images/4.png")
      }
    }
  },
  computed: {
    productIcon () {
      return this.imgMap[this.$route.path]
    }
  }
}
</script>


<style scoped="scoped">
.detail-wrap {
  width: 1200px;
  margin: 0 auto;
  overflow: hidden;
  padding-top: 20px;
}
.detail-left {
  float: left;
  width: 200px;
  text-align: center;
}
.detail-right {
  float: left;
  width: 980px;
  margin-left: 20px;
}
.product-board {
  background: #fff;
  padding: 20px 0;
}
.product-board ul {
  margin-top: 20px;
}
.product-board li {
  text-align: left;
  padding: 10px 15px;
  cursor: pointer;
}
.product-board li.active,
.product-board li:hover {
  background: #4fc08d;
  color: #fff;
}
.product-board li a {
  display: block;
}
.sales-board {
  background: #fff;
}
.sales-board-form {

}
.sales-board-intro h2 {
  font-size: 20px;
  padding: 20px;
}
.sales-board-intro p {
  background: #f7fcff;
  padding: 10px 20px;
  color: #999;
  line-height: 1.8;
}
.sales-board-form {
  padding: 30px 20px;
  font-size: 14px;
}
.sales-board-line {
  clear: both;
  padding-bottom: 20px;
}
.sales-board-line-left {
    display: inline-block;
    width: 100px;
}
.sales-board-line-right {
    display: inline-block;
    width: 75%;
}
.sales-board-des {
  border-top: 20px solid #f0f2f5;
  padding: 15px 20px;
}
.sales-board-des p {
  line-height: 1.6;
}
.sales-board-des h2 {
  font-size: 20px;
  padding-bottom: 15px;
}
.sales-board-des h3 {
  font-size: 18px;
  font-weight: bold;
  padding: 20px 0 10px 0;
}
.sales-board-des li {
  padding: 5px 0;
}
.sales-board-table {
  width: 100%;
  margin-top: 20px;
}
.sales-board-table th {
  background: #4fc08d;
  color: #fff;
}
.sales-board-table td {
    border: 1px solid #f0f2f5;
    padding: 15px;
}
</style>
  • Ⅴ 最终效果

◆ 语法小总结

  • v-for 

对于循环我们可以利用div或者template做循环:

<template v-for="item in List">
	{{item}}
</template>
  • :class

对于样式支持数组和对象的形式

  1. 1 后者为真,则显示该css
:class="{'line-last' : index % 2 !== 0}"
  1. 为数组,并且支持字符串拼接
:class="[{'line-last' : index % 2 !== 0}, 'index-board-' + item.id]"

 

➌ footer 略

发布了234 篇原创文章 · 获赞 52 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Sicily_winner/article/details/104010006