vue项目小结

补充

1.main.js入口文件注册过router,会有router,router,route俩个属性
<template>
   <div><TabBar v-if = "tabBarFlag"/></div>
</template>
export default{
    watch: { // 监听 $route属性
        $route:{
            deep: true,// 开启深度监听
            handler(){ // 处理函数
                if( this.$route.name == 'detail') {
                    this.tabBarFlag = false
                }else {
                    this.tabBarFlag = true
                }
            }
        }
    }
}
2.router-link
      <!-- 使用vue内置提供的 router-link 组件来完成 -->
        <router-link 
          :to=" item.path " tag = "li"
          active-class = "active" //给当前点击的加类 active-class
        >
          <i class="fas" :class = "[ item.iconName ]"></i>
          <span> {{ item.text }} </span>
        </router-link>
3. 父传给子,子接收数据渲染时,可能会报错

如果数据存在渲染两次情况,其中一次时undefined/null,那么我们需要通过判断来排除undefined/null

export default {
  props: ['resource'], // 接收属性
  computed: {
    list () { // 需要加一个计算属性重新计算,在拿这个属性渲染就不会报错
      return this.resource && this.resource 
    }
  }
}
4.其余(native修饰符,filter,绑定属性传值写法)

组件身上添加原生事件,要加native修饰符

1.@click.native = “addShopCar”

2.路由接参,route访route是一个属性,在结构里面可以直接访问route,方法里面this.$route

3.js工具库,loadsh,原生方法封装库, https://www.lodashjs.com/

4.better-scroll 最适合移动端开发的前端 mvvm 框架是 Vue

5.Vue.filter(‘imgFilter’, val => { return val.replace(‘w.h’,‘128.180’)})

6.@import ‘~assets/stylesheets/border.styl’; 引入样式加~

7 支持这种传值

//封装
export const getStorage =  ( name ) => {
  return localStorage.getItem( name ) && JSON.parse(localStorage.getItem( name )) || []
}
export const saveStorage = ( name, value ) => {
  localStorage.setItem( name,JSON.stringify(value) )
}

一、vue路由

守卫是异步解析执行

router.afterEach() ,全局后置守卫router.afterEach()

 next [必须要写的]
         1. next表示两者之间的连接
         2. 取值
            1. next()  //默认连通
            2. next( true ) // 表示连通
            3. next( false ) // 不表示断开连接
            4. next(路由路径) 
               1. next('/home')
               2. next({ name: 'home', params: {},query: {} })
            5. next( vm => {  } ) // vm指的是目标组件

1.全局导航守卫

  • 全局前置守卫router.beforeEach()

使用场景 -> 后台管理系统 || 社区app 登录拦截

接收三个参数,to,from,next

router.beforeEach((to,from,next) => {
    next() // 默认不写参数是允许
    next(error)
     if ( to.path == '/home/hot' ) {
      next()
    }
})

demo,全局前置守卫,倒计时3s后判断要不要进入

router.beforeEach((to ,from , next) => {//全局守卫
    if( token || to.path == '/login'){ // 判断token,或者进入的是login页面,要执行的语句
        if(to.path == '/buyer') {
            const toast = Toast.loading({
              duration: 0, // 持续展示 toast
              forbidClick: true,
              message: '倒计时 3 秒进入购买页'
            });

            let second = 3;
            const timer = setInterval(() => {
              second--;
              if (second) {
                toast.message = `倒计时 ${second} 秒`;
              } else {
                clearInterval(timer);
                // 手动清除 Toast
                Toast.clear();
              }
            }, 1000); // 以上是组件带的,只有倒计时,现在要实现需要
            setTimeout(() => { // 开一个延时定时器,3s判断要不要进入页面
                next()
                return // 终止掉,一定要加
            })
        }else{
            next()
        }
        
    }else{
        next('/login')
    }
})
  • 全局后置守卫router.afterEach()

全局后置守卫 - 建议不用

应用场景: 没有拦截这一个功能,只有提示功能

