vue06----portfinder、组件切换(动态组件、路由)、路由的配置项、router-view、router-link、动态导航(params)、编程式导航、声明式导航、路由传参的方式(动态导航、query、params)、命名视图、嵌套路由、node抛出和ES6抛出、better-scroll、浏览器渲染流程、$route、$router和routes的区别
### 端口号问题:vue.config.js中devServer中port无效
问题描述:vue项目开发中,用axios请求数据时,用到服务器代理,在vue.config.js中设置服务器代理devServer时,配置 port:3001, 失效。
解决:
第一种方法:修改portfinder版本号:
在node_modules中,依次找到@vue----cli-service----package.json,将 "portfinder": "^1.0.22", 改为 "portfinder": "^1.0.20",
第二种方法:修改port的值:
在node_modules中,依次找到@vue----cli-service----lib----commands----serve.js,将 const port = await portfinder.getPortPromise() 改为 const port = portfinder.basePort
### 组件切换
##### 动态组件
<component :is="components"></component>
任意标签名加上 is 属性,在当前的位置渲染指定的组件,最好是写成component标签。
component标签开辟一块空间,本身不渲染。
##### 路由
1、监听地址栏的变化
2、根据地址栏的变化切换组件
①安装路由插件:npm install vue-router
②创建路由:src下新建router.js,抛出router实例
```
import Vue from "vue";// 引入vue
import Router from "vue-router";// 引入vue-router
Vue.use(Router);// 使用路由
import Recommend from "./Recommend.vue";// 引入Recommend组件
import Singer from "./Singer.vue";// 引入Singer组件
const router=new Router({// 实例化router对象
mode:"hash",// 使用hash路由,带#号
routes:[// 路由的配置项
{path:"/recommend",component:Recommend},// recommend路径对应Recommend组件
{path:"/singer",component:Singer},// singer路径对应Singer组件
]
});
export default router;// 抛出路由
```
③使用:js的入口文件main.js中引入并使用
```
import router from "./router.js"
// 注册
new Vue({
router:router
})
```
###### 路由的配置项
1、mode 路由模式,hash和history两种。hash:默认,地址栏有#,不需要后端配置;history:地址栏没有#,打包上线(npm run build)的时候,刷新页面会404,此时需要后端配置。
2、path 路由匹配的路径
3、component 当path的路由匹配成功会显示对应的组件
4、children 路由嵌套,一个小型的reutes,值是一个数组,数组中的每一项就是一个二级路由的配置项,它里面的属性和一级路由的配置项属性一致。注意:path不要加 /
5、name 命名路由,path:"/home" 后面加一个 name:"home",用于路由传值时以对象的形式传值
6、meta 路由元信息,每个路由身上携带的信息
7、props 路由解耦,当使用路由解耦时,在配置项中增加 props:true
8、redirect 重定向,{path:"/",redirect:"/home"}
> router-view标签:在根组件App.vue中开辟一块空间,根据地址栏变化显示不同的组件
<router-view></router-view>
> router-link标签:点击跳转
<router-link to="/recommend" tag="div" activeClass="active">推荐</router-link>
<router-link to="/singer" tag="div" activeClass="active">歌手</router-link>
to:跳往的路径
tag:要渲染成的标签,默认是a标签
activeClass:当前标签添加类名
如果不用activeClass,可以用.router-link-active直接设置,可以不再标签中写activeClass:
.router-link-active {
color: #c33;
}
### 动态导航(路由传参的一种方式)
何时使用?跳转到组件中并且需要传递一个参数时
1、router.js中,申明路由表的时候加上 /:id :{path:"/dongtai/:id",component:Dongtai},
2、地址栏中: http://localhost:3002/#/dongtai 的后面加上 /111(111可以是任意字符)
3、目标组件Dongtai.vue中:mounted生命周期中通过 this.$route.params 可以拿到动态路由传的参数
4、App.vue中,跳转动态导航时传参,动态导航有几级路径上就添加几级:<router-link :to="{path:`/dongtai/${id}`}" tag="div" activeClass="active">动态导航</router-link>
### 编程式导航
例如:window.location.href=""
window下history的方法:
window.history.go(1)
window.history.go(-1)
window.history.forward()
window.history.back()
window.history.push()
window.history.replace()
1、go() forward() back() push() 会将新页面保存到页面栈中,有返回键
2、replace() 替换,没有返回
编程式导航:
*this.$router.back() 后退
this.$router.forward() 前进,一般不用
*this.$router.push() 跳转,用的最多
this.$router.go() 指定跳转,一般不用
this.$router.replace() 替换,没有返回,一般不用
场景:列表页跳转到详情页
#### 路由传参的另外两种方式(利用编程式导航)
1、query传值:(少)
this.$router.push({path:"/singer",query:{us:"wql",ps:123}})
通过this.$route.query取值
2、params传值:(多)
this.$router.push({name:"singer",params:{us:"wql",ps:123}}) ----命名路由用于params传值和动态路由的is属性
注意:params传参和path不能同时使用,params表示的就是path,当有path时,params会被忽略。因此需要在路由表中加上name属性:{path:"/singer",name:"singer",component:Singer},
通过this.$route.params取值
### 声明式导航
例如:
<a href=""></a>
<router-link to="/home"></router-link>
场景:tab
### 命名视图
给router-view起一个名字,和组件形成对应关系,在同时渲染不同的组件的时候用到命名视图。
1、渲染多个组件的时候,分别设置一个name属性:
<router-view name="recommend"></router-view>
<hr>
<router-view name="singer"></router-view>
2、路由表中添加一个配置项:
{path:"/nameView",components:{
recommend:Recommend,// name属性的值分别对应相应的组件,那个router-view标签就会只渲染该组件
singer:Singer
}},
### 嵌套路由 children
my页面是在App.vue下的,login和userinfo页面在my页面下,此时需要用到嵌套路由,在路由表中配置children:
{path:"/my",component:My,children:[
{path:"login",component:Login},
{path:"userinfo",component:UserInfo},
]},
注意:children里的path不要加 / ,它相当于一个小型的routes,值是一个数组,属性和一级路由一样。
### 抛出:module.exports={}; 和 export default router; 有什么区别?
配置项相关的,像vue.config.js是通过node来执行的,用node语法抛出,module.exports={};
在写vue代码的时候,它用的是ES6的环境,用ES6的抛出,export default xxx;
### better-scroll
1、安装插件:npm install better-scroll
2、引入:import BS from "better-scroll";
3、结构和样式:
<div class="wrapper" ref="wrapper">
<div class="container">
<ul>
<li v-for="(item,index) in 100" :key="index">{{item}}</li>
</ul>
</div>
</div>
.wrapper{
position: fixed;
.top(88);
bottom: 0;
left: 0;
right: 0;
background-color: deeppink;
overflow: hidden;
.container{
background-color: pink;
}
}
4、初始化:mounted中初始化:new BS(this.$refs.wrapper,{});
注意:
①盒子层级结构一定是wrapper包裹container,并且container的高度要大于wrapper的高度,一般是container中的结构时数据请求来的,也就是一个列表,wrapper是用固定定位写的充满屏幕。
②初始化的时候,用ref获取DOM,尽量不要用类名或id名获取DOM,因为这样有可能会有重复的类名,ref确保唯一性。
### Q:
1、浏览器渲染流程
①浏览器会将html解析成一个DOM树,DOM树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
2、将css解析成CSS Rule Tree。
3、根据DOM树和CSSOM来构建Rendering Tree。注意:Rendering Tree渲染树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在渲染树中了。
4、有了Rendering Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及它们的从属关系,下一步操作称之为layout,顾名思义就是计算出每个节点在屏幕中的位置。
5、再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。
注意:上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时可能还在通过网络下载其余内容。
2、$route、$router和routes的区别
$route中存放当前路由的一些信息,如路由的跳转和携带的参数(query、动态导航params)。
$route中有:name、path、hash、query、params、fullpath(完整路径)...
$router是路由的实例对象,具有路由的方法,如编程式导航的跳转。
$router中有:currentRoute($route)、options、mode...
routes是路由表,填写路由的配置项,是一个数组。