从零搭建vue 项目(一)

从零搭建vue 项目(一)

我的博客

代码地址

代码地址

首先4个官方文档

  1. Vue
  2. Vue CLI
  3. Vue Router
  4. Vuex

创建vuedemo的项目

npx @vue/cli create vuedemo

从零搭建vue 项目(一)_第1张图片

从零搭建vue 项目(一)_第2张图片

cd vuedemo

yarn run serve  or npm run serve

从零搭建vue 项目(一)_第3张图片
从零搭建vue 项目(一)_第4张图片

项目结构

项目中的vue各个版本号

"dependencies": {
    "@vue/cli-plugin-babel": "^3.12.0",
    "@vue/cli-plugin-eslint": "^3.12.0",
    "@vue/cli-service": "^3.12.0",
    "vue": "^2.6.10",
    "vue-router": "^3.1.3",
    "vuex": "^3.1.1"
  },

项目结构

├── vue.config.js      		# vue-cli 配置文件
├── public					# 根html 存放目录
.
└── src
    ├── index.html
    ├── main.js
    ├── App.vue  			 # 根vue
    ├── api					 # 请求api文件
    │   └── ... 			 # 抽取出API请求
    ├── components  		 # 公共组件
    │   ├── App.vue
    │   └── ...
    └── pages 				  # 页面合集
    │   ├── A          		  # A 页面
    │   │   └── index.vue     # A 页面导出页面
    │   └── B				  # B 页面
    │   │   └── index.vue     # B 页面导出页面
    │   └── ...
    └── router 				  # 存放路由
    │   ├── index.js          # 我们组装模块并导出 router 的地方
    │   └── routers.js        # router 导出的数据合集
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        └── modules
            ├── cart.js       # 购物车模块
            └── products.js   # 产品模块

安装vue-router

官方文档https://router.vuejs.org/zh/installation.html

yarn add vue-router

官方文档上,给出了一个 demo
https://router.vuejs.org/zh/guide/#html
这里,我按照自己项目的结构进行设置。

  1. 首先新建 pages、router 文件夹

  2. 建立对应的文件内容

  3. 在 main.js 引入 router

  4. 在 App.vue 设置路由匹配到的组件,即

  5. 查看效果

  6. 设置如下的文件

从零搭建vue 项目(一)_第5张图片

  1. 在router文件夹内设置
//  router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routers'
Vue.use(VueRouter)

const router = new VueRouter({
  routes,
//   mode: 'history'
})

// 全局路由守卫
router.beforeEach((to, from, next) => {
  if (to.matched.length === 0) { // 如果未匹配到路由
    next({ path: '/404' })
  } else {
    next() // 如果匹配到正确跳转
  }
})

export default router
// router/routers.js
export default [
  {path: '/', component: () => import ('../components/HelloWorld.vue')},
  {path: '/demo1', component: () => import ('../pages/demo1/index.vue')},
  {path: '/demo2', component: () => import ('../pages/demo2/index.vue')},
  {path: '/404', component: () => import ('../pages/unfound/index.vue')},
];

  1. 在 main.js 引入 router
// main.js
import Vue from 'vue'
import App from './App.vue'
+ import router from './router'

Vue.config.productionTip = false

new Vue({
+  router,
  render: h => h(App),
}).$mount('#app')

  1. 在 App.vue 设置路由匹配到的组件,即

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    
    <router-link to="/">Go to 首页router-link>
    <router-link to="/demo1">Go to demo1router-link>
    <router-link to="/demo2">Go to demo2router-link>
    <router-view>router-view>
  div>
template>

  1. 效果

从零搭建vue 项目(一)_第6张图片
这里注意:
如果使用官方 demo 的引入组件,来测试路由的话,会出现以下问题。

const Foo = { template: '
foo
'
} const Bar = { template: '
bar
'
} // 2. 定义路由 // 每个路由应该映射一个组件。 其中"component" 可以是 // 通过 Vue.extend() 创建的组件构造器, // 或者,只是一个组件配置对象。 // 我们晚点再讨论嵌套路由。 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ]

会报错,如下

 You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

从零搭建vue 项目(一)_第7张图片
这里 需要在vue.config.js 设置如下内容,即可

// vue.config.js
module.exports = {
  // 选项...
  runtimeCompiler: true, //加入内容
};

再重新编译一下,就好了
https://cli.vuejs.org/zh/config/#runtimecompiler
详细原因,见 官方文档
https://cn.vuejs.org/v2/guide/installation.html#%E8%BF%90%E8%A1%8C%E6%97%B6-%E7%BC%96%E8%AF%91%E5%99%A8-vs-%E5%8F%AA%E5%8C%85%E5%90%AB%E8%BF%90%E8%A1%8C%E6%97%B6

安装 vuex

https://vuex.vuejs.org/zh/

yarn add vuex

store 可以有两种写法,这里会一一分别列出。
第一种写法

// app.js
export default {
  state: {
    count: 0,
  },
  getters: {},
  mutations: {
    ADD (state, data) {
      state.count = data;
    },
    DEC (state, data) {
      state.count = data;
    },
  },
  actions: {
    add ({commit, state}, data) {
      commit ('ADD', state.count + data);
    },
    dec ({commit, state}, data) {
      commit ('DEC', state.count - data);
    },
  },
};

第二种写法

// app2.js

// initial state
const state = {
    count2: 2,
};

// getters
const getters = {};

// actions
const actions = {
  add2 ({commit, state}, data) {
    commit ('ADD2', state.count2 + data);
  },
  dec2 ({commit, state}, data) {
    commit ('DEC2', state.count2 - data);
  },
};

// mutations
const mutations = {
  ADD2 (state, data) {
    state.count2 = data;
  },
  DEC2 (state, data) {
    state.count2 = data;
  },
};

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations,
};

在 demo1 使用

<template>
  <div>
    <h1>demo1h1>
    <p>app-count:{{ count }}p>
    <p>app2-count2:{{ count2 }}p>
    <button @click="add(1)">count 加1button>
    <button @click="add2(1)">count2 加1button>
    

    <button @click="dec(1)">count 减1button>
    <button @click="dec2(1)">count2 减1button>
  div>
template>

<script>
import { mapState, mapActions } from "vuex";
export default {
  computed: {
    ...mapState({
      count: state => state.app.count,
      count2: state => state.app2.count2
    })
  },
  methods: {
    ...mapActions(["add", "dec"]),
    ...mapActions({
      add2: "app2/add2",
      dec2: "app2/dec2"
    })
  },
  created() {
    this.$nextTick(() => {
    });
  }
};
script>

<style>
style>

导出store

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

import app from './modules/app'
import app2 from './modules/app2'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //
  },
  mutations: {
    //
  },
  actions: {
    //
  },
  //   插件位置
  plugins: [],
  modules: {
    app,
    app2,
  }
})

在main.js 引入store

import Vue from 'vue'
import App from './App.vue'
import store from './store/index'

import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

效果完成
从零搭建vue 项目(一)_第8张图片

你可能感兴趣的:(Vue)