由于一个完整的项目包含许多的视图,组件全部写在一个html页面中也不利于后期维护。所以我们需要通过脚手架进行项目工程化来构建我们的项目,就不再使用html来构建了,也不在引入vue.js文件了。全部换成单文件组件+webpack+vue的脚手架进行项目的构建。
首先,需要全局安装vue脚手架(全局安装,只需一次),方法是: npm i vue-cli -global
然后就可以构建项目了,vue提供了两种模板:webpack的模板、webpack-simple的模板。
-
官方模版 vue init webpack my-project (tips:代码语法检查较麻烦,适合新手使用)
-
推荐 vue init webpack-simple my-project (tips:适合熟练vue脚手架项目的人用)
用这个模板构建项目的前提是已经配置过vue和webpack以及vue脚手架的环境,即 npm install -g vue全局安装、npm i webpack -g全局安装、 npm install -g vue-cli脚手架全局安装。使用指令模板之后,根据提示进行依赖安装。
- 项目启动 npm run dev
- 项目打包 npm run build
- 单文件组件 组件 css拥有作用域,scoped属性可规定当前css只作用于自己的组件,不影响其他
以一个移动端小项目来代入-------------
假设vue和webpack环境已配好,新建一个目录并调出小黑窗-->npm i vue-cli -g(安装过就不用再装)--->vue init webpack pro--->cd pro--->npm run dev运行即可,会启动8080端口,浏览器打开localhost:8080,若占用会默认加1即8081。
项目构建好之后就可以根据需求来修改配置了。下面用路由来实现三个页面的跳转:
//APP.vue
<template>
<div id="app">
<header>{{str}}</header>
<section>
<router-view @toparent="getdata"></router-view>
</section>
<footer>
<router-link to="/home" tag="span">首页</router-link>
<router-link to="/about" tag="span">关于</router-link>
<router-link to="/other" tag="span">其他</router-link>
</footer>
</div>
</template>
<script>
export default {
name: 'App',
data:function(){
return{
str:"首页"
}
},
methods:{
getdata(msg){
this.str=msg
}
}
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
.router-link-active{
color: yellow;
}
#app {
height: 100Vh;
display: flex;
flex-direction: column;
}
header,footer{
height: 40px;
background: blue;
color: #fff;
text-align: center;
line-height: 40px;
}
section{
flex: 1;
}
footer span{
float: left;
width: 33.3%;
}
</style>
注:这个单文件组件在main.js已在vue实例化中挂载,index.html页面引入即可展示。在这个组件里面可以通过router-link做一个导航路由,去写一下导航路由连接的组件(在项目的src文件夹的components目录下建Home、About、Other组件)
//Home.vue
<template>
<div>
<h1>首页</h1>
</div>
</template>
<script>
export default{
name:"Home",
data(){
return{
str:"首页"
}
},
mounted(){
this.$emit("toparent",this.str)
}
}
</script>
<style>
</style>
//Other.vue
<template>
<div>
<h1>其他</h1>
</div>
</template>
<script>
export default{
name:"Other",
data:function(){
return{
str:"其他"
}
},
mounted(){
this.$emit("toparent",this.str)
}
}
</script>
<style>
</style>
//About.vue
<template>
<div>
<h1>关于</h1>
</div>
</template>
<script>
export default{
name:"About",
data(){
return{
str:"关于"
}
},
mounted(){
this.$emit("toparent",this.str)
}
}
</script>
<style>
</style>
然后在router目录下配置一下路由规则
//index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '../components/Home'
import About from '../components/About'
import Other from '../components/Other'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/other',
component: Other
},
{
path: '*',
redirect:"/home"
}
]
})
注:上面代码有用到子组件向父组件传值,用的是自定义绑定事件@toparent="getdata",子组件在挂载的时候通过this.$emit("toparent",this.str)将数据传送给父组件,父组件通过事件getdata(msg){console.log(msg)}来接收,msg就是接收的数据。
下面就是用axios来请求数据的使用,需要安装依赖npm i axios -S,哪个文件使用就在哪个文件中引入,引入方式是import axios from "axios".上代码:
//Home.vue
<template>
<div>
<h1>首页</h1>
<ul>
<li v-for="item in list"><router-link :to="'/detail/'+item.pid" tag="span">{{item.pname}}</router-link></li>
</ul>
</div>
</template>
<script>
import axios from "axios"
export default{
name:"Home",
data(){
return{
str:"首页",
list:[]
}
},
mounted(){
this.$emit("toparent",this.str)
var _this = this
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
_this.list = data.data.data
})
}
}
</script>
<style>
</style>
在上面Home组件里面请求数据展示在页面上,然后通过params传参到详情页面。下面是详情页面的组件:
//Detail.vue
<template>
<div>
<h1>详情</h1>
<ul>
<li v-for="item in arr">
<img :src="item.imgSrc"/>
<span >{{item.desC}}</span>
</li>
</ul>
</div>
</template>
<script>
import axios from "axios"
export default{
name:"Detail",
data(){
return{
str:"详情",
arr:[],
imgsrc:"",
desc:""
}
},
mounted(){
this.$emit("toparent",this.str);
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:_this.$route.params.id}
}).then(function(data){
_this.imgsrc = data.data.data.pimg;
_this.desc = data.data.data.pdesc;
_this.arr.push({imgSrc:_this.imgsrc,desC:_this.desc});
})
}
}
</script>
<style scoped="">
ul li{
width: 300px;
height: 480px;
background: #CCCC99;
float: left;
margin: 10px;
}
img{
display: block;
width: 260px;
height: 300px;
margin:10px 0 0 20px;
}
span{
display: block;
margin:20px 0 0 20px;
}
</style>
index.js中配置一下路由规则
//index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '../components/Home'
import About from '../components/About'
import Other from '../components/Other'
import Detail from '../components/Detail'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/other',
component: Other
},
{
path: '/detail/:id',
component: Detail
},
{
path: '*',
redirect:"/home"
}
]
})
对传递数据的处理写在详情组件上面。
引入icon图标的方法,main.js里面导入文件
import './icon/iconfont.css'
和vue搭建比较好的框架有Element(适合pc端)饿了吗饿了吗 Mintui(适合移动端的UI框架)mint-ui要翻墙要翻墙
另外,vue里面返回上一级的操作是:$router.back(-1),这个经常会用到。