• Vue详解及综合案例


    一、Vue简介

    1.1 简介

    Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式的js框架,发布于 2014 年 2 月。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库(如:vue-routervue-resourcevuex)或既有项目整合。

    1.2 MVVM 模式的实现者——双向数据绑定模式

    • Model:模型层,在这里表示 JavaScript 对象

    • View:视图层,在这里表示 DOM(HTML 操作的元素)

    • ViewModel:连接视图和数据的中间件,Vue.js 就是 MVVM 中的 ViewModel 层的实现者 

    这里 核心就是 ViewModel 里面有DOM监听以及数据绑定,View是页面数据展示 Model也就是前面data里定义的,通过Vue来实现各种快捷功能,我们用普通js写的话 得写一大串Js代码;

    mvvm设计模式 这里的

    第一个m是 model 也就是vm的data属性

    第二个v是 view 视图 网页模版

    最后vm就是中间vue的 viewmodel 代码体现就是vm对象或者vm实例;

    1.3 其它 MVVM 实现者

    • AngularJS

      简单介绍一下,AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。

    • ReactJS

      React引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。

    • 微信小程序

      微信小程序的视图层和数据层就是通过MVVM进行绑定的。

    1.4 为什么要使用 Vue.js

    • 轻量级,体积小是一个重要指标。Vue.js 压缩后有只有 20多kb (Angular 压缩后 56kb+,React 压缩后 44kb+)

    • 移动优先。更适合移动端,比如移动端的 Touch 事件

    • 易上手,学习曲线平稳,文档齐全

    • 吸取了 Angular(模块化)和 React(虚拟 DOM)的长处,并拥有自己独特的功能,如:计算属性

    • 开源,社区活跃度高

    1.5 Vue.js 的两大核心要素

    1.5.1 数据驱动

    当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器。

    这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时 getter/setter 的格式化并不同,所以你可能需要安装 vue-devtools 来获取更加友好的检查接口。

    每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

    1.5.2 组件化

    • 页面上每个独立的可交互的区域视为一个组件

    • 每个组件对应一个工程目录,组件所需的各种资源在这个目录下就近维护

    • 页面不过是组件的容器,组件可以嵌套自由组合(复用)形成完整的页面

    二、Vue的初体验

    2.1在页面引入vue的js文件即可。

    注意:cdn是一种加速策略,能够快速的提供js文件

     

    2.2 在页面中绑定vue元素

    创建一个div,id是app

    <div id="app">div>

    2.3 创建vue对象,设计对象的内容

    其中该vue对象,绑定了页面中id是app的那个div

    1. # el: element的简称,也就是Vue实例挂载的元素节点,值可以是 CSS 选择符,或实际 HTML 元素,或返回 HTML 元素的函数。
    2. # data: 用于提供数据的对象,里面存放键值对数据。

    说明:

    这里有几点重要说明:

    new Vue 我们创建了Vue对象;

    el 指定了绑定DOM,接管DOM操作;

    data:用于提供数据的对象,里面存放键值对数据

    v-model 重点 可以实现数据双向绑定,改变了这里的值,其他地方也根据改变;

    {{xxxxx}} 显示数据;

    2.4 在页面的元素中使用插值表达式来使用vue对象中的内容

    1. <div id="app">
    2. {{ title }}
    3. div>

    三、 插值表达式

    插值表达式的作用是在View中获得Model中的内容

    Model中的内容如下:

    1. new Vue({
    2. el:"#app",
    3. data:{
    4. title:"hello world!"
    5. },
    6. methods:{
    7. sayHello:function(){
    8. return "hello vue";
    9. }
    10. }
    11. });

    3.1 简单使用插值表达式获取数据

    1. <div id="app">
    2. {{title}}
    3. div>

    此时,页面上将会显示"Hello world!"

    3.2 在插值表达式中获取数组中的内容

    1. "app">
    2. {{[1,2,3,4][2]}}
  • 此时,页面上会显示“3”,也就是数组中的第三个元素被获取。

    3.3 使用插值表达式获取对象中的属性

    1. <div id="app">
    2. {{ {"name":"xiaoyu","age":20}.age }}
    3. div>

    此时,页面上会显示“20”,也就是对象中age属性的值。

    3.4 使用插值表达式调用Vue中的方法

    1. <div id="app">
    2. {{ sayHello()}}
    3. div>

    此时,页面上会显示“hello vue”,也就是调用了vue对象中的sayHello方法,并展示了方法的返回值。

    3.5Vue对象总结 

    Vue.js通过加载js,实现对页面的快速渲染。vue封装的js该如何使用? 就必须了解MVVM双向数据绑定模式。Vue将视图层和数据层分离,通过MVVM建立视图层和数据层的连接。其中,插值表达式是一种连接方式,可以通过插值表达式以多种方式,快速的从数据层获取数据并展示在视图层上。数据层Vue对象,也是由很多部分组成,比如之前介绍的el,data,methods等,以及之后要介绍的mount,computed等。

    四、Vue的分支 v-if

    4.1 v-if

    Vue中的分支语句v-if非常好理解,逻辑跟Java中的if-else相同。v-if语句块包含以下内容:

    • v-if

    • v-else

    • v-else-if

    接下来以一个简单例子即可理解:

    1. <html>
    2. <head>
    3. <meta charset="utf-8">
    4. <title>title>
    5. head>
    6. <body>
    7. <div id="app">
    8. <p v-if="flag">
    9. 今天天气很舒服!
    10. p>
    11. <p v-else-if="rich">
    12. 今天天气很燥热!晚上要去放松一下!
    13. p>
    14. <p v-else="rich">
    15. 晚上只能自嗨!
    16. p>
    17. div>
    18. body>
    19.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    20. <script>
    21. new Vue({
    22. el:'#app',
    23. data:{
    24. flag:false,
    25. rich:false
    26. },
    27. methods:{
    28. }
    29. });
    30. script>
    31. html>

    从这个例子可以看出,vue对象中的data提供了分支的条件。根据条件,如果是true,则v-if的内容就会显示,反之不显示。

    4.2 v-show

    v-if和v-show之间有着看似相同的效果,但优化上却有区别。先看下面这个例子:

    1. <html>
    2. <head>
    3. <meta charset="utf-8">
    4. <title>title>
    5. head>
    6. <body>
    7. <p v-show="rich">
    8. 有钱!
    9. p>
    10. <p v-if="rich">
    11. 有钱!
    12. p>
    13. <button type="button" @click="rich=!rich">今晚彩票开奖button>
    14. div>
    15. body>
    16.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    17. <script>
    18. new Vue({
    19. el:'#app',
    20. data:{
    21. flag:false,
    22. rich:false
    23. },
    24. methods:{
    25. }
    26. });
    27. script>
    28. html>

    通过点击“今晚彩票开奖”按钮,能切换rich的值,此时发现,v-if和v-show的显示状态都会来回切换。看起来是一样的,但通过查看控制台代码发现,v-show实际会将p标签的css样式的display属性设为none来达到隐藏的效果。 

    而v-if是直接在页面上添加和删除p标签来达到效果,因此v-show在反复切换的应用场景下,效率比v-if更高。

    五、Vue的循环 v-for

    Vue中的循环关键字并没有Java的那么多,只有v-for,但用法上有多种。接下来我们来逐一介绍。

    5.1 普通的for循环

    我们需要定义数据源,然后通过v-for来遍历数据源,再使用差值表达式输出数据。

    1. <body>
    2. <div id="app">
    3.    <ul>
    4.        <li v-for="item in items">{{item.date}}li>
    5.    ul>
    6. div>
    7. body>
    8.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    9. <script>
    10.    new Vue({
    11.        el:'#app',
    12.        data:{
    13.            items:[1,2,3,4,5,6]
    14.       }
    15.   });
    16. script>

    在这个例子中,数据源提供了一个数组。视图层通过v-for来循环输出多个li标签,非常简单。

    5.2 带着索引的for

    1. <body>
    2. <div id="app">
    3.    <ul>
    4.        <li v-for=" (a,i) in args" :key='i'>{{i}}{{a}}li>
    5.    ul>
    6. div>
    7. body>
    8. <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
    9. <script>
    10.    new Vue({
    11.        el:'#app',
    12.        data:{
    13.            args:[1,2,3,4,5,6]
    14.       }
    15.   });
    16. script>

    此时的i就是每次循环的循环变量 ,从0开始一直到元素个数-1

    5.3 遍历一个对象中的信息: value、name、index

    1. <body>
    2. <div id="app">
    3.    <ul>
    4.        <li v-for="(value,name,index) in student">{{name}}--{{value}}--{{index}}li>
    5.    ul>
    6. div>
    7. body>
    8. <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js">script>
    9. <script>
    10.    new Vue({
    11.   el:'#app',
    12.   data:{
    13.       student:{
    14.           username:'小鱼',
    15. age:20,
    16. girl:'如花'
    17.       }
    18.   }
    19. });
    20. script>

    value、name、index 这几个字符可以自己定义,分别表示每次循环内容的值、键、序号。

    • value: 循环中每条数据的值 小鱼、20、如花

    • name: 循环中每天数据的键 username、age、girl

    • index: 循环的序号,从0开始

    页面效果如下:

    5.4 遍历对象数组:嵌套的for循环

    1. <div id="app">
    2. <table style="border: 1px solid black">
    3.            <tr>
    4.                <th>姓名th>
    5.                <th>年龄th>
    6.                <th>联系方式th>
    7.            tr>
    8.            <tr v-for="(stu,index) in students" v-bind:key="index">
    9.                <td>{{stu.name}}td>
    10.                <td>{{stu.age}}td>
    11.                <td>{{stu.phone}}td>
    12.            tr>
    13.        table>
    14. div>
    15.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    16. <script>
    17.    new Vue({
    18.   el:'#app',
    19.   data:{
    20.       students:[
    21.               {
    22.                    name:'zs',
    23.                    age:18,
    24.                    phone:'111'
    25.               },
    26.               {
    27.                    name:'ls',
    28.                    age:18,
    29.                    phone:'222'
    30.               },{
    31.                    name:'ww',
    32.                    age:18,
    33.                    phone:'333'
    34.               }
    35.           ]
    36.   }
    37. });
    38. script>

    可以清楚的看到,此时数据源是一个student数组,通过两层v-for循环,外层遍历数组中的每个student对象,内层v-for遍历每个对象的v、k、i。

    六、Vue的属性绑定

    Vue提供了多个关键字,能快速的将数据对象中的值绑定在视图层中。

    6.1 v-model

    通过v-model将标签的value值与vue对象中的data属性值进行绑定。

    1. <html>
    2. <head>
    3. <meta charset="utf-8" />
    4. <title>title>
    5. head>
    6. <body>
    7. <div id="app">
    8. <input type="text" v-model="title">
    9. {{title}}
    10. div>
    11. body>
    12.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    13. new Vue({
    14. el:'#app',
    15. data:{
    16. title:"hello vue"
    17. }
    18. })
    19. script>
    20. html>

    此时input标签中加入了“v-model='title'”,表示input的value值与vue对象中的title属性绑定,当在input输入框中输入内容会实时修改title的值。于是{{title}}插值表达式能实时输出input输入框内的值。

    页面效果如下:

     6.2 v-bind

    我们知道插值表达式是不能写在html的标签的属性内的,那如果一定要用vue中的属性作为html标签的属性的内容,就可以通过v-bind进行属性绑定。

    1. <html>
    2. <head>
    3. <meta charset="utf-8" />
    4. <title>title>
    5. head>
    6. <body>
    7. <div id="app">
    8. <a v-bind:href="link">a>
    9. div>
    10. body>
    11.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    12. new Vue({
    13. el:'#app',
    14. data:{
    15. link:'http://www.baidu.com'
    16. }
    17. })
    18. script>
    19. html>

    这样,a标签内的href属性就可以使用vue对象中的属性值。

    注意: v-bind也可以简写,使用冒号“:”来代替。

    bind:href='link'>  等价于  'link'>

    七、Vue的事件绑定 

    关于事件,要把握好三个步骤:设参、传参和接参。

    1. <html>
    2. <head>
    3. <meta charset="utf-8" />
    4. <title>title>
    5. head>
    6. <body>
    7. <div id="app">
    8. sum={{sum}}<br/>
    9. {{sum>10?'总数大于10':'总数不大于10'}}<br/>
    10. <button type="button" @click="increase(2)">增加button>
    11. div>
    12. body>
    13. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
    14. <script type="text/javascript">
    15. new Vue({
    16. el:'#app',
    17. data:{
    18. sum:0
    19. },
    20. methods:{
    21. increase:function(s){
    22. this.sum+=s
    23. }
    24. }
    25. })
    26. script>
    27. html>

    从这里例子中:

    设参:

    <button type="button" @click="increase(2)">增加button>

    传参: 

    increase:function(s)

     接参:

    this.sum+=s

    注意:increase:function(s){ }函数可以写成increase(s){ }

    接下来我们来看一下VUE中如何进行事件绑定。

    7.1 v-on

    通过配合具体的事件名,来绑定vue中定义的函数

    1. <html>
    2. <head>
    3. <meta charset="utf-8" />
    4. <title>title>
    5. head>
    6. <body>
    7. <div id="app">
    8. <input type="text" v-on:click="changeMajor"  />
    9. div>
    10. body>
    11. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
    12. <script type="text/javascript">
    13. new Vue({
    14.   el:'#app',
    15.   data:{
    16.       major:'java'
    17.   },
    18.   methods:{
    19.       sayHi(){
    20.           alert("HELLO VUE!");
    21.       },
    22.       changeMajor(){
    23.           console.log("change Title")
    24.       }
    25.   }
    26. script>
    27. html>

    此时,该按钮,在点击时将会调用Vue对象中定义的changeMajor方法。

    注意: v-on也可以简写,使用"@"替代。

    <input type="text" @click="changeMajor"  />

    7.2 事件修饰符

    可以使用Vue中定义好的事件修饰符,快速达到效果。查看以下例子:

    1. <head>
    2. <meta charset="utf-8" />
    3. <title>title>
    4. head>
    5. <body>
    6. <div id="app">
    7. <p @mousemove="mm">
    8. x:{{x}}
    9. y:{{y}}
    10. <span @mousemove.stop>鼠标移动到此即停止span>
    11. p>
    12.            <div @click = "doDivClick" style="width: 100px;height: 100px;border: 1px solid black">
    13.            <a @click.stop="doThis" href="https://www.baidu.com">
    14.               百度
    15.            a>
    16.        div>
    17. div>
    18. body>
    19. <script   <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    20. new Vue({
    21. el:'#app',
    22. data:{
    23. x:0,
    24. y:0
    25. },
    26. methods:{
    27. mm(event){
    28. this.x = event.clientX;
    29. this.y = event.clientY;
    30. },
    31. stopm(event){
    32. event.stopPropagation();
    33. },
    34. doThis(){
    35.               alert("执行到了a的click");
    36.           },
    37.           doDivClick(){
    38.               alert("执行到了div的click");
    39.           }
    40. }
    41. })
    42. script>

    当鼠标经过P标签区域内时,区域内就会显示X和Y轴的坐标,如果经过P标签内的Span标签内时,此时会调用事件属性mousemove.stop预定的效果,鼠标移动的效果将会被取消,X和Y不再显示信息。

    7.3计算属性:computed

    7.3.1 什么是计算属性

    计算属性的重点突出在 属性 两个字上(属性是名词),首先它是个 属性 其次这个属性有 计算 的能力(计算是动词),这里的 计算 就是个函数;简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;

    7.3.2 计算属性与方法的区别

    1. html>
    2. <html>
    3. <head>
    4.    <meta charset="UTF-8">
    5.    <title>布局篇 计算属性title>
    6.    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js">script>
    7. head>
    8. <body>
    9. <div id="vue">
    10.    <p>调用当前时间的方法:{{currentTime1()}}p>
    11.    <p>当前时间的计算属性:{{currentTime2}}p>
    12. div>
    13. <script type="text/javascript">
    14.    var vm = new Vue({
    15.        el: '#vue',
    16.        data: {
    17.            message: 'Hello Vue'
    18.       },
    19.        methods: {
    20.            currentTime1: function () {
    21.                return Date.now();
    22.           }
    23.       },
    24.        computed: {
    25.            currentTime2: function () {
    26.                this.message;
    27.                return Date.now();
    28.           }
    29.       }
    30.   });
    31. script>
    32. body>
    33. html>

    说明

    • methods:定义方法,调用方法使用 currentTime1(),需要带括号

    • computed:定义计算属性,调用属性使用 currentTime2,不需要带括号;this.message 是为了能够让 currentTime2 观察到数据变化而变化

    注意:methods 和 computed 里不能重名

    7.3.3 测试效果 

    仔细看图中说明,观察其中的差异

    7.3.4 结论

    调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点;计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销

    八、Vue的组件化

    8.1 什么是“组件化”

    Vue的组件化设计思想借鉴了Java的面向对象思想。Java认为万物皆对象,在Vue中,万物皆组件。

    也就是说,在实际的vue项目中,以及使用了Vue框架的项目中,Vue的对象都会以组件的形式出现,能被反复使用。

    要想实现组件化,需要在页面中注册组件:关于注册的方式有两种,分别是全局注册和本地注册。

    8.1.1 组件的全局注册

    1. html>
    2. <html lang="en">
    3. <head>
    4.    <meta charset="UTF-8">
    5.    <title>vue组件的全局注册title>
    6. head>
    7. <body>
    8.    <div id="app">
    9.        <model1>model1>
    10.        <model1>model1>
    11.        <model1>model1>
    12.    div>
    13.        <hr/>
    14.    <div id="app1">
    15.        <model1>model1>
    16.        <model1>model1>
    17.        <model1>model1>
    18.    div>
    19. body>
    20.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    21. <script>
    22. //通过Vue.component实现组件的全局注册,全局注册后的组件可以被重复使用。
    23.    Vue.component("model1",{
    24.        template:"

      {{title}}

      "
      ,
    25.        data:function(){
    26.            return {
    27.                title:"hello vue"
    28.           }
    29.       },
    30.        methods:{
    31.            btnfn:function(){
    32.                alert("hello !!!");
    33.           }
    34.       }
    35.   });
    36.    new Vue({
    37.        el:'#app'
    38.   })
    39.    new Vue({
    40.        el:'#app1'
    41.   })
    42. script>
    43. html>

    8.1.2 组件的本地注册

    vue的全局注册,也就意味着在页面的任意一个被vue绑定过的div中,都可以使用全局注册了的vue组件。

    但是,如果是对vue组件进行本地注册,那么在其他被vue绑定的div中,不能使用该组件。

    1. html>
    2. <html lang="en">
    3. <head>
    4.    <meta charset="UTF-8">
    5.    <title>vue组件的本地(局部)注册title>
    6. head>
    7. <body>
    8.    <div id="app">
    9.        <model11>model11>
    10.    div>
    11. <hr/>
    12.    
    13.    <div id="app1">
    14.        <model11>model11>
    15.    div>
    16. body>
    17.  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    18. <script>
    19.    new Vue({
    20.        el:'#app',
    21.        components:{
    22.            "model11":{
    23.                template:"

      {{title}}

      "
      ,
    24.                data:function(){
    25.                    return {
    26.                        title:"hello vue"
    27.                   }
    28.               },
    29.                methods:{
    30.                    btnfn:function(){
    31.                        alert("hello !!!");
    32.                   }
    33.               }
    34.           }
    35.       }
    36.   })
    37.    new Vue({
    38.        el:'#app1'
    39.   })
    40. script>

    8.1.3 小结

    这是一个完整的Vue组件。该组件包含了三个部分:template(html视图层内容)、script(Model层)、style(CSS样式)。这样封装好的组件可以被复用,也可以作为其他组件的组成部分而被封装——Java的面向对象再次体现。

    • 特点1: template标签内,必须有且只能有一个根标签。

    • 特点2: componet中注册的组件中的data,必须是已函数的形式。

      如下:

    1. data:function(){
    2.     return {
    3.           title:"hello vue"
    4.     }
    5. }

    8.2 组件的生命周期

    Vue中的组件也是有生命周期的。一个Vue组件会经历:初始化、创建、绑定、更新、销毁等阶段,不同的阶段,都会有相应的生命周期钩子函数被调用。

    组件的生命周期钩子

        生命周期主要有三个阶段:

    • 一,初始化显示;(重要勾子 mounted 网页加载完毕触发)
    • 二,更新显示;(重要勾子beforeUpdate 数据属性更新前)
    • 三,死亡;(重要勾子beforeDestroy vm死亡前)

       每个生命周期都会有对应的生命周期的函数,或者叫做勾子函数;

    1. <html>
    2. <head>
    3.    <meta charset="UTF-8">
    4.    <title>Titletitle>
    5.    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js">script>
    6. head>
    7. <body>
    8.    <pre>每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、
    9.       将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,
    10.       这给了用户在不同阶段添加自己的代码的机会。pre>
    11.    <div id="app">
    12.        <p>{{name}}p>
    13.        <button @click="update">updatebutton>
    14.        <button @click="destroy">destroybutton>
    15.    div>
    16. <script type="text/javascript">
    17.    new Vue({
    18.        el:"#app",
    19.        data:{
    20.            a:1,
    21.            name:"zs"
    22.       },
    23.        methods:{
    24.            update(){
    25.                this.name = Math.random() +"---";
    26.           },
    27.            destroy(){
    28.                this.$destroy();
    29.           }
    30.       },
    31.        beforeCreate(){
    32.          console.log("创建vue实例之前");
    33.       },
    34.        created(){
    35.            //
    36.            console.log("vue实例创建成功");
    37.            console.log(this.a);
    38.       }
    39.       /* created: () => console.log(this.a)*/
    40.       ,
    41.        beforeMount(){
    42.            console.log("vue对象挂载之前");
    43.       },
    44.        mounted(){
    45.            // 只执行一次   页面加载完之后执行       比如 咱们在 页面加载完毕 发送ajax请求 获取数据
    46.            console.log(" mounted   挂载完毕")
    47.       },
    48.        beforeUpdate(){
    49.            // 可执行多次
    50.            console.log("data更新之前执行");
    51.       },
    52.        updated(){
    53.            // 可执行多次
    54.            console.log("data更新之后执行");
    55.       },
    56.        beforeDestroy(){
    57.            // 只执行一次
    58.            console.log("vue实例销毁之前执行");
    59.       },
    60.        destroyed(){
    61.            // 只执行一次
    62.            console.log("vue实例销毁之后执行");
    63.       }
    64.   });
    65. script>
    66. body>
    67. html>

    九、使用Vue-Cli搭建Vue项目

    9.1 什么是vue-cli

    cli: Command Line 命令行工具,vue-cli就是vue的命令行工具,也称之为脚手架,使用vue-cli提供的各种命令可以拉取、创建、运行我们需要使用到的框架,比如webpack、Element UI、Element Admin等等。那么要想使用vue-cli命令,需要先安装node.js。

    9.2 node.js的介绍及安装

    node.js的介绍

    node.js提供了前端程序的运行环境,可以把node.js理解成是运行前端程序的服务器。

    node.js的安装

    从官网下载安装即可: 下载 | Node.js 中文网

    测试node.js是否安装成功: 在DOS窗口中输入“node -v” 查看版本,如果看到版本,就表示安装成功。

    9.3 使用node.js安装vue-cli

    使用如下命令安装vue-cli

    1. npm install -g vue-cli   安装的是2.9.6 版本     -------   不装这个
    2. npm install  -g   @vue/cli     安装的是新版本   新版本 支持 vue ui
    • npm: 使用node.js的命令

    • install: 安装

    • vue-cli: 要安装的vue-cli

    • -g: 全局安装

    注意 这里的安装可能需要管理员权限

    安装完了之后 可能被windows的安全策略限制 参考

    VSCode报错:vue : 无法加载文件 D:\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。_没有咸鱼的梦想的博客-CSDN博客

    当出现以下界面,表示正在安装:

    如果使用npm官方镜像速度比较慢,可以使用淘宝镜像来安装:

    npm install -g cnpm --registry=https://registry.npm.taobao.org

    之后使用npm命令时就可以替换成cnpm

    1. cnpm install vue-cli -g
    2. cnpm install
    3. cnpm run dev

    9.4创建vue项目

    dos命令输入vue ui会进入如下图:

    创建项目 不保存预设 然后 后台就开始下载文件

    创建好之后 页面跳转到仪表盘

    可以在这里 安装一些插件 比如 axios element-ui 等等

    这是已经安装的插件

    点 添加插件

    安装 ajax 插件 axios

    然后 可以关掉仪表盘,使用vscode 打开 刚才创建的工程 使用 vue run serve 启动工程,

    9.4.1配置vue片段

    打开VSCode,文件—>首选项—>配置用户代码片段 

    输入一下代码:配置完成后新建.vue文件输入vue回车就会生成以下代码。

    1. {
    2. "Print to console": {
    3. "prefix": "vue",
    4. "body": [
    5. "",
    6. "",
    7. "",
    8. "",
    9. ""
    10. ],
    11. "description": "生成vue模板"
    12. }
    13. }

    9.5 使用vue-cli下载项目骨架搭建我们的项目

    就像maven一样,vue为我们提供了一些官方项目骨架。使用vue list命令可以列出当前官方提供的骨架,可以使用这些骨架来快速搭建出项目。

    vue list

    完事 用vscode 打开项目文件夹

    9.6vue工程的组件使用

    9.7父组件向子组件传递数据---父子组件之间

    父组件

    消息订阅与发布组件PubSub

    9.8 消息订阅与发布组件PubSub

    我们前面讲了父子组件之间通过prop来实现消息传递;但是再其他情况,比如兄弟组件,爷孙组件消息传递时候,就要用到高级的消息订阅与发布;

    1.首先我们安装下消息订阅与发布pubsub组件;

    npm install --save pubsub-js

    2.把 pubsub 配置成全局组件 在 main.js 中配置

    3.在 父组件中 订阅消息 可以在 mounted 钩子函数中 监听消息

    在这里 使用了 箭头函数 => ,在箭头函数中 的 this 代表 当前 vue 对象,如果 使用一般函数 ,那么在这个函数内 this 就代表PubSub对象,所以 在这里 咱们使用 =>箭头函数

    在别的组件中 发布消息

    注意: 执行上面的案例 会发现 订阅消息的回调函数 执行了两次 , 我们需要在我们每次接受数据pubsub.subscribe的时候,先执行pubsub.unsubscribe操作就好了,就完美解决了,这样你接收以后的callback只执行一次

    1. PubSub.unsubscribe();
    2. PubSub.subscribe(eventName, callback);   //这样 回调就只执行一次

    9.9插槽 slot

    父组件向子组件传递标签,通过slot 插槽实现

    主要作用:

    某一个区块,先占位,然后可以动态的搞个标签进去,方便切换该位置的内容,无需再搞多个页面。

    父组件 直接定义标签p 注意 slot 属性

    子组件 使用 slot 标签 占位置 注意 slot 标签的name 属性,当父组件没有传对应的插槽(属性值对应)内容时,会显示插槽默认内容

    9.10 使用Webpack骨架快速创建项目

    常用命令:

    • npm install

      在运行和调试项目前,一般都需要先执行该命令,目的是安装项目运行所需要的环境。

    • npm run dev

      以调试的方式运行项目

    • npm run build

      生成用于项目部署所需的最小资源,生成的内容存放在build文件夹内。

    Webpack是一个前端资源的打包工具,它可以将js、image、css等资源当成一个模块进行打包。

    从图中我们可以看出,Webpack可以将js、css、png等多种静态资源进行打包,使用webpack有什么好处呢?

    1、模块化开发程序员在开发时可以分模块创建不同的js、css等小文件方便开发,最后使用webpack将这些小文件打包成一个文件,减少了http的请求次数。webpack可以实现按需打包,为了避免出现打包文件过大可以打包成多个文件。

    2、编译typescript、ES6等高级js语法随着前端技术的强大,开发中可以使用javascript的很多高级版本,比如:typescript、ES6等,方便开发,webpack可以将打包文件转换成浏览器可识别的js语法。

    3、CSS预编译webpack允许在开发中使用Sass和Less等原生CSS的扩展技术,通过sass-loader、less-loader将Sass和Less的语法编译成浏览器可识别的css语法

    4.使用vue.js开发大型应用需要使用webpack打包工具

    vue init webpack my-project1
    • webpack: 骨架名称

    • my-project1: 项目名称 

    过程中会出现如下界面,需要手动操作。
    出现如下界面,表示安装成功。

    进入到my-project1文件夹内后,使用以下命令来运行项目。

    npm run dev

    访问http://localhost:8081,页面效果如下:

     十、Vue-router 路由

    10.1 安装路由模块

    npm install vue-router --save 

    10.2 引入路由模块并使用

    创建views 文件夹 其下面创建Index.vue 和 Menu1.vue

    在main.js中引入路由模块并使用

    1. import Vue from 'vue'
    2. import App from './App'
    3. import router from './router'  //引入路由模块
    4. Vue.config.productionTip = false
    5. /* eslint-disable no-new */
    6. new Vue({
    7.  el: '#app',
    8.  router, //使用路由模块
    9.  components: { App },
    10.  template: ''
    11. })

     在 router文件夹下 的index.js 是 路由的配置文件

    index.js中:

    1. import Vue from 'vue'
    2. import Router from 'vue-router'
    3. import HelloWorld from '@/components/HelloWorld'
    4. import Index from '@/views/Index'
    5. import Menu1 from '@/views/Menu1'
    6. Vue.use(Router)
    7. export default new Router({
    8.  routes: [
    9.   {
    10.      path: '/',
    11.      name: 'HelloWorld',
    12.      component: HelloWorld
    13.   },
    14.   {
    15.      path: '/index',
    16.      name: 'Index',
    17.      component: Index
    18.   },
    19.   {
    20.      path: '/menu1',
    21.      name: 'Menu1',
    22.      component: Menu1
    23.   }
    24. ]
    25. })

    在App.vue 中的路由写法

    1. <div class="menu">
    2.      <ul>
    3.        <li>
    4.          
    5.          <router-link to="/index">首页router-link>
    6.        li>
    7.        <li>
    8.          
    9.          <router-link to="/menu1">菜单1router-link>
    10.        li>
    11.      ul>
    12.    div>
    13.    <div class="content">
    14.      <router-view>router-view>
    15.    div>

    通过 router-link 向路由配置发送请求 ,结果会在 router-view 显示

    10.3嵌套路由

    Menu1.vue是在前面创建的views文件夹下 继续嵌套 下级页面 配置嵌套路由,其他代码有vue片段生成

    Menu1.vue

    1. <div>
    2.     {{msg}}
    3.      <ul>
    4.          <li>
    5.            <router-link to="/menu1/submenu1">子菜单1router-link>
    6.          li>
    7.          <li>
    8.            <router-link to="/menu1/submenu2">子菜单2router-link>
    9.          li>
    10.        ul>
    11.        <div class="content">
    12.                <router-view>router-view>
    13.      div>
    14.  div>

    在路由配置文件src文件夹下router文件夹下的index.js中

    1. {
    2.      path: '/menu1',
    3.      name: 'Menu1',
    4.      component: Menu1,
    5.      children:[   // 子路由
    6.       {
    7.          path:'/menu1/submenu1',    // 当然 对应的 子组件 得创建好
    8.          component: () => import('@/views/SubMenu1.vue')   // 这样就不用在文件上面配置了
    9.       },
    10.       {
    11.          path:'/menu1/submenu2',
    12.          component: () => import('@/views/SubMenu2.vue')
    13.       },
    14.       {
    15.          path:'',
    16.          redirect:'/menu1/submenu1'     // 默认显示submenu1
    17.       }
    18.     ]
    19.   },

    在views文件夹下创建SubMenu1.vue,其他代码vue片段生成