Vue学习笔记

  • 主要针对笔者在学习中遇到的一些疑问进行记录
  • 以前一直以为概念是不太重要的东西,所以一直疲于记录,但是最近发现这些原理的概念还是要在以后的学习和使用中不断反复琢磨才能更加灵活的使用,因此会在后期的学习中专门记录。
Vue 生命周期

Vue2.0 生命周期官网图

从图中我们可以看到Vue运行的整个生命周期以及各个阶段的动作。

  • beforeCreate

组件实例刚刚被创建,组件属性计算之前,如data属性等;

  • created

组件实例创建完成,属性已绑定,完成了数据的观测,但是DOM结构还没有生成(尚未挂载),$el属性还不存在,不可用;

  • beforeMount

模板编译/挂载之前

  • mounted

模板编译/挂载之后,el挂载到实例上后调用,业务逻辑一般会在这里开始;

  • beforeUpdate

组件更新之前

  • updated

组件更新之后

  • activated

组件被激活时调用:for keep-alive

  • deactivate

组件被移除时调用:for keep-alive

  • beforeDestory

组件销毁前调用,主要解绑一些使用addEventListener监听的事件;

  • destoryed

组件销毁后调用

Vue插值

  • 数据的展示使用{{}},括号里面可以包括data里面的数据;
  • 如果有的时候想输出HTML,而不是将数据解释后的纯文本,可以使用v-html ;
  <div id="app">
      <span v-html="link"></span>
  </div>
<script>
    var app = new Vue{{
        el:"#app",
        data:{
            link:'<a href="#">只是一个链接</a>'
        }
    }}
</script>

link的内容会被渲染为一个a标签,而不是纯文本,为了防止XSS攻击,可以将“<>”进行转义;

  • 如果想显示{{}}标签,而不进行替换,使用v-pre即可跳过这个元素和他的子元素的编译过程;
