vue项目搭建并设计简单的架构(2019-07-13---15)


准备阶段
  1. 安装nodejs、npm
  2. 全局安装vue、vue-cli
  3. 全局安装webpack
  4. 在合适的位置建一个项目文件夹
开始

打开你的Terminal(MAC)或者cmd(windows)
一路cd到你的项目文件夹
通过vue-cli脚手架搭建项目:vue init webpack xxx xxx为你的项目名
设置项目名、描述、作者、是否使用vue-router(使用)、是否使用ESLint(虽然很有用但是我不喜欢用哈哈)、单元测试(不需要)、e2e (NO)、使用npm...反正就是一路回车,看自己需求搭建。

项目初始化

用vscode打开项目,在终端处cd到初始化的项目目录运行npm start

npm start

好了 项目初始化搞定✌️
打开你的浏览器输入http://localhost:8080就可以看到Vue的界面了


简单设计项目架构

项目有一个设计合理的架构是非常重要的,不同的文件不同的代码做着不同的工作,我们现在要给他们划分开,一人一个坑😄
新建几个文件夹让你的自动生成的项目目录长成这样 /* 👇 */

项目目录结构


utils工具类

在这里我们定义一些开发时会用到的工具类,例如封装axios、时间格式化工具、封装本地存储等


屏幕快照 2019-07-13 下午3.13.28.png

例子:http.js 简单封装axios
baseURL就是你要访问的地址的ip和端口号

import axios from 'axios'

let httpInstance = axios.create()

// httpInstance.defaults.baseURL = 'http://172.20.10.2:3001'//iphone热点
// httpInstance.defaults.baseURL = 'http://172.30.10.127:3001' //公司ip
//httpInstance.defaults.baseURL = 'http://39.97.114.146:3001' //服务器地址
// httpInstance.defaults.baseURL = 'http://192.168.1.109:3001' //软件园5号楼宿舍
httpInstance.defaults.baseURL = 'https://api.apiopen.top/' //发放接口


httpInstance.defaults.timeout = 5000

//POST 请求
httpInstance.formurl = (url, data, config) => {
  return httpInstance.post(url, data, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    ...config
  })
};

//  request拦截器
httpInstance.interceptors.request.use(
  config => {
    //这里写拦截后你需要的操作
    //例如:
    // if (store.getters.token) {
    //   config.headers['Authoriztion'] = store.getters.token; //让每个请求都携带token
    // }
    // config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    return config
  },
  error => {
    console.log('err' + error) //only for debug ~~~
    return Promise.reject(error)
  }
)
//  reponse拦截器
httpInstance.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response)
    }
  },
  error => {
    return Promise.reject(error)
  }
)
export default httpInstance



api.js 接入后端服务的api管理

对所有访问后端的接口进行统一管理可以使复杂的系统变得有条理,可以使开发时候思路更清晰,也方便管理维护,我们建一个api文件夹,不同类别的接口各自定义在自己的模块中,那里出错就去哪里找问题。


api管理
例子:userApi.js
import HttpUtils from '../utils/http'

const UserApi = {
  userLogin: (params) => {
    let url = '/login';
    return HttpUtils.post(url, params)
  },
  userRegist: (params) => {
    let url = '/regist';
    return HttpUtils.post(url, params)
  }
}

export default UserApi;

在业务界面调用接口时直接使用定义好的接口就ok啦👌 /* 👇 */

import UserApi from "../api/userApi";

UserApi.userLogin({ account: 666 , password: 'wozhende666' })
  .then(res => {
     console.log(res);
   })
  .catch(err => {
     console.log(err);
   });

这样最终访问的地址就是http.js中的baseURL+userApi.js中定义的接口:
https://api.apiopen.top/login 也就是后端接口放的地方,把公共部分提取出来为baseURL,不同的接口在api管理中来区分✌️


项目路由router

由 前端 来控制页面的跳转(但其实是个单页面),根据不同的 url 地址展示不同的内容和页面。
优点:体验好,不需要每次从服务器获取全部,快速展现给用户;
缺点:不利于SEO;使用浏览器的前进,后退键的时候会重新发送请求,没有合理的利用缓存;单页面无法记住之前滚动的位置,无法在前进和后退的时候记住滚动的位置。

