一、main.js
main.js是程序的入口,用于初始化vue实例,使用需要的插件,加载公共组件
需要导入

import Vue from 'vue'
import router from './router'
import App from './App'

main.js中导入router   import router from './router'  import后面的router只能写成router,且首字母大写都不行,不然在下面new Vue里面注入的时候控制台会报错Cannot read property 'matched'

实例化vue

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

上面实例化的方法是vue2.x的方法,在1.x中是如下写法

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

我们来详细说说2.x的方法,render函数是渲染一个视图,然后提供给el挂载,如果没有render那页面什么都不会出来

render: h => h(App)使用的是es6箭头函数。

render: h => h(App)

等价于

render: h => {
        return h(App);
}

等价于

render: function (h) => {
        return h(App);
}

等价于

render: function(createElement) {
        return createElement(App);
}

h是createElement的别名,vue生态系统的通用管理

$mount('#app') 手动挂载 在实例化vue时使用,或者new vue 括号里面el:#app

当vue实例没有el时,需要手动挂载,如上面vue2.x写法 如果像vue1.x中指定了el 则不需要手动挂载了 

Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),之后要手动挂载上。new Vue时,el和$mount并没有本质上的不同

当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中;
假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载。例如:
 
new Vue({
//el: '#app',
router,
render: h => h(App)
// render: x => x(App)
// 这里的render: x => x(App)是es6的写法
// 转换过来就是:  暂且可理解为是渲染App组件
// render:(function(x){
//  return x(App);
// });
}).$mount("#app")

或者

new Vue({
el: '#app',
router,
render: h => h(App)
// render: x => x(App)
// 这里的render: x => x(App)是es6的写法
// 转换过来就是:  暂且可理解为是渲染App组件
// render:(function(x){
//  return x(App);
// });
})

vue渲染机制图

二、App.vue

App.vue是我们的主组件,页面入口文件 ,所有页面都是在App.vue下进行切换的。也是整个项目的关键,app.vue负责构建定义及页面组件归集

有三个疑惑:

1.app.vue里面有个div id="app"  index.html中也有个div id="app" 那么main.js中el或mount挂载的是哪个app呢?

2.app.vue里面的div id="app" 与 index.html中的div id="app" 有什么关系

3.index.html里面的那个带id#app的div,为什么不会出现在dom结构里.

后来百度了,才明白

1.是index中的app

2.app.vue 跟 index.html 里面的ID 不一定一样 ,app.vue里面的id 会最终渲染到DOM结构里,并且写的其他标签 要放到那个div里面 而且template下级 只能有一个div

3.出现在dom中的是app.vue里面的带id#app的div,index.html 里面那个ID只在node环境用,打包以后就渲染成挂载的app.vue的页面了。index中的id为#app的用于挂载,app.vue中的id为app的用于渲染

在项目入口文件app.vue里面加上<router-view></router-view> //不加的话控制台不报错,但是组件始终渲染不出来,以前不熟悉的时候忘了在这里写上视图容器反正纠结过很久

 

三、import  from
刚开始接触vue,下面这段代码看的不明白,总觉的这个路径不对

import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import './less/index'

后来网上查询,看到简书上有个人总结的,才明白
解释代码之前,先来看我的项目文档(这5行代码位于main.js中):

那么现在我对上述代码一一作出解释:
import Vue from 'vue'     最完整的写法是:import Vue from "../node_modules/vue/dist/vue.js"
import App from './App'    最完整的写法是:import App from './App.vue'
import router from './route'    最完整的写法是:import router from './route.js'
import axios from 'axios'    最完整的写法是:import axios from '..\node_modules\axios\dist\axios.js'
和引入vue文件是一样的原理,都是从node_modules中加载相应名称的模块。
import './less/index'     最完整的写法是:import './less/index.less'
而且不难发现后缀名都省略了,那是不是所有文件的后缀都可以省略呢?不是的

resolve: {
    extensions: ['.js', '.vue', '.json', '.styl'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      '#': resolve('src/common')
    }
  }

extensions指定了可导入的文件类型,vue1.x是在webpack.base.conf.js中设定,2.x需要自己写一个vue.config文件,在里面设定。
图上可导入的类型中,.js  .vue  .styl 都是可以省略后缀,.json不能省略(特殊)
如果test.js 和 test.vue是在同一个文件夹下,那导入的顺序是js>vue
from 后面的来源可以是文件,也可以是文件夹,导入的组件需要注册才能使用

//导入需要的组件
import { NavBar, Tab, Tabs } from 'vant'
import { BaiduMap, BmMarker } from 'vue-baidu-map/components'

//注册后才能使用
components: {
    BaiduMap,
    BmMarker,
    [NavBar.name]: NavBar,
    [Tab.name]: Tab,
    [Tabs.name]: Tabs,
    RealTime: () => import('./real-time'), //组件的懒加载
    History: () => import('./history')  
}

有的项目里面写

import bordertip from '@/components/bordertip/bordertip'
import { wxConfig } from '#/js/wxconfig'

