组件总结
模板上用的代码: {{}} v-text v-html v-pre v-clock v-bind(:) v-on(@) 事件修饰符 .stop .once .capture .self .native v-xxx directive v-if/v-else v-show v-for v-model listener 新:v-slot 旧:slot
组件内的代码 data:()=>{} props:[], comments:{}, directives:{}, filters:{}, watch:{}, computed:{}, beforeCreate(){}, created(){}, beforeMount(){}, mounted(){}, beforeUpdate(){}, updated(){}
this可以访问哪些东西? 属性 方法 data emit=>自定义事件
路由
1.相关认识
后端路由:对于前端的网络请求,不同的pathname,去执行后端的不同业务 前端路由:不同的网址对应各自的页面 vue的前端路由:SPA应用要做出路由效果,就得判断当前网址,然后切换组件 vue-router就是专门做切换组件的功能,它是一个单独的技术,依赖vue 就像jQuery和dom操作一样
2.引入
2.1.cdn自己网上随便看看
2.2 自己npm下载引入使用
//安装到项目中:
npm i vue-router --save-dev//注意:这种下载不好,因为打包之后容易出问题
npm i vue-router --save或者 npm i vue-router --S
在main.js入口文件中引入
import Vue from "vue"
import VueRouter from "vue-router"//引入路由工具
import App from "./App.vue"
Vue.use(VueRouter)//注入路由,就是运行路由的相关函数和给vue绑定东西:比如$router
//创建路由工具
const router=new VueRouter({
//routes路由器 生成很多网址对应的切换组件
routes:[{path:"/home",component:()=>import("./home.vue")},
{path:"/about",component:()=>import("./about.vue")}]
})
new Vue({
router,//把路由挂载到页面
render(h){return h(App)}
}).$mount("#app")
//在App.vue中写 <router-view></router-view>
2.3 cli安装
vue create xxapp 空格键选择router然后回车 自定就会把路由安装好
3.router-view和router-link 标签
router-view:相当于 路由网址匹配到的组件 会渲染到当前组件的这个标签上(学不学的会路由 就看能不能理解这个)
router-link:相当于a标签,给我们提供跳转到某个路由的功能,如果没有匹配到路由就会跳转失败:
他渲染到页面也是a标签,但是只是改变了地址栏的网址并没有重新加载网页
路由的底层就是采用的history去监听地址栏的变化 然后把当前APP组件中的router-view切换了
因此这种跳转用在网站内部的路由跳转
xx 编程式跳转: this.$router.push({path:"路由"})
4.动态路由&传参 路由传参有2种方式
传递的参数都在路由信息对象中: 路由对应的组件中获取 this.$route
4.1 query传参:
//2种传参:
<router-link to="/xx?name=karen&pwd=123">go</router-link>
this.$router.push({path:"/xx",query:{name:"karen",pwd:123}})
//在路由匹配的组件中获取数据:
mounted(){let queryObj=this.$route.query}
4.2动态路由传参
//设计:
const router=new VueRouter({
routes:[
{path:"/home/:id",component:()=>import("./home.vue")},
{path:"/about",component:()=>import("./about.vue")}]
})
//2种传参:
<router-link to="/home/123">go</router-link>
this.$router.push({path:"/home",params:{id:123}})
// 如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
//在路由匹配的组件中获取数据:
mounted(){let paramsObj=this.$route.params}
5.路由嵌套
路由嵌套--子路由跳转
*代表所有匹配都通过 redirect代表重定向 //注意:子路由中的匹配地址不要在前面加/ 否则就会认为是根路由
//语法:一个路由对象的设计中中包含: path(路由匹配的路径) component(匹配路径时对应渲染的组件) redirect(匹配路径时重新匹配另外的路径) children(子路由们的数组) name(路由的名字,方便直接通过名字来匹配路由):
//routes=[{path,component,redirect,children,name},{path,component,redirect,children,name}]
const routes = [{
path: '/',
component: () => import("../views/root.vue"),
redirect:"/goods_rank",// 访问/时默认重新访问/goods_rank
children: [{
name:"goods_rank",
path: "goods_rank",
component: () => import("../views/root/goods_rank.vue"),
//goods_rank组件加载的条件是路由匹配上了: localhost:8080/goods_rank
children: [{
name:"goods_rank_all",
path: "goods_rank_all",
component: () => import("../views/root/goods_rank/goods_rank_all.vue")
//goods_rank_all组件加载的条件是路由匹配上了: localhost:8080/goods_rank/goods_rank_all
},
{
path: "goods_rank_highpraise",
name:"goods_rank_highpraise",
component: () => import("../views/root/goods_rank/goods_rank_highpraise.vue")
},
{
path: "goods_rank_middlepraise",
name:"goods_rank_middlepraise",
component: () => import("../views/root/goods_rank/goods_rank_middlepraise.vue")
},
{
path: "goods_rank_badepraise",
name:"goods_rank_badepraise",
component: () => import("../views/root/goods_rank/goods_rank_badepraise.vue")
},
{
path: "*",
component: () => import("../views/root/goods_rank/goods_rank_all.vue")
}
]
},
{
path: "goods_inventory",
name:"goods_inventory",
component: () => import("../views/root/goods_inventory.vue")
},
{
path: "goods_new",
name:"goods_new",
component: () => import("../views/root/goods_new.vue")
},
{
path: "goods_set",
name:"goods_set",
component: () => import("../views/root/goods_set.vue")
}
]
}]
组件中跳转时:
//4种语法:
//1
<router-link to="/当前代码所在组件的路由地址/去哪一个子路由的地址">go</router-link>
this.$router.push({path:"/当前代码所在组件的路由地址/去哪一个子路由的地址"})
//2
<router-link to="去哪一个子路由的地址">go</router-link>
this.$router.push({path:"去哪一个子路由的地址"})
//注意:前面的/要写上,代表绝对路由,不写的话代表相对于当前路由,而不是当前父组件路由
//3
<router-link :to="{name:'注册的路由的name'}">go</router-link>
this.$router.push({name:'注册的路由的name'})
例:
<router-link to="/goods_rank/goods_rank_highpraise">go</router-link>
this.$router.push({path:"/goods_rank/goods_rank_highpraise"})
<router-link :to="{name:'goods_rank_highpraise'}">go</router-link>
this.$router.push({name:'goods_rank_highpraise'})
补充:
//replace跟push很像,但不会向 history 添加新记录,而是替换当前的history记录
this.$router.replace({path:"/home"})
this.$router.go(1)// 在浏览器记录中前进一步,等同于 history.forward()
this.$router.go(-1)// 后退一步记录,等同于 history.back()
this.$router.go(3)// 前进 3 步记录
this.$router.go(-100)// 如果 history 记录不够用,那就默默地失败呗
//跳转总结:
注册路由时,路由路径不要在前面加 斜杠
跳转路由时 1.path里写的路径必须前面加斜杠 从根路由路径开始写 2.不用path 直接使用name
6.路由模式--hash&history(面试)
hash模式: 在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取; 特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。 hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式: history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。 history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述: “不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
const router=new VueRouter({
mode:"hash",//"history"
routes:[{path:"/home",component:()=>import("./home.vue")},
{path:"/about",component:()=>import("./about.vue")}]
})
7.VueRouter router route区别
VueRouter是一个nodejs识别的模块包 route是路由匹配时,携带了一些信息的对象,包括path,params,hash,query等等信息 router是路由实例对象,包含了路由的跳转方法,钩子函数等等
8.路由守卫
8.1全局守卫
全局前置钩子router.beforeEach(fn),导航被触发----一般登录验证 全局解析钩子router.beforeResolve(fn),组件初始化 全局后置钩子router.afterEach(fn),没有next,导航被确认,一般路由跳转以后用window把窗口调上去
//全局前置守卫
router.beforeEach((to, from, next) => {
//用户未登录只能访问首页、登录注册页面
if (to.path == "/" || to.path == "/login" || to.path == "/register") {
next();
} else {
//去其他页面判断是否登录
let flag = window.localStorage.getItem("email");
//登录过直接放行
if (flag) {
next()
} else {
//未登录则跳转到首页
Message({
message: '您尚未登录哦,请先登录!',
type: 'warning',
duration: 1500
});
next("/");
}
}
})
//全局后置守卫
router.afterEach((to, from) => {
window.scrollTo(0,0)
})
8.2路由独享的守卫
路由独享的守卫beforeEnter(to,from,next),路由初始化(组件未初始化)----
a,路由鉴权-----用户体验:界面,功能,bug,效率,权限
b,组件异步加载情景中(插件配置:syntax-dynamic-import)
routes:[{
path:"/test",
component:()=>import("../components/Test.vue"),
beforeEnter(to,from,next){
if(to.path==="/test"){
alert("请登录");
next(false); // 禁止跳转
}else{
next()
}
}
}]
3)组件内部生命周期守卫
beforeRouteLeave 从该组件离开
beforeRouteEnter(to,from,next),组件被激活,使用不了this,故构造指定该next 可以接收一个回调函数接收当前vm 实例----路由传参获取参数,得到初始化数据
beforeRouteUpdate(to,from,next),组件重用时被调用----路由传参获取参数,避免增添watch 开销
导航守卫执行顺序:beforeRouteLeave < beforeEach < beforeRouteUpdate < beforeEnter < beforeRouteEnter < beforeResolve < afterEach
出发路由,预备从当前组件离开,判断路由变化,判断组件是否重用,判断新路由初始化,判断组件初始化,路由与组件初始化完毕,路由组件重定向完毕