路由的结构设计可以按自己的项目页面结构情况来设计
我一般的习惯是将头部,底部等公共的部分抽离出来放到外层,各个业务界面定义为子路由
举个🌰 /* 👇 */

import Vue from 'vue'
import Router from 'vue-router'
import Home from "../views/home";
import Index from '../views/index'
import FirstPage from '../views/firstpage/firstpage.vue'
Vue.use(Router)

export default new Router({
  routes: [{
    path: '/',
    name: 'home',
    component: Home,
    redirect: '/index', //配置默认子路由为index
    children: [{
      path: '/index',
      name: 'index',
      component: Index,
    }, {
      path: '/firstpage',
      name: 'firstpage',
      component: FirstPage,
    }]
  }]
})
页面结构

view下有个 home.vue是入口页面,页面的头部和底部抽离出来在这里使用,在头部和底部之间又定义了一层二级路由(在router.js中配置了children)index.vue是首页,其他页面文件按功能不同进行分类,在定义路由的时候要弄清楚层级关系
home.vue代码如下:

<template>
  <div>
    <top-header></top-header>
    <router-view></router-view>
    <top-footer></top-footer>
  </div>
</template>

<script>
import TopHeader from "../components/layout/top_header";
import TopFooter from "../components/layout/top_footer";
export default {
  name: "",
  components: { TopHeader, TopFooter },
  data() {
    return {};
  }
};
</script>

<style scoped>
</style>

效果如下



如图地址改变只是改变了中间需要改变的部分,头部和底部不用重新渲染,同时在写代码的时候也不需要每次都写那些代码,方便多了不是吗?


状态管理

由于前端技术爆发式发展,SPA、组件化、模块化等概念被炒的飞起,项目中各个模块如果需要共同状态或者说数据的话,就需要组件间通讯,但是如果业务结构一层套一层,数据状态在父、子、孙、曾孙... 之间传递的时候很容易就乱了,于是在项目比较大的时候,出于对项目架构的灵活性考虑就要使用状态管理。
常见的状态管理技术:mobx Vuex Reduex

简单来说说vuex

在store文件夹下新建store.js
store.js

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

export default new Vuex.Store({
  name: 'store',
  state: {
    //定义要进行状态管理的数据
    count: 0
  },
  //改变state的属性的值的方法放在mutations里
  mutations: {
    increment(state) {
      state.count += 1
    },
    decrement(state) {
      state.count -= 1
    }
  }
})

在main.js中将store挂载到全局下每一个组件上

import store from './store/store'
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

当你需要使用store中的某一数据时,你可以这样:
{{$store.state.count}}对没错,就是直接用哈哈
这里要记住一定不要忘了$,我就老忘🤦‍♂️
当要改变数据的状态时,要把改变数据的逻辑写在store.js的 mutaiins 中👆 请看上上个图
使用时是这样👇
index.vue

<template>
  <div>
    <button @click="$store.commit('increment')">+</button>    
    <button @click="$store.commit('decrement')">-</button>
    <button @click="change">change</button>
  </div>
</template>

<script>
export default {
  name: "",
  components: {},
  data() {
    return {};
  },
  created() {},
  methods: {
    change() {
      this.$store.commit({
        type: "decrement",
        amount: 10
      });
    }
  }
};
</script>

<style scoped>
</style>

直接在行内调用。或者像第三个按钮一样绑定事件都可以。


🎉因为我太懒了,状态管理还有许多更方便有趣的内容,这里只是提了冰山一角,最最最基础的使用
🎉这篇文章最初开始写的目的只是因为每次建项目总是觉得不完美,这里那里差点东西的样子,撸个文巩固一下,并且也规范一下自己建一个合理、逻辑清晰的目录结构
🎉关于架构部分,本人还是个前端小学生,在这里根据自己对项目结构的理解,觉得哪些技术在工程中需要就设计了哪些,如果又不合理或者有错误的地方还请指正!
🎉如果觉得哪里还需要完善欢迎留言!
🎉本篇还会继续修正、更新。
🎉求点赞、分享。转发请备注作者出处
志同道合的小伙伴可以加微信:tong961790😄

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容