<span v-pre>{{hello,I'm 不会被编译}}</span>
Vue过滤器

  • Vue支持在{{}}插入的值的尾部添加一个管道符'|'来对数据进行过滤,用来格式化文本,如字母全部大写,货币千位或者逗号分隔符,可以自定义过滤的规则,通过给vue实例添加filters来设置;
<template>
    <span>{{date|formatDate}}</span>        
</template>
<script>
    var app = new Vue{{
        el:"#app",
        data:{
            link:'<a href="#">只是一个链接</a>',
            date:new Date(),
        },
        filters:{
            //过滤的方法
            formatDate:function(value){
                let date = new Date(value);
                var year = date.getFullYear();
                var month = date.getMonth()+1;
                var day = date.getDate();
                return year+"-"+month+"-"+day;
                
            }
        }
    }}
</script>

过滤器也可以串联,而且可以接收参数

<!--  串联 -->
1. {{message |filterA | filterB}}
<!--  接收参数 -->
2. {{message |filterA('arg1',arg2")}}
内置指令
  1. v-cloak

不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none配合使用;

  • v-cloak是一个解决初始化慢导致页面闪动的方法;
  1. v-once

定义它的元素或组件只渲染一次,包括元素和组件的所有子节点;首次渲染后,不再随数据的变化重新渲染,被视为静态内容。

  1. v-if, v-else-if,v-else

v-else-if要紧跟v-if.v-else要紧跟v-else-if或者v-if

  1. v-show

v-show 的用法和v-if基本一致,不过v-show改变元素的display属性,v-show表示的值是false时,元素会隐藏;

  • v-show不能再<template>上使用

v-show和v-if的比较:

  1. v-if才是真正的条件渲染,他会根据表达式适当的销毁或重建元素及绑定元素的事件或子组件,只要当条件第一次为真时才开始编译;
  2. v-show只是简单的css属性切换,无论条件真与否,都会被编译。v-if更适合条件不经常改变的场景,因为切换开销相对较大,而v-show适用于频繁切换条件;
  1. v-for
  • 数组列表循环
<template>                                                     
    <div>                                                      
        <ul v-for="item in books">   
                 <!--  如果需要索引可以使用如下方式 -->        
                  <!--  <ul v-for="(item,index)  in books">    -->                   
            <li>{{item.name}}</li>                             
        </ul>                                                  
    </div>                                                     
</template>                                                    
                                                               
<script>                                                       
                                                               
    export default{                                            
        data(){                                                
            return{                                            
                books:[                                         
                    {name:'<Vue实战>'},                          
                    {name:'<Javascript实战>'},                   
                    {name:'<CSS实战>'},                   

                ]                                              
            }                                                  
        }                                                      
    }                                                          
      </script>                                                
                                                 
  • 对象遍历
<template>                                                     
    <div>                                                      
          <span v-for="(val,key,index) in bookInfo">{{index}}-{{key}}- {{val}}</span>                                             
    </div>                                                     
</template>                                                    
                                                               
<script>                                                       
                                                               
    export default{                                            
        data(){                                                
            return{                                            
                bookInfo: {  
                       name:'<Vue实战>',
                       edition:1.2.3,
                       author:'wang yan'
                     },                          
                }                                                  
        }                                                      
    }                                                          
      </script>                                                
                                             

数组更新
  • 改变数组的方法: push(),pop(),shift(),unshift(),splice(),sort(),reverse()
  • 不改变数组的方法: filter(),concat(),slice()

这些数组的用途可以参见MDN[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter]

  • 通过索引直接设置项和修改数组长度都不会触发视图更新,可以使用set方法
Vue.set(app.books,3,{
 name:'Vue 设置数据'
})


Prop
  • slot

    父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译

  • keep-alive

要求被切换到的组件都有自己的名字,不论是通过组件的name选项还是局部/全局注册;

Prop

include:字符串或者正则表达式,只有匹配的组件会被缓存
exclude:字符串或者正则表达式,任何匹配的组件都不会被缓存

用法:

  • 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition相似,keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。
  • is特性:
Vuex
  • action 提交的是 mutation,而不是直接变更状态。
  • action 可以包含任意异步操作。
  • action 通过 store.dispatch 方法触发。
Vue Router
  • this.$route.query 路由查询字符串
  • this.$route.hash 路由的hash值
  • this.$route.params 路由的的参数
  • router.push({ name: 'user', params: { userId }}) == router.push({ path: /user/${userId} })
  • 使用props将组件和路由解耦
    const User = {
        props: ['id'],
        template: '<div>User {{ id }}</div>'
    }
    const router = new VueRouter({
        routes: [
            { 
                path: '/user/:id', 
                component: User, 
                props: true 
            },
            // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
            {
                path: '/user/:id',
                components: { default: User, sidebar: Sidebar },
                props: { default: true, sidebar: false }
            }   
        ]
    })

  • History模式

正常情况下都需要后端配合着使用

  • node js 使用的是connect-history-api-fallback
导航守卫
  • router.beforeEach 注册一个全局前置守卫
router.beforeEach((to,from,next)=>{
    //...   
})

1.next:Function 一定要通过调用该方法来resolve这个钩子。执行结果依赖next方法的调用参数;

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

3.next(false)中断当前的导航。如果浏览器的URL改变了,那么URL地址会重置到from路由对应的地址;

4.next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个
新的导航。你可以向 next传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的
选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

5.next(error): 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传
递给 router.onError() 注册过的回调。

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

  • router.beforeResolve 注册一个全局守卫,这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

  • 全局后置钩子:这些钩子不会接受next函数也不会改变导航本身

  • 路由独享的守卫 beforeEnter

  • 组件内的守卫:
    beforeRouteEnter(to,from,next)

在渲染该组件的对应路由被confirm前调用,不能访问组件实例this,因为当守卫执行前,组件实例还没被创建

  • beforeRouteUpdate (to,from,next)

在当前路由改变,但是该组件被复用时调用,可以访问组件实例this,

eg: 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。

  • beforeRouteLeave(to,from,next)

导航离开该组件的对应路由时调用,可以访问组件实例this

完整的导航解析流程
  1. 导航被触发。
  1. 在失活的组件里调用离开守卫。
  2. 调用全局的 beforeEach 守卫。
  3. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  4. 在路由配置里调用 beforeEnter。
  5. 解析异步路由组件。
  6. 在被激活的组件里调用 beforeRouteEnter。
  7. 调用全局的 beforeResolve 守卫 (2.5+)。
  8. 导航被确认。
  9. 调用全局的 afterEach 钩子。
  10. 触发 DOM 更新。
  11. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
路由元信息
  • 常常被用来验证登录权限以及设置页面的title
const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,
          // a meta field
          meta: { 
            requiresAuth: true,
            title:'Bar page'
            
          }
        }
      ]
    }
  ]
})

一个路由匹配到的所有路由记录会暴露在route对象的route.matched数组

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 确保一定要调用 next()
  }
})
数据获取
  • 导航完成之后获取

先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。

  • 导航完成之前获取

导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。

从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 项目脚手架 在这里我使用vue-cli来进行安装 查看项目结构,index.html/main.js是项目入口,A...
    等酒香醇V阅读 711评论 0 1
  • 学习目的 学习Vue的必备技能,必须 熟练使用 Vue-router,能够在实际项目中运用。 Vue-rout...
    _1633_阅读 91,529评论 3 58
  • 父 => 子 传值 父组件中定义属性 <com-a :aaa="parm"> ,子组件通过 props:['aaa...
    _月光临海阅读 384评论 0 0
  • 序言:乱七八糟一锅粥! 基于Vue.js 教程、介绍— Vue.js 心得: 在vue中,推荐始终使用 kebab...
    苦苦修行阅读 645评论 0 1
  • 用Vue.js + vue-router创建单页应用,是非常简单的,基本是这样的: 组件 → 路由 → 渲染地方 ...
    阿go阅读 1,395评论 0 0