5、main.js,app.vue,import from,router
一、main.jsmain.js是程序的入口,用于初始化vue实例,使用需要的插件,加载公共组件需要导入import Vue from 'vue'import router from './router'import App from './App'main.js中导入router import router from './router' ////import后面的rou...
一、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>
更多推荐
所有评论(0)