四、路由嵌套
1.搭建
首先创建工程和对应的目录,但是不将vue.js和vue.router.js导入进来,而是直接cmd到对应folder进行下载。
注意:在这里有必要说一句,作者使用的是webpack 4.x.x,所以可以不手动去写webpack.config.js,此文件的作用仅仅是将默认的./src/index.js的入口文件转换成了./src/vm.js,导出文件由./dist/main.js转换成了./dist/bundle.min.js效果是一样的,并且关于webconfig.js,src,node_modules,dist,vm.js,router.js的相对位置一定不能乱,不然用cmd进行webpack打包操作的时候会说无法找到文件报错
下面开始进行入口文件的初始化。
首先是Vue的初始化
//入口文件
import Vue from 'vue/dist/vue.esm';
import VueRouter from 'vue-router';
import router from './router'
import '../css/main.css'
Vue.use(VueRouter);
let vm = new Vue({
el:'#div1',
data: {},
router
});
然后将引入的路由模块进行完善
router.js
//路由初始化
import VueRouter from 'vue-router';
import Header from './components/header';
import Home from './components/home';
import News from './components/news1'
export default new VueRouter({
routes:[
{
path:'/index',
name:'index',
components:{
header:Header,
default:Home
}
},
{
path:'/news',
name:'news',
components:{
header:Header,
default:News
}
}
]
})
其余的css与js保证有内容即可,这里只搭建框架
然后用我们的index.html进行主页面的引入
<!--主文件-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="div1">
<router-view name="header"></router-view>
<router-view></router-view>
</div>
</body>
<script src="dist/bundle.min.js"></script>
</html>
最后使用webpack进行打包,就可以直接访问index页面了
2.子路由模块
接下来就要体现我们的路由嵌套了,
首先要实现的就是将子路由嵌套进去
router.js
//路由初始化
import VueRouter from 'vue-router';
import Header from './components/header';
import Home from './components/home';
import News from './components/news1'
export default new VueRouter({
routes:[
{
path:'/index',
name:'index',
components:{
header:Header,
default:Home
}
},
{
path:'/news',
name:'news',
components:{
header:Header,
default:News
},
children:[
{
path:'1',
component:{
template:'<div>111</div>'
}
},
{
path:'2',
component:{
template:'<div>222</div>'
}
}
]
}
]
})
现在子路由写完了,但是子路由如何显示出来,就是现在要解决的问题
首先要明确一点,子路由的域名地址,是基于父级路由的,比如父级路由是/a,子路由是/b,那么访问到子路由对应的页面也就是/a/b,所以子路由只能写成相对路径。
那么,知道了这一点,问题也就好办多了,我们只需要和之前一样给子路由在对应的news.js上添加一个router-view就可以让template的内容显示出来了。
news.js
export default {
template:'' +
'<div>' +
'新闻' +
'<router-view></router-view>' +
'</div>'
}
然后重新打包测试。
打包成功。
接下来我们要装配嵌套好的路由,原理很简单,由于我们是在news的模块内插入的子路由,所以我们也只需要在news.js内嵌套一个子路由映射即可,映射地址也就是我们上面所提到的/news/id然后就可以link到我们制定的域名了。
news.js
export default {
template:'' +
'<div>' +
'新闻' +
'<div>'+
'<router-link to="/news/1">新闻1</router-link>'+
'<router-link to="/news/2">新闻2</router-link>'+
'</div>'+
'<router-view></router-view>' +
'</div>'
}
我们也可以进行一些简写,因为子路由是news的,所以我们可以将子路由的json写在news里,然后再用import将模块导入到router.js,注意由于子路由有多种,所以export的时候要以[]列表的形式。
下面就要开始完善我们的子路由了,将完整的news1和news2导入到news.js
首先先随意的写出news1 news2的template
news1.js
export default {
template:'<div>新闻111</div>'
}
然后将两个js文件导入到我们的主路由中
import News1 from './news1';
import News2 from './news2';
export default {
template:'' +
'<div>' +
'新闻' +
'<div>'+
'<router-link to="/news/1">新闻1</router-link>'+
'<router-link to="/news/2">新闻2</router-link>'+
'</div>'+
'<router-view></router-view>' +
'</div>'
}
export let router=[
{
path:'1',
name:'news1',
component:News1
},
{
path:'2',
name:'news2',
component:News2
}
];
注意在这里配置component的时候就可以不用写template了,因为这个属性在子路由的js文件中写过了
五、组件
1.局部组件
首先也还是照常的建立一个工程,配置webpack.config.js等配置文件,在index文件进行装载,和上面不同的是,我们这次采用局部组件的方式
import Vue from 'vue/dist/vue.esm';
let vm = new Vue({
el:'#div1',
data:{},
//局部组件
components:{
cmp1:{
template:'<div>aa</div>'
}
}
});
我们定义了一个name为cmp1的template,这样就可以在index.html内直接用name调用模板了
如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="div1">
<cmp1></cmp1>
</div>
</body>
<script src="dist/bundle.js" charset="utf-8"></script>
</html>
用webpack打包之后来到index页面是可以访问成功的。
这里注意,如果在局部组件内定义data,就必须是函数类型,而不能是json
如下:
import Vue from 'vue/dist/vue.esm';
let vm = new Vue({
el:'#div1',
data:{},
//局部组件
components:{
cmp1:{
data(){
return {a: 12}
},
template:'<div>{{a}}</div>'
}
}
});
这里重新访问,就可以重新得到a的数据了,顺带一提,如果不想cmp1这个标签写在index的主界面,也可以写在vm的自带模板中,去除掉之前的index的cmp1然后如下:
import Vue from 'vue/dist/vue.esm';
let vm = new Vue({
el:'#div1',
data:{},
template:'<div><cmp1/></div>',
//局部组件
components:{
cmp1:{
data(){
return {a: 12}
},
template:'<div>{{a}}</div>'
}
}
});
也可以正常的访问到a的数据。
2.部署dev-server
我们每次使用webpack编译很麻烦,所以可以使用部署webpack-dev-server进行实时debug
首先先在项目进行本地安装
然后再package.json内进行相关的配置
然后全局模式下安装webpack与webpack-cli模块
就可以用npm run start来开启我们的热更新了
此时我们对于页面的修改就可以实时更新在页面上了。
3.全局组件
顾名思义,就是此组件会在全局生效
新建一个vue入口文件vm.js,然后引入cmp2,这次就在cmp2.js里写全局组件了
vm.js
import Vue from 'vue/dist/vue.esm';
let vm = new Vue({
el:'#div1',
data: {},
//全局组件
template:'<div><cmp1/></div>'
});
cmp2.js
import Vue from 'vue/dist/vue.esm';
//注册一个全局组件,名叫cmp2
Vue.component('cmp2', {
data() {
return{a:12, b: 55};
},
template:'<div>'+
'result={{a+b}}'+
'</div>'
});
然后在Vue入口内引入此js生效
直接import './cmp2’即可
然后到对应端口查看效果
测试成功。
而现在如果想要在Vue入口的template内声明一个属性,在cmp2调用并显示出来,则需要注册这个元素属性。
同时,不光可以显示integer,string这种基本类型,也可以显示像列表这样的属性
然后在我们的cmp2中将全局组件的模块进行完善
import Vue from 'vue/dist/vue.esm';
//注册一个全局组件,名叫cmp2
Vue.component('cmp2', {
props:['name','list'],
data() {
return{a:12, b: 55};
},
template:'<div>'+
'{{name}}'+'<br>'+
'<ul>' +
'<li v-for="item in list">{{item}}</li>' +
'</ul>'+
'</div>'
});
但现在我们来到index界面,会发现
这样是不合乎规范的,所以我们要在列表的属性中加上v-bind
然后就可以正常运行了。
在全局组件中,如果我们想要做到灵活的选择组件,就要将组件转换为动态的,需要一个component标签属性
此作用主要在于,根据用户在input框内不同的输入可以显示不同的内容
4.测试组件
组件用于渲染页面,而当我们想调用一个组件加入到我们的网站进行测试并且在测试完成之后将组件停止,是一件很有必要的事情,所以我们就要将注册的组件存入一个变量中
然后对我们封装好的参数进行检验。也相当于一个动态组件,多用于测试。
5.slot插槽
此标签可以让以注册的组件为名的标签包裹起来的text通过一个叫slot的标签进行转移
这是原Vue入口文件,并且在之前顶一个my-dialog标签
现在我们直接在标签下的模板用slot的标签便可直接引用vue入口自定义标签的模板内的text
而如果想要在插槽的内容里含有一些特殊的内容,像标题,那么就需要具名插槽,也就是有name标记的slot
例如我们要使用插槽来体现出文章标题,那么就对title属性进行具名标记,而这个特殊的属性,是一定要被包裹在template标签内的,这是具名插槽的规则。
接下来我们要将其余正常的内容照搬,而title要使用特殊的方法。
单独拿出title属性,并且用name标记的要与之前slot标记的同名,这样就能将特殊属性体现出来了。
6.组件的生命周期
Vue是有一个很完美的生命周期的下面来简要的简述一下:
- 第一步:new一个Vue对象。
我们先拥有一个Vue对象,而这个Vue对象的获取有两种方法,第一种就是lei vm = new Vue();这是我们主动的将Vue 给new出来了,第二种是Vue.component()这是之前说的生成局部组件,也就是被动的将Vue生成出来。 - 第二步:Init lifecycle
在开始整个进程之前进行,初始化一个生命周期 - 第三步:初始化内部对象
初始化之后准备开始挂载。 - 第四步:检测el
如果有el,那就是主动new了个Vue,如果没有,那就是被动new的Vue,也就是Vue.component,这时候就会在内部执行vm.$mount() - 第五步:检测new的时候是否自带了template
如果有,那多半是用的局部组件,那就进行初始化操作,如果没有,那就肯定是new Vue(),那就会把主界面的html代码进行初始化 - 第六步:挂载
将vm内部生成的el取代原来的el,也就是说,将绑定的标签用现有模板取代原来的模板。 - 第七步:Mounted
操作页面标签,在更新页面之前对于页面进行渲染操作,不断持续这个步骤。直到产生了bug或者组件被取消,就会自我destroy - 第八步:destroy
标签无法访问,便会启用自我毁灭,像关闭了网页