vue 开发笔记

优秀组件和库

  • vue-server-renderer 服务端渲染方案
  • vue-devtools vue开发调试工具,方便调试大型复杂项目
  • antd-desigin-vue / element UI 基于vue的第三方ui组件库
  • vxe-table 优秀的vue表格解决方案
  • vue-multiselect vue强大的多选下拉组件
  • Vuelidate 基于vue强大且轻量的校验库
  • vuex-router-sync 保持vue-router和vuex store同步

1. 直接使用 {{}} 绑定某一个 methods 或者计算属性中的某一个方法名

<div>{{changeName()}}</div>

1.vue-router

跳转页面功能

router-view 嵌套路由,加深项目层级

1 vue2.1.0 新增include/exclude
2 <template>
3      <div>
4          <keep-alive include="a,b,c">     //缓存包括 name 为 a,b,c 的组件,也可正则匹配     :include="reg"        
5              <router-view></>
6          </keep-alive>
7      </div>
8 </template>

router-link 映射路由,类似标签 a

1 <router-link to="/index"></router-link>

编程式导航 this.$router.push 与 router-link 相同

 1 <template>
 2     <div>
 3         <button @click="to"></button>
 4     </div>
 5 </template>
 6 <script>
 7     export default {
 8         methods: {
 9             to () {
10                  this.$router.push({name: 'article',id:'自定义'})  
11             }
12         }
13     }
14 </script>                                

this.$router.push 传参,适合非父子直接传递数据用。注:非父子组件传递不建议用 bus event,请使用 vuex

// 字符串,这里的字符串是路径path匹配噢,不是router配置里的name
this.$router.push('home')

// 对象
this.$router.push({ path: 'home' })

// 命名的路由 这里会变成 /user/123
this.$router.push({ name: 'user', params: { userId: 123 }})

// 带查询参数,变成 /register?plan=private
this.$router.push({ path: 'register', query: { plan: 'private' }})
 1 //路由配置
 2 export default new Router({
 3     routers: [
 4          { name:'home', path:'/home',compontent:Home}
 5     ]
 6 })
 7 
 8 //通过 name 获取页面,传递 params
 9 this.$router.push({ name:'home', params:{ userId: this.arg1}});
10 this.$router.push({ path:'/home', query:{ index: index, row: row}})
11 12 //目标页面 13 {{this.$route.params.userId}} 或 {{this.$route.query.row.XXX}}

动态参数应用

router\index.js 中路由组件映射

 1 import Vue from 'vue'
 2 import Router from 'vue-router'
 3 import Article from 'article路径'
 4 Vue.use(Router)
 5 const router = new Router({
 6     routes: [
 7         {
 8           path: '/article/:id.html',   //动态参数 id,前端可使用 this.$route.params.id 获取,node 可使用 req.params.id 获取
 9           name: 'article',
10           component: Article
11         }
12     ]
13 })
14 export default router

router-link 动态映射+事件 native,注:路由传参如 key 没有要求一定在 router/index.js 中显示 path:'/:id/:random'

<router-link :to="{name:'article', params{id:自定义字符,key:XXX,random:XXX}, path: 'balabala'}" @click.native='meth'></router-link>  /* 路由添加事件要加个native */

Get请求传参

样例:http://localhost:8080/linkParamsQuestion?age=18

获取:

let age = this.$route.query.age; //问号后面参数会被封装进 this.$route.query;

路由监听

 1 export default {
 2     watch : {
 3           '$route':'meth' //监听方法meth
 4     },
 5     methods :{
 6         meth () {
 7            if(this.$route.path==='/'||this.$route.path==='/login')                {
 8             console.log('change')
 9         }else{
10             console.log('nochange')
11         }
12     }
13 }                

导航钩子

导航钩子函数,主要是在导航跳转的时候做一些操作,比如可以做登录的拦截,权限校验,而钩子函数根据其生效的范围可以分为 全局钩子函数路由独享钩子函数组件内钩子函数

全局钩子函数

可以直接在路由配置文件router.js里编写代码逻辑。可以做一些全局性的路由拦截。

router.beforeEach((to, from, next)=>{
  //do something
  next();
});
router.afterEach((to, from, next) => {
    console.log(to.path);
});

每个钩子方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象

  • from: Route: 当前导航正要离开的路由

  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

    • next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

确保要调用 next 方法,否则钩子就不会被 resolved。

路由独享钩子函数

可以做一些单个路由的跳转拦截。在配置文件编写代码即可

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内钩子函数

更细粒度的路由拦截,只针对一个进入某一个组件的拦截。

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当钩子执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

钩子滚动行为

scrollBehavior 方法接收 tofrom 路由对象。

第三个参数 savedPosition 当且仅当 popstate 导航 (modehistory 通过浏览器的 前进/后退 按钮触发) 时才可用。

这里就不细致的讲了,文档都有也非常简单,记住有这个东西就行。

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
  }
})
//所有路由新页面滚动到顶部:
scrollBehavior (to, from, savedPosition) {
  return { x: 0, y: 0 }
}

//如果有锚点
scrollBehavior (to, from, savedPosition) {
  if (to.hash) {
    return {
      selector: to.hash
    }
  }
}

路由元信息

这个概念非常简单,就是在路由配置里有个属性叫 meta,它的数据结构是一个对象。你可以放一些key-value进去,方便在钩子函数执行的时候用。

举个例子,你要配置哪几个页面需要登录的时候,你可以在meta中加入一个 requiresAuth标志位。

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      meta: { requiresAuth: true }
    }
  ]
})

然后在 全局钩子函数 beforeEach中去校验目标页面是否需要登录。

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    //校验这个目标页面是否需要登录
    if (!auth.loggedIn()) {  
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 确保一定要调用 next()
  }
})

这个auth.loggedIn 方法是外部引入的,你可以先写好一个校验是否登录的方法,再importrouter.js中去判断。

2.other

vue 请求返回状态码 304 原因之一:可能使用了 keep-alive 缓存

3.数据传递,数据监听与改变

https://blog.csdn.net/lander_xiong/article/details/79018737 组件通信

https://cn.vuejs.org/v2/guide/components-props.html

1.子组件获取父组件数据,props

2.子组件触发父组件方法,$emit 触发,@监听

3.父组件触发子组件属性和方法,注册ref

4.数据强制刷新

数据强制刷新 this.$forceUpdate

5.element-ui

1.handleSelect 传参

<el-autocomplete 
v-model="state4" 
:fetch-suggestions="querySearchAsync" 
placeholder="请输入内容" 
@select="((item)=>{handleSelect(item, index)})" // 写个闭包就可以了,index表示第几个组件 
>
</el-autocomplete>

6.vue-cli3配置vue.config.js持续更新

https://github.com/staven630/vue-cli4-config