接收(to,from)

  router.afterEach( to => {
    if ( to.path == '/recommend' ) {
      Notify({ type: 'success', message: '通知内容' }); // 提示内容
    }
  })
  • 全局解析守卫也叫更新守卫
    • 在 2.5.0+ router.beforeResolve这和router.beforeEach` 类似
    • 区别: 是否完整遍历路由表
    • 区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,才被调用。
    • 更新守卫要遍历完整路由表之后才跳转页面

2.路由独享守卫,beforeEnter

const List = () => import(/*webpackChunkName: "group1"*/ '@/views/list/index.vue')
const router = new VueRouter({
    routes:[
        {
            path: '/list/:id',
            // 动态路由组件配置 http://localhost:3000/list/001?a=1&b=2
            component: List,
            name: 'list',// 取一个别名
            meta: {
                include: 'List', 
              /** <keep-alive :include="$route.meta.include"> 
               		 <router-view><router-view/> 来接收路由对应的组件
                </keep-alive>
                */
            },
            beforeEnter:(to,from,next) => {
                const token = getCookie('token')
                if (token) {
                    next()
                }else{ // 没token,要提醒
                    Toast.fail('您还没登录,无法查看')
                    next(false)
                }
            }
        }
    ]
})

3.组件内守卫***

beforRouterEnter, beforeRouteUpdate, beforeRouteLeave

a. 组件前置守卫【 钩子 】beforRouterEnter ***********
  1. 拦截组件的进入

  2. 执行: 创建创建前执行,这个时候没有组件,没有this ,通过next((vm) => {vm.$set()})

  3. 功能

    • 判断是否有token,然后是否进入当前页面

    • 数据预载

      • 进入组件前,提前得到数据,并将这个数据赋值给组件

demo1组件预加载

export default { // 数据预载 进入页面前先请求加载数据,但没有this
    data () {
        return {
          cinemas: {}
        }
    },
    async beforeRouteEnter (to,from,next) {
       const result = await request({
           url:'/ajax/search',
           params: {
               ke:'n'
           }
       }) 
       next( vm => { // vm 就是当前组件 解决没有this的问题
            // vm.cinemas = result.data.cinemas.list  这么写可行吗? 不行 
            // 对象的合并  Object.assign() -> Vue.set/this.$set( 属性,属性值 )
           vm.$set( vm.cineams, JSON.stringfy(result.data.cinemas.list)) // 对象合并后进入
           next()
       })
    }
}

demo2组件前置守卫,判断是否有token,是否允许进入

export default {
    beforeRouteEnter(to, from, next){ // 无this
        const token = getCookie('token')
        if ( token ) {
            next() // 允许进入
            return
        }
        next( false )
    }
}
b.组件后置守卫(钩子)
  1. 拦截组件离开
  2. 执行: 离开组件前,这时有组件,有this
export default {
    beforeRouteLeave(to, from, next) {
        if( this.username || this.password) {
            if(confirm('还没提交,确定离开么')){
                next()
                return // 一定记得加
            }else{
                next(false)
                return
            }
        }else{
            next()
        }
    }
}
c.组件更新守卫 beforeRouteUpdate()

专用于动态路由

二、编程式导航路由

router.push

router.replace

router.go(n) 后退

- $router

- push vs replace

​ - push会将我们操作放入历史记录,点击浏览器返回会一层一层返回

​ - replace不会将我们的操作放入历史记录,点击浏览器返回反回2层

// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

如果提供了 pathparams 会被忽略 ,所以要注意params和query同时写的问题

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

三、其他有关路由

1.命名路由

路由表里面配置一个命名路由,name,起的别名,router-link链接到一个命名路由

<router-link :to = "{name: 'home',params: {userId: 123}}" > 
</router-link>
// 这跟代码调用 router.push() 是一回事
// 点击一个事件触发,在事件里面可以取
this.$router.push({name:'home',params:{userId:123})

2.命名视图

同一个页面展示多个视图 ,而不是嵌套展示 ,router-view 没有名字就是默认为default

<router-view></router-view>
<router-view name = 'a'></router-view>
<router-view name = 'b'></router-view>

一个视图使用一个组件渲染 ,一个路由多个视图,要用components【s】一定要加上配置上,单个不加

const router = new VueRouter({
    routes: [
        {
            path: '/',
            components: { // s 多个组件渲染 一定记得加
                default: Foo,
                a: Bar,
                b: Bar2
            }
        }
    ]
})
发布了17 篇原创文章 · 获赞 0 · 访问量 293
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览