从零搭建vue 项目(一)

从零搭建vue 项目(一)

我的博客

代码地址

代码地址

首先4个官方文档

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

创建vuedemo的项目

npx @vue/cli create vuedemo

image.png

image.png

cd vuedemo

yarn run serve  or npm run serve

image.png
image.png

项目结构

项目中的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. 设置如下的文件

image.png

  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 设置路由匹配到的组件,即
<!-- App.vue -->
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <!-- <HelloWorld msg="Welcome to MyVue" /> -->
    <router-link to="/">Go to 首页</router-link>
    <router-link to="/demo1">Go to demo1</router-link>
    <router-link to="/demo2">Go to demo2</router-link>
    <router-view></router-view>
  </div>
</template>

  1. 效果

image.png
这里注意:
如果使用官方 demo 的引入组件,来测试路由的话,会出现以下问题。

const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 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.

image.png
这里 需要在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>demo1</h1>
    <p>app-count:{{ count }}</p>
    <p>app2-count2:{{ count2 }}</p>
    <button @click="add(1)">count 加1</button>
    <button @click="add2(1)">count2 加1</button>
    

    <button @click="dec(1)">count 减1</button>
    <button @click="dec2(1)">count2 减1</button>
  </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')

效果完成
image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值