文章目录
- 2018年12月27日 星期四
- 第94个视频 - 安装CLI错误和ESLint规范
- 第95个视频 - runtime-compiler和runtime-only的区别
- 第96个视频 - vue cli3创建项目和目录结构
- 第97个视频 - vuecli3配置文件的查看和修改
- 第98个视频 - 箭头函数的使用和this指向
- 2018年12月27日下午
- 第99个视频 - 什么是路由和其中映射关系
- 第100个视频 - 前端渲染后端渲染和前端路由后端路由
- 第101个视频 - url的hash和html5的history
- 第102个视频 - vue-router的安装和配置方式
- 第103个视频 - 路由映射配置和呈现出来
- 第104个视频 - 路由的默认值和修改为history模式
- 第105个视频 - router-link的其他属性补充
- 第106个视频 - 通过代码跳转路由
2018年12月27日 星期四
第六天
第94个视频 - 安装CLI错误和ESLint规范
这两天要学习的内容,主要如图所示
昨天有个同学安装npm install @vue/cli -g
不成功,管理员运行cmd,运行npm clean cache -force
,清空缓存。
创建两个项目runtimecompiler和runtimeonly
eslint演示
用这个ESLint相当不方便。
王红元写js是不加分号的。在js当中可以加分号,也不可以加分号的。王红元前段时间是做了python课程,习惯了不加分号。
eslint的规范来说,是不让加分号的。
你可能完全不让用这个玩意。有可能公司要求用这个玩意,你只能习惯。
eslint让代码更规范,可能也打破了你的习惯。所以我们尽可能不用这个破玩意了。
有可能一开始的时候年少无知,创建项目的时候,选择了eslint,后来就不想用了,那怎么办呢?
怎么关闭这个eslint呢?
第95个视频 - runtime-compiler和runtime-only的区别
runtime-compiler和runtim-only的区别,就在main.js当中,我们可以看下面的图:
runtime-compiler当中,我们使用App组件是先在components当中注册,然后在vue实例的template当中使用。
runtime-only当中,它没有注册组件,而是使用了一个render属性:h => h(App),这是一个箭头函数。箭头函数就相当于是一个匿名函数,箭头的左边就是参数,箭头的右边就是返回值。
相当于下面的代码:
也就是说这个render属性是一个函数。
这个render函数里面的h是一个缩写。
要想理解这个render函数,我们必须先来讲讲vue程序运行过程。
vue程序运行过程
- 当我们把一个template传给vue的时候,vue内部就会在vm.options.template当中进行一个保存。
- 接着,会对template进行parse,就是解析,会把template解析成为ast。ast完整的写法叫做抽象语法树。abstract syntax tree。这个东西还是比较复杂的。
- 然后就会进行compile,就是编译成为vm.options.render(functions)。
- 通过render函数将我们对应的template,最终翻译成为virtual dom,也就是虚拟dom。创建虚拟dom节点,变成虚拟dom树。
- 最终虚拟dom树渲染到ui当中。
- 总结:template - > ast -> render() -> virtual dom -> ui(真实dom)
因此在runtimecompiler项目中,就是template经过ast,经过render(),经过virtual dom,变成了dom。
在runtimeonly项目中,没有template,直接就是render(),render函数到了virtual dom,到了dom UI。
也就是runtimeonly比runtimecompiler少了环节,性能更高,代码量更少。
我们以后开发中,就要选择runtimeonly。
render函数是什么?
我们的runtimecompiler项目中,也可以使用render函数,我们改写一下。
我们可以写一个render属性,然后写一个匿名函数,参数是h,这个h指代的是vue内部的一个creatElement函数。
creatElement函数
creatElement函数有三个参数,第一个参数是标签,第二个参数是一个对象,对象里面放的是标签的属性。第三个参数是一个数组,数组里面放置的就是标签当中的内容。
我们可以直观看下面的图片:
这个效果应该是使用h2标签,将el里面挂载indexhtml当中的id为app的div,替换掉。
我们可以编译一下项目,看看是不是这个效果:
到这里之后,重新编译成功了。
看看页面效果:
既然creatElement函数的第三个参数,是一个数组,我们还有第二种写法:
我们可以看到页面是这样的效果:
上面讲的就是creatElement的普通用法:
这个createElement还有第二个用法,就是传入一个组件对象。
我们之前写组件的时候,就是可以直接写一个对象的,如图:
然后我们可以vue实例当中的components当中注册,然后在template当中使用,然后去替换vue实例的el。
我们的creatElement函数当中,第二个用法,就是可以直接传入一个组件的:
我们这样的写法,就可以将cpn组件,直接替换了el挂载的div标签,这里面没有vue实例的template了,不需要进行编译了,直接由render函数渲染成为虚拟dom,在页面展示。
既然能够传入我们上面写的cpn组件,肯定是可以传入我们的.vue文件的组件的。
然后我们跑一下。
这样就跟runtimeonly项目当中的main.js一样了。
小疑惑?
老师你说runtimeonly当中是没有template到ast到render函数,这个部分的代码的。
那么我们的组件App.vue当中的template咋整呢?
难道这里的template不需要经过ast到render函数的步骤吗?
是,不需要的。
为什么呢?
因为App.vue最终被编译出来的,就是一个普通的对象,这个普通的对象已经将template渲染成render函数了。
这个普通的对象传入了createElement函数当中。
我们可以在main.js当中打印一下App对象,看一下:
我们可以看到打印结果是:
我们可以看到这里面,根本就没有App.vue文件中的template,而是在对象中,多了一个render函数。
也就是说。
.vue
文件中的template,是谁处理的呢?
是由我们安装的vue-template-compiler来进行处理的。
之前,在我们讲解webpack配置vue的时候,为了让webpack能够打包.vue
文件。我们安装了vue-loader,我们也安装了vue-template-compiler。
这里的vue-loader是加载.vue
文件的。解析.vue
文件是用vue-template-compiler,这个东西就是将.vue
文件中的template解析成为了render函数了。
所以,最终我们在项目的main.js当中引用vue文件的时候,引入的并不是template,而是经过vue-template-compiler解析的对象。
这个对象里面没有包含任何的template。而这个vue-template-compiler只是一个开发时依赖。也就是说,我们最终运行的项目中,所有的组件都不包含template。
所以,我们在生产运行时,使用vue的时候,我们没有必要使用runtime-compiler版本的vue,所有的.vue
文件都已经经过开发时依赖的vue-template-compiler变成了普通对象,template变成了render函数了。
所以,我们最终使用runtime-only版本的vue,就可以了。这就是开发当中,我们只使用runtime-only版本的vue的原因,代码量更少,性能更高。
第96个视频 - vue cli3创建项目和目录结构
npm run build
npm run dev
修改webpack配置起别名
这个部分先不讲,到项目当中再讲。
webpack cli3
现在vue的版本是2.5.21,王红元个人估计,会在2019年5月或6月份发布vue 3.x。
vue的2.x当中为了增加类型检查,加入了一个东西,叫做flowtype。
用来做一些类型检测,这是facebook的一个东西。
但是在vue的3.x中,不打算用flowtype了,打算转向typescript,这是微软开源的语言。
可能到时候也会讲typescript。
现在发布的玩意,叫做vue cli3,是脚手架3。
也就是2018年8月11日发布的脚手架3,现在网上的项目70-80%,还是用脚手架2。
如果是新的项目,最好是用脚手架3。
脚手架2和脚手架3有啥区别
脚手架3当中,直接把脚手架2当中的build和config配置,移除掉了。就看不到这些配置了。
但是你想要改webpack的配置的时候,也可以,后面再讲。
webpack3和webpack4确实也有很多区别,webpack4也有很多链式配置的方案。
脚手架3还提供了一个命令,vue ui,可以在可视化地进行配置。
脚手架2当中的static文件夹,原来放静态资源,可以直接原封不动复制到dist文件夹中。
使用脚手架3来构建项目
我们使用vue create testvuecli3
使用脚手架3,来创建一个testvuecli3的项目。
这是让我们选择一个配置,preset,就是配置的意思。
default就是默认的配置,manually是手动的意思。
我们选择手动,我们看看哪些是可以配置的。
有这么多选项,选中按空格,取消也是按空格。
我们要在这里,把Linter取消掉,这就是类似vue cli2当中的eslint的。
css pre-processors,如果你想用less可以选这个。
typescript里面语法很多,很像java,接口,泛型之类的。
还有一个叫Progressive Web App(PWA)Support,Progressive是先进的意思,PWA就是先进的web app。
以前的app,想要本地进行一些存储的时候,是比较难的。
我们更多是使用session_storage,效率低,存储有限。
而PWA可以缓存很多东西。另外PWA还可以推送通知。
PWA现在用的还不是特别多,谷歌、阿里有一些产品用这个PWA。
下课有兴趣可以了解。
dedicated是独立的意思,意思就是某些配置文件,你是想放到package.json,还是想要单独的一个配置文件,一般王红元喜欢选择第一个。
这个选项的意思,是,是否将这个配置,作为未来项目的配置参考呢?
我们选择yes。
就是准备将之前的配置,保存一个什么名字呢?
我们在这里输入一个名字。
下一次,我们创建项目的时候,就会看到我们保存的配置:
如果后面不想用了,可以删掉吗?是可以的。
打开电脑这个位置:
为什么很多东西配置文件的后缀名都叫rc呢?在linux中,很多文件命名,和终端相关的,都叫做rc,意思就是run command。
可以在这里删除。
这个还是选,用npm,还是用yarn。
我们还是选npm。
王红元在这里讲了一点git。
说自己不喜欢用webstorm中的版本控制功能,比较喜欢用终端:
脚手架2和脚手架3的目录对比
.postcssrc.js
是css转换的文件。很少改动。
-
package-lock.json也讲过了,这是个中间文件,显示的是在node当中,真实安装的包版本是什么。
-
README.md就是一个说明文件。
怎么跑脚手架3的项目
我们怎么跑脚手架3创建的项目呢?
在脚手架2当中,我们是使用npm run dev
或者npm run start
来跑的。
这是因为在项目的pakcage.json当中,有对应的配置,如下图所示:
在脚手架3当中,我们也去查看一下package.json,然后去看看,配置了什么命令:
我们看到里面配置了serve,这个就是用来跑项目的命令。
为什么是serve呢?我们前面提到过,在脚手架3当中,是通过@vue/cli-service
这个东西,来间接管理我们的包的。
所以,现在是零配置,执行的是哪个配置文件,看不到了。
在脚手架2当中,还记得吗?我们是通过npm run dev之后,执行的是build.js这个配置文件,现在是完犊子了,什么都看不到了。
在脚手架3当中,我们直接执行:npm run serve
就跑起来了。
脚手架3的src文件夹
这个就是src文件夹中的main.js文件的显示内容。
Vue.config.productionTip = false。
这个是什么意思呢?
我们在构建项目的时候,会有一些提示信息,就是在执行npm run build的时候。
但是,我们在npm run serve的时候,是不需要这些信息的。
所以,我们可以设置为false。
发布的时候,可以设置为true,到时候终端这里会有很多的信息,构建了什么信息之类的。用处不是很大。
重点是下面的vue实例的代码:
这个玩意,跟我们之前写的玩意,不太一样哦。跟我们脚手架2当中的东西。
那么应该怎么办呢?
new Vue({
el: '#app',
render: h => h(App)
})
new Vue({
el: '#app',
render: function (h) {
return h(App)
}
})
我们现在,脚手架3当中,main.js当中的代码是:
new Vue({
render: function (h) {
return h(App)
}
}).$mount('#app')
这种$mount的写法,跟el的写法,内部没有区别。
- 内部当你把el传进去的时候,内部还是执行$mount这种东西的。
- 如果你是el的写法,vue的内部会判断,你有没有这个属性。如果你有这个el属性,内部执行$mount。
- 如果你是自己用了$mount,那就不会判断了。
- 最终挂载的东西,都会被我们render出来的东西替换掉。
第97个视频 - vuecli3配置文件的查看和修改
在vuecli3当中,你想要修改配置的话,有三种方案。
vue ui
第一种方案就是启动一个服务vue ui。
我们是通过npm install @vue-cli -g
这种指令去安装脚手架3的。
这个指令的执行,安装了vue,我们可以使用vue init webpack 或者vue creat创建项目。这里面,还包含了一个vue ui的东西。
当执行这个指令的时候,会启动一个本地服务,会管理项目的。
这个指令在哪个目录下执行,都可以的。
在终端执行了vue ui之后,看到的就是这样的,一个页面。
我们选择03-testvuecli3,这是用脚手架3,创建的项目。
然后,我们点击导入文件夹,然后进入的,就是下面的文件:
点击第二个Plugins,看到的就是下面的内容:
现在显示的插件,跟package.json当中的devDependencies是一样的内容。
我们点击第三个图标dependencies,看到是下面的内容:
vue-template-compiler是归类到了依赖当中。
vue-template-compiler的版本和vue的版本肯定是一样的。截止目前为止(2018年12月27日)。
上面的都是依赖的管理。
还可以点击configuration这个地方的配置。
第一个是public path,配置base url。
第二个是输出目录,输出到dist文件件当中。
这两个东西,我们都很少改。
这些,都是属于webpack相关的配置。
第三个是静态资源。
如果你启动了运行时编译,你用的就是runtime-compiler版本了,默认用的是runtime-only。
这个表示,会生成一个文件,.map
的文件,这个文件后面是用于我们调试代码用的。
sourcemap是一个比较大的东西,如果要讲的话,要讲的内容是很多的。
上面的图,就是并行编译的意思。
上面的图,是css相关的配置,默认情况下,是只编译css相关的文件。
如果你想要用less,就可以在这里增加。
王红元个人很少在vue ui当中改这些配置。
还有任务的标签页:
这里还有一些统计信息,真的是非常棒。
找到vuecli3的配置
在脚手架2当中是专门有两个文件夹,build和config文件夹,是用来放置,我们的webpack的相关的配置的。
在脚手架3当中,配置都是被隐藏掉了。
我们可以通过如图的步骤,找到对应的位置。
我们可以看到,在webpack.config.js当中,有一个句子,通过commonjs的语法require引入了Service.js。
我们可以看到,上面图中展示的,就是隐藏起来的配置。
在Service.js当中,还引用了很多的配置。这些配置都在config文件夹下。
修改webpack的默认配置
需要在自己当前项目目录下,创建一个文件,叫做vue.config.js
。
你在这里写的配置,会和默认的配置,一起进行合并,作为webpack整体的配置。
这个文件的名字,不能够修改。
第98个视频 - 箭头函数的使用和this指向
箭头函数的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 箭头函数:一种定义函数的方式
// 1. 定义函数的方式:function
const aaa = function () {
}
// 2. 对象字面量中定义函数
const obj = {
bbb: function () {
}
}
const obj2 = {
bbb(){
}
}
// 3. es6中的箭头函数
const ccc = function () {
}
// const ddd = (参数列表) => {函数代码体}
const cccc = () => {}
</script>
</body>
</html>
参数和返回值的问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 1. 参数问题
// 1.1 放入两个参数的问题
const sum = (num1, num2) => {
return num1 + num2;
};
// 1.2 放入一个参数的问题
const power = (num) => {
return num * num;
};
const power1 = num => {
return num * num;
};
// 2. 函数中的代码体的问题
// 2.1. 函数代码块当中有多行代码
const test = () => {
// 1. 打印hello world
console.log('hello world');
console.log('hello vuejs');
};
// 2.2. 函数代码块中只有一行代码
const mul = (num1, num2) => num1 * num2;
console.log(mul(20, 30));
// 2.3 没有返回值,只有一行代码,log函数没有返回值,返回值就是undefined。
const demo = () => console.log('hello demo')
</script>
</body>
</html>
箭头函数中this的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 什么时候,使用箭头函数
// 当我们准备把一个函数,传到另外的一个函数中的时候,使用箭头函数
setTimeout(() => {
console.log(this); // Window对象
}, 1000);
setTimeout(function () {
console.log(this); // Window对象
}, 1000);
// 结论: stack over flow上面有一个帖子,专门讨论箭头函数当中的this到底是指向谁的。
// 问题:箭头函数中的this是如何查找的呢?
// 答案:向外层作用域中,一层一层查找,直到有this的定义。
//
const obj = {
aaa() {
// 这里面的function在调用的时候,是通过call,
// call会把Window作为第一个参数传进去的。
setTimeout(function () {
console.log(this); // Window对象
}, 1000);
// 这里面的箭头函数,执行逻辑和上面的不同。
// 箭头函数的{}中是没有this这样的变量或者关键字的。
// 会向外查找。
// 向外找一层作用域就是aaa的{}
// 在aaa这个函数作用域当中,是有this的。
// aaa这个函数是在对象当中定义的。
// 一旦一个函数,是在对象当中定义的,只要用this,就是用的当前对象。
// 所以aaa这个函数当中的this就是obj对象。
setTimeout(() => {
console.log(this); // obj对象
});
}
};
obj.aaa();
//---------------------------
const obj = {
aaa() {
setTimeout(function () {
setTimeout(function () {
console.log(this); // Window
});
setTimeout(() => {
console.log(this); // Window
});
});
setTimeout(() => {
setTimeout(function () {
console.log(this); // Window
});
setTimeout(() => {
console.log(this); // obj
});
});
},
};
</script>
</body>
</html>
2018年12月27日下午
第99个视频 - 什么是路由和其中映射关系
很多人不太懂什么是前端路由。
第100个视频 - 前端渲染后端渲染和前端路由后端路由
什么是前端渲染什么是后端渲染
这要从网页的历史讲起来。
以前的网页开发,都是使用jsp、php、asp来进行开发的。
以前是没有js的,jsp叫做java server page。
用java写出来一个网页,传到浏览器,让浏览器展示。
现在淘宝这种网页,应该还是使用后端渲染的。
因为后端渲染对SEO优化支持比较好。
我们在浏览器当中输入一个:https://www.taobao.com。
浏览器会把这个url发给服务器。
服务器拿到这个url之后,第一步要解析看看你要请求的是什么样的网页。
后台会通过jsp的技术,会直接把网页写好。包含html、css,并且包含java代码。
java代码的作用是从数据库中读取数据,并且动态放在页面当中。
最终我们的页面,在服务器就已经生成了。
以前的网页是没有ajax请求的。
服务器端是最终的网页。直接将最终的网页传给浏览器。
传给浏览器的网页,只有html和css,当然里面还包含一些数据。
这个东西,就叫做后端渲染。整个网页渲染是在后端完成的,通过jsp已经渲染好了。
这个东西,就叫做服务端渲染,也叫做后端渲染。
我们在淘宝首页,点击男装后,又来到了一个网页:
淘宝男装这个页面新的网址,就会发给服务器,url2。
服务器会对这个url2做一个解析,然后还是jsp的技术,生成一个网页,发给浏览器。
也就是说一个url,就生成一个网页。
在服务器这里,已经形成了这么一种映射关系。一个url对应一个页面。
这种映射关系,是服务器在处理。
后端处理url和页面之间的关系,这种路由,就叫做后端路由。
学习原生js和ajax的时候,就是前后端分离阶段。
不需要使用java代码,将数据嵌入到html代码当中了。
前后端分离
后端只负责提供数据,不负责任何前端的内容展示。
我们有一个浏览器,有一个服务器(提供接口),提供一个静态资源服务器。
接口服务器使用apache tomcat,静态资源服务器使用nginx。
前端为了获取数据,要经常发送ajax请求,服务器把数据给前端。
然后前端通过js动态创建一些div标签,ul标签,li标签,动态放到浏览器上进行渲染。
以前开发的html代码和css代码,并不是一开始就在用户浏览器这里的。
用户浏览器中输入了url,需要去服务器拿到一些东西,包括:html、css、js。
这样,这三个东西已经跑到浏览器这里了。
html和css这些代码,浏览器是可以直接渲染的。
js这些东西,浏览器是必须执行的。
比方你写了$ajax(url: api接口,success: function)。
这就会通过网络请求api服务器。
api服务器会返回大量的数据。
接下来,再通过其他的,大量的js代码,创建div标签,插入到html代码中。
这些数据不是在服务器渲染好的,是ajax请求数据后,由我们写js代码,请求写好的。
这个前后端分离的阶段,就叫做前端渲染。
浏览器中显示的,网页中的大部分内容,都是由我们前端写的js代码,在浏览器中执行,最终渲染出来的网页。
现在我们整个的网页,大部分的渲染, 都是我们的浏览器帮助我们完成的。这个过程就叫做前端渲染。
在这里其实没有什么,前端路由和后端路由的概念。
前端路由
在前后端分离的情况下,加上前端路由,变成SPA,单页面富应用。
我们在浏览器输入url,会先去浏览器中请求html,css,js。
第三个阶段,就是我们的前端路由阶段,spa页面。
一般情况下,我们的整个网站,只有一个html网页。
spa叫做simple page web application。
spa在静态资源服务器中放置的资源,和前后端分离阶段放置的静态资源有什么不同呢?
如果是前后端分离的接口,在静态资源服务器上放置了好几套的html+css+javascript。
每一套的html+css+js对应一个url。
在spa中,在静态资源服务器当中,只有一个index.html,另外就是css,还有js,更多时候,只有一个js。
极端情况下,html+css+js都只有一个。
按照以前的理解,好像是只开发了一个网页。
假如我们自己开发了一个网站:coderwhy.com,输入这个url,会从静态资源服务器,把html+css+javascript都请求下来了。
当你把静态资源都请求下来的时候,并不会把所有的东西都渲染出来的。
当我点击某个按钮的时候,显示对应的东西。怎么说呢,大致可以看下面的示意图:
怎么把一个页面分成三个页面呢?
需要前端路由来做支撑。
前端路由当中会配置一些映射关系。
什么映射关系呢?
当我点击某个按钮的时候,会生成一个url,例如点击首页,生成coderwhy/home。
之前前后端分离的时候,一旦有新的url,立马会去静态服务器请求一套资源的。
但是现在不这么做了。
在前端路由当中,通过js代码的判断,将我们需要对应显示的内容抽离出来。
我们之前写vue文件,一个vue文件,就是一个组件。
我们使用webpack进行打包的时候,会打包到一个js文件当中。
一旦浏览器上出现了对应的url,就会去大的js文件当中,找到组件相关的东西,渲染出来。
url和组件页面的映射关系,就是前端路由管理的。
一个url,对应一个jsp页面,后端路由。
一个url,对应一套静态资源,前后端分离。
一个url,对应一个组件或页面,前端路由。
spa页面就是在前后端分离的基础上,加上了前端路由。
改变url的时候,页面是不刷新的。
第101个视频 - url的hash和html5的history
前端路由就是要做到,url改变的,但是页面不要刷新,不要向服务器重新请求资源。
url的hash
在浏览器中,我们通过location.hash,修改了页面的url,追加了aaa
,但是页面没有发生刷新,没有重新请求资源。
html5的history对象
在html5当中有一个history的对象,你通过这个东西修改url的话,也是不会有任何的刷新的。
栈结构
push在数据结构的栈结构的时候,用的比较多。push就是压栈。
什么是栈结构呢?
栈结构只有一个入口和出口。如果往里面放一个东西,就是入栈,就是push。
如果想要从栈当中取出来东西,只能从栈顶拿。
先进后出,后进先出。
html5的history对象
history.pushState({}, ’ ', ‘home’),入栈
history.back(),出栈。
html的history的模式中pushState方法改变url,会有历史记录的。
replaceState()方法中,是没有历史记录的,不能够返回。
history模式的go
history.go(-1) // 这个方法,等同于history.back()
history.go(-2)
history.go(2)
history对象的五个方法
- history.pushState()
- history.replaceState()
- history.go()
- history.back()
- history.forward()
以后在开放当中,有两种模式可以选择,一种默认就是hash的方式,另外就是history的方式。
第102个视频 - vue-router的安装和配置方式
只要url发生了改变,就会加载对应的组件。把对应的组件渲染到页面当中。
-
第一步,我们是要在项目文件夹下的src文件夹下面,创建一个router文件件,我们在这个文件夹当中,主要是放置所有的路由相关的配置。
-
第二步,我们在router文件夹下面创建一个index.js文件,在这个js文件当中配置路由相关的信息。
-
vue-router是我们安装的一个vue的插件,我们首先是要导入这个插件:
import VueRouter from 'vue-router';
-
第一步
- 在vue当中,我们使用插件都是要通过
Vue.use(插件)
这样的方法来进行使用的。所以,我们也需要导入vue。import Vue from 'vue';
。 - 然后我们安装插件:
Vue.use(VueRouter);
- 在vue当中,我们使用插件都是要通过
-
第二步
-
使用vue-router插件来创建路由对象:
const router = new VueRouter()
。 -
在通过new创建对象的时候,传入一个options对象:
const router = new VueRouter({})
。 -
在options对象当中,我们主要是设置一个routes属性。注意routes属性和router的拼写区别。
-
这个属性的值,是一个数组。
-
// 2. 创建VueRouter对象 const routes = [ ] const router = new VueRouter({ // 配置路径和组件之间的映射关系 // routes: [ // // ] routes });
-
为了方便,我们可以创建一个routes对象,然后使用对象属性字面量的增强写法。
-
然后就可以在这个routes数组当中配置
url和路径的对应关系
。
-
-
第三步
- 将我们通过vue-router插件创建的router对象,传入到vue实例当中。这个需要我们在router/index.js当中导出我们的router对象。
export default router
-
-
在我们的项目的入口文件main.js当中,我们导入我们的路由对象,然后挂载到vue实例当中,就可以对我们的vue实例生效了。
整体的代码如下所示:
index.js
import VueRouter from 'vue-router';
import Vue from 'vue';
// 1. 通过Vue.use(插件)来安装这个插件。
// 任何的插件,都是通过Vue.use(插件)来安装这个插件。
Vue.use(VueRouter);
// 2. 创建VueRouter对象
const routes = [
]
const router = new VueRouter({
// 配置路径和组件之间的映射关系
// routes: [
//
// ]
routes
});
// 3. 将我们的router对象传入到vue实例当中。
export default router
main.js
import Vue from 'vue';
import App from './App';
//import router from './router/index' // 当你导入的是一个目录的时候,会自动寻找目录当中的index.js文件的。
import router from './router';
Vue.config.productionTip = false;
new Vue({
el: '#app',
// router: router,
router,
render: h => h(App)
});
第103个视频 - 路由映射配置和呈现出来
第一步:删除新建项目当中的垃圾
- 第一个垃圾就是components文件夹下面的HelloWorld.vue组件。
- 第二个垃圾就是我们App.vue当中的垃圾
使用vue-router的第一步
创建路由组件:
我们创建了两个.vue
文件的组件。分别象征性写了一点内容。
使用vue-router的第二步
配置路由映射,也就是在router文件夹下面的index.js当中,在routes对象当中配置路由映射关系。
第一个要注意的点,就是一个映射关系就是一个对象。对象的属性,我们现在就配置path和component。
第二个要注意的点,这里是component,而不是components。
我在操作的过程当中,就是因为配置了components,所以出现很多错误。我还以为是我的vue-router的版本的问题呢。折腾了一会儿。
参考这个文章解决错误。
使用vue-router的第三步
使用路由。我们是在我们的App.vue当中来使用路由。
这里需要用到两个标签。
- 第一个就是router-link标签,这个是我们的vue-router插件注册的全局组件,可以在任何地方使用的。
- router-link标签最终是会被渲染成为a标签的。
- 然后就是router-view了。router-view就是相当于占位了,就是组件内容展示的位置。你把router-view放置在router-link的上面或者下面,那么对应的组件的内容,就会在上面或下面进行显示了, 就是这么申请的啦。
总结
- 创建两个路由组件。
- 在路由配置文件当中配置路由对象,配置path和component
- 在我们的App.vue当中使用router-link和router-view
第104个视频 - 路由的默认值和修改为history模式
细节一 - 重定向
用户第一次进入到网页的时候,应该默认到home页面。
在代码当中的配置如下:
{
path: '',
redirect: '/home'
},
path这里写不写/
都可以的。
细节二:history模式
默认情况下路径的模式是location.hash的这种模式。这种模式的路径风格是这样的:
看起来是有点难看的。
我们希望修改成为h5的history模式。
这样设置:
修改过之后,路径就变成了,这样的风格。
第105个视频 - router-link的其他属性补充
我们之前只是使用了router-link的to属性,如下图所示:
tag属性
还有一个属性,叫做tag属性。做什么呢?
router-link最终渲染成为a标签的。但是开发过程当中,我不想要让它渲染成为a标签。我想要一个button。
或者我想要渲染出来是一个div。那应该怎么办呢?
我们增加一个tag属性就可以了。如下图:
replace属性
现在我们的项目的路由的模式是history模式的。
我们的history模式默认使用的是pushState方法的。
这种情况下,我们是可以通过浏览器的返回按钮来进行返回的。
但是,我的需求是,我不希望用户通过浏览器的返回按钮来进行返回,而是必须通过点击我们的页面的按钮来提供返回。
这个时候应该怎么办呢?
我们肯定是想要将pushState修改为replaceState这种方法的。
那么我们怎么样router-link知道,我们应该使用replaceState方法呢?
active-class属性
这两个按钮,被点中的时候,就会处于活跃状态了。你只要点了谁,就会在对应的标签上面,增加对应的class。
一个是router-link-exact-active,这个class先不要看,这个class是跟我们的路由嵌套有关系的。
一个是router-link-active。
这个class是有什么用呢?
假设我提交了一个需求:我点击哪个按钮,哪个按钮的字体颜色变成绿色?
那我们就可以根据这些class来实现这个需求了。
我们的需求是:我们的class不想要叫router-link-active这个名字了,我们想要定义叫做active-class。
这个怎么改呢?
在实际的开发过程中,我们很少改变这种。
这里有一点不好,假设我们上面的图中,有很多很多的router-link,我们不是要全部都写一下class吗?
路由相关的配置,都在我们的index.js当中。
第106个视频 - 通过代码跳转路由
组件的$router属性
刚才为了让路由组件之间能够跳转,我们使用了router-link标签。
如果我们不想要写router-link呢?
我们写的是两个按钮,并且监听点击。
但是我们监听点击,我们怎么样才能够实现跳转呢?
我们怎么样通过代码的方式来修改路径呢?
难道说我们可以拿到history对象,然后通过pushState的方法来修改路径的吗?
不要这样做,这样是绕过了我们的vue-router来修改路径,是不好的。
vue-router的源码当中,给我们所有的组件当中,都加入了属性,叫做$router属性。
我们可以使用这个$router的push方法,就可以了。
这样我就通过代码的方式,来实现了跳转。
我们使用push方法,等于使用history的pushState方法。
如果我们不想要用push方法,我们就可以使用$router的replaceState方法。