这个@ #  什么指代呢?
事实上也在配置文件里,里面有alias  这里指代了
@号替代src/components
#号替代src/common
在js中导入模板文件或js可以像上面一样使用,但是在 css 文件,如 less, sass, stylus 中,使用 @import "@/style/theme" 的语法引用相对 @ 的目录确会报错,”找不到 ‘@’ 目录”,说明 webpack 没有正确识别资源相对路径。
解决方法
在引用路径的字符串最前面添加上 ~ 符号,如下

@import '~@/assets/css/all.scss';//这里assets是src目录下的文件夹

各类非 js 直接引用(import require)静态资源,依赖相对路径加载问题,都可以用 ~ 语法完美解决

css module 中: @import "~@/style/theme"
css 属性中: background: url("~@/assets/xxx.jpg")
html 标签中: <img src="~@/assets/xxx.jpg" alt="alias">

**总结:**
1.import...from...的from命令后面可以跟很多路径格式,若只给出vue,axios这样的包名,则会自动到node_modules中加载;若给出相对路径及文件前缀,则到指定位置寻找。
2.可以加载各种各样的文件:.js、.vue、.less等等。
3.可以省略掉from直接引入。
4.有些后缀名省略了
5.可以用别名替代某些指代的文件夹

参考:ES6神奇的import...from...命令
参考:Vue中import from的来源:省略后缀与加载文件夹
参考:Webpack 中 css import 使用 alias 相对路径

四、router
router index.js 把准备好路由组件注册到路由里

第一步:在src目录下面新建一个router文件夹,里面index.js存放路由

import Vue from 'vue' //注:这句必须要有//注:这句必须要有,虽然在main.js里面已经引入过Vue,但是这里不要这句的话,就直接报错了Vue is not defined
import Router from 'vue-router'  //加载路由

Vue.use(Router)  //告诉vue使用路由

const router = new Router({
  routes: [{  //注:此处的方法名,记住这里是routes,不是routers,没有r,要是写成routers,控制台不会报错,就是渲染不出组件来,牢记啊!不然会让人崩溃的
      path: '/',
      redirect: '/shangjie'
    },
    {
      path: '/quyu',
      name: 'quyu',
      component: () => import('##/quyu/quyu')  //注:此处容易跟着代码提示一不小心写成components,要注意,控制台报错TypeError: Cannot read property '$createElement' of undefined
    },
    ……
],
  linkActiveClass: 'tab-active'
})

第二步:main.js里面的内容

import Vue from 'vue'
import router from './router'  //import后面的router只能写成router,且首字母大写都不行,不然在下面new Vue里面注入的时候控制台会报错Cannot read property 'matched' of undefined
import App from './App'  

Vue.config.productionTip = false

new Vue({
  router, //记得在这里注册引入的router
  render: h => h(App)
}).$mount('#app')

第三步:在项目入口文件app.vue里面加上<router-view></router-view> //不加的话控制台不报错,但是组件始终渲染不出来,以前不熟悉的时候忘了在这里写上视图容器反正纠结过很久

总结

容易出错的地方大概有以下几点

1.新建的router文件夹的index.js文件没有引入import Vue from 'vue'这句话,导致报错Vue is not defined

2.在new VueRouter实例中的数组变量名routes写成routers,控制台不报错,但就是渲染不出组件内容

3.main.js中引入router配置文件时命名变量名不是router,或者首字母写成大写,导致报错Cannot read property 'matched'

4.接着第三点在引入了router之后,忘记在下面new Vue实例中注册,报错Cannot read property 'matched' of undefined"

5.在app.vue里面忘了写路由视图组件<router-view></router-view>

参考:vue router引入路由与路由配置容易犯错的地方与常见的报错与处理报错

路由懒加载

路由懒加载是为了解决白屏问题,让首屏组件加载更快一些

懒加载就是延迟加载或者按需加载

常用的懒加载方式有两种,一是vue异步组件    二是使用ES6的import (推荐)

import vue from 'vue'
import Router from 'vue-router'

vue.use(Router)

const main = () => import('##/main/main')

const router = new Router({
  routes: [
    {
      path: '/',
      redirect: '/home'
    },
    {
      name: 'login',
      path: '/login',
      component: () => import('##/login/login') //这种就是懒加载
    },
    {
      path: '/',
      component: main,
      children: [
        {
          path: '/home',
          name: 'home',
          component: () => import('##/home/home')
        }
      ]
    },
    {
      path: '/',
      component: main,
      children: [
        {
          path: 'equipment',
          name: 'equipment',
          component: () => import('##/equipment/equipment')
        }
      ]
    }
  ]
})

export default router

组件也可以懒加载

1.原来组件中的写法

<template>
  <div class="hello">
  <One-com></One-com>
  1111
  </div>
</template>

<script>
import One from './one'
export default {
  components:{
    "One-com":One
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

2.ES6使用import懒加载(推荐)

<template>
  <div class="hello">
  <One-com></One-com>
  1111
  </div>
</template>

<script>
const One = ()=>import("./one");
export default {
  components:{
    "One-com":One
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

3.异步加载

<template>
  <div class="hello">
  <One-com></One-com>
  1111
  </div>
</template>

<script>
export default {
  components:{
    "One-com":resolve=>(['./one'],resolve)
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

参考:vue路由懒加载及组件懒加载

Logo

前往低代码交流专区

更多推荐