环境搭建
推荐用Vue-Cli搭建项目。如果打算集成第三方框架,如Element-UI、Antd等,就用第三方提供的脚手架。
项目结构
刚撸完的一个完整项目
用到的一些技术
- dist:运行yarn build后生成的目录,不需要运行在node环境,可以直接用浏览器打开
- node_modules:依赖
- public:这里面我只留了一个index.html
- api:调用接口的方法
- components:组件,也可以简单理解成能够被多个vue文件复用的vue文件
- routers:这里面也是vue文件,很多人弄不清它和components的区别,虽然都是vue文件,但是routers里面的vue文件能够被vue-router控制,做页面跳转(hash路由)
- store:为Vuex存放的模块化数据,这里做的比较简单,只存了方法名,便于commit
- util:一些工具类
- App.vue:就放一个router-view标签做路由,不干其它事
- main.js:主方法,在这里初始化vue实例,将vue-router和vuex集成到vue实例上
- router.js:初始化vue-router
- store.js:初始化vuex
- vue.config.js:可以覆盖webpack的一些配置
其它的没啥好介绍的了
技术细节
Router创建
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './routers/Home'
import FabanSearch from './routers/FaBanSearch'
import FaBanList from './routers/FaBanList'
Vue.use(VueRouter)
const routers = [
{
path: "/",
component: Home,
meta: {
title: '查询类型'
}
},
{
path: '/fabansearch',
component: FabanSearch,
},
{
path: '/fabanlist',
component: FaBanList,
},
]
export default new VueRouter({
routes: routers,
})
- 先用Vue.use()一下Vue-Router对象
- path是路径,可以通过router-link(a)标签或者js路由
- component就是router文件夹里的vue文件
Vuex创建
先来看store文件夹有一个mutationType.js文件,这里面定义了vuex的mutations的方法名
export default {
SAVE_TEST: 'saveTest',
}
再来看store.js怎么写的
import Vue from 'vue'
import Vuex from 'vuex';
import mutationType from './store/mutationType'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
test: [],
},
mutations: {
[mutationType.SAVE_TEST](state, test) {
state.test = test
}
},
})
- state就像vue实例里面的data,但是vuex里面的这个state可以让所有vue组件访问。而vue里面的data只能自己玩。
- mutations:修改state的。当然也可以直接修改state,但是通过mutations修改的state会在vue-devtool中显示状态流,方便debug。
Vue集成Vue-Router、Vuex
在main.js中
// vue
import Vue from 'vue'
// 路由
import router from './router'
// vuex
import store from './store'
// vant
import Vant from 'vant';
import 'vant/lib/index.css';
// index
import App from './App.vue'
Vue.config.productionTip = false
Vue.use(Vant)
// 将router和store放进去就行了
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
Api接口方法定义
import axios from 'axios'
import qs from 'qs'
import { baseUrl } from './baseOption'
// 基础配置
const http = axios.create({
method: 'POST',
baseURL: '/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
})
/**
* 获取进站证发班明细列表
* @param {Object} param 查询参数
*/
export async function listFaban(param = { page: 1, rows: 10 }) {
const resp = await http({
url: '/api/test1',
data: qs.stringify(param),
})
return resp.data
}
/**
* 获取所有区域列表和场站列表
*/
export async function listArea() {
const resp = await http({
url: '/api/test2',
})
return resp.data
}
- 在vue方法中可以把方法声明成async,然后await调用就可以将异步方法当同步方法用了,非常方便
async initSelect() { const data = await listArea(); ... }
- qs用来将对象转成url参数的
Vue组件的定义
在定义Vue组件的时候切记不能再组件中使用Vuex或者其它第三方的数据,它最好只用data(自己的数据)和props(父组件传过来的数据)的数据
Vue组件如果要修改Vuex里的数据,最好是父组件在子组件监听一个方法,子组件通过emit方法触发父组件的方法,父组件通过回调修改vuex数据。
Vue子组件为了复用性最好是不要与父组件之外的数据有交互,component文件夹就是我们定义的子组件,这些组件可以在多处被重复使用
上个代码,自己理解
component中的组件
<template>
<div class="list">
<van-list
v-model="loading"
:finished="dataList.length >= total"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell v-for="(item, index) in dataList" :key="index">
<slot name="default">
<div class="container">
<div class="item" style="background: #eee;">第{{index+1}}条 共{{total}}条数据</div>
<div class="item" v-for="(itemMap, itemIndex) in item" :key="itemIndex">
<span>{{itemMap.key}}</span>
<span>{{itemMap.value}}</span>
</div>
</div>
</slot>
</van-cell>
</van-list>
</div>
</template>
<script>
export default {
name: "List",
props: ["dataList", "onLoad", "total"],
data() {
return {
loading: false
};
}
};
</script>
<style scoped>
.container {
width: 100%;
background-color: #ffffff;
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
.container .item {
padding: 5px 10px;
display: flex;
flex-basis: 100%;
justify-content: space-between;
}
.container .item span {
flex: 1;
}
</style>
router中的组件,List在components中声明后使用,List组件就可以根据父组件传过来的数据进行渲染。只要父组件(调用方)保证数据正确,而不需要在意vuex或者其它数据源的数据是否正确。List就相当于一个功能组件,和util差不多的意思。
<template>
<div id="faBanList">
<List :dataList="fabanListFormat" :onLoad="listFaban" :total="fabanTotal" ref="list" />
</div>
</template>
<script>
import List from "../components/List";
export default {
...
// 声明
components: {
List: List
},
...
}
</script>
打包
这里说个小坑,我在打包的时候,dist/index.html的路径默认引入的是绝对路径,如果文件不是放在服务器的根目录下,会导致css、js找不到。所以我后来加了个vue.config.js文件
module.exports = {
publicPath: './'
}
把webpack的默认配置改下,默认是/,就会用相对路径访问资源文件
yarn build就可以打包了