Vue框架-基础知识(vue指令、实例生命周期、计算属性与监听属性、插槽理解、组件介绍、数据交互、ES6语法等)

Vue.js 介绍

  • vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的。相比于Angular.js,Vue.js提供了更加简洁、更易于理解的API,使得我们能够快速地上手并使用Vue.js。

什么是MVVM模式?

MVVM

  • ViewModel是Vue.js的核心,它是一个Vue实例。Vue实例是作用于某一个HTML元素上的,这个元素可以是HTML的body元素,也可以是指定了id的某个元素。

当创建了ViewModel后,双向绑定是如何达成的呢?

  • 从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据.
  • 从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。

下面展示一下栗子:

  • vue的使用是从一个对象开始的,先创建一个js的对象 new Vue
  • el查找标签的参数
  • data存放数据的参数
  • methods封装函数的参数
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <!--这是我们的View-->
        <div id="app">
            {{ message }}
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 这是我们的Model
        var exampleData = {
            message: 'Hello World!'
        }

        // 创建一个 Vue 实例或 "ViewModel"
        // 它连接 View 与 Model
        new Vue({
            el: '#app',
            data: exampleData
        })
    </script>
</html>
  • 使用Vue的过程就是定义MVVM各个组成部分的过程的过程。
    • 1:定义View
    • 2:定义Model
    • 3:创建一个Vue实例或者ViewModel,它用于连接View和Model
  • 在创建Vue实例时,需要传入一个选项对象,选项对象可以包含数据挂载元素方法模生命周期钩子等等。

    • 1.选项对象el属性指向Viewel: '#app'表示该Vue实例将挂载到<div id="app">...</div>这个元素;data属性指向Modeldata: exampleData表示我们的Model是exampleData对象
    • 2.Vue.js有多种数据绑定的语法,最基础的形式是·文本插值(也叫大胡子),使用一对大括号语法,在运行时{{ message }}会被数据对象的message属性替换,所以页面上会输出”Hello World!”。

    下面举一个双向绑定栗子:

  • MVVM模式本身是实现了双向绑定的,在Vue.js中可以使用v-model指令在表单元素上创建双向数据绑定。

        <!--这是我们的View-->
        <div id="app">
            <p>{{ message }}</p>
            <input type="text" v-model="message"/>
        </div>
  • 可以把上面的代码,给它包含在< body>标签中进行一下运行,能更深刻的理解一下v-model指令的双向绑定。

Vue.js的常用指令

什么是vue.js的指令呢?

  • Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性
v-if指令
  • v-if是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:

    v-if="content"
  • v-if取值为false不是隐藏 是删除标签(销毁标签)

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title></title>
    </head>
    <body>
    <div id="app">
      <h1>Hello, Vue.js!</h1>
      <h1 v-if="yes">Yes!</h1>
      <h1 v-if="no">No!</h1>
      <h1 v-if="age >= 25">Age: {{ age }}</h1>
      <h1 v-if="name.indexOf('fe') >= 0">Name: {{ name }}</h1>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
    
      var vm = new Vue({
          el: '#app',
          data: {
              yes: true,
              no: false,
              age: 28,
              name: 'fe_cow'
          }
      })
    </script>
    </html>
  • 大家能想象出来下面的页面哪些数据不会出现么 ?

    • 我们需要注意的是:yes, no, age, name这4个变量都来源于Vue实例选项对象的data属性。
    • 数据的yes属性为true,所以“YES!”会被输出。
    • 数据的no属性为false,所以”No!”不会被输出。
    • 运算式age >= 25返回true,所以”Age: 28”会被输出。
    • 运算式name.indexOf('fe') >= 0返回false,所以”Name: fe_cow”会被输出。

v-if指令是根据条件表达式的值(v-if='xxx')来执行元素的插入或者删除行为。

v-else指令
  • 可以用v-else指令为v-ifv-show添加一个“else块”。v-else元素必须立即跟在v-ifv-show元素的后面——否则它不能被识别。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <title></title>
    </head>
    <body>
    <div id="app">
      <h1 v-if="age >= 25">Age: {{ age }}</h1>
      <h1 v-else>Name: {{ name }}</h1>
      <h1>---------------------分割线---------------------</h1>
      <h1 v-show="name.indexOf('1') >= 0">Name: {{ name }}</h1>
      <h1 v-else>Sex: {{ sex }}</h1>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
      var vm = new Vue({
          el: '#app',
          data: {
              age: 28,
              name: 'fe_cow',
              sex: 'cow'
          }
      })
    </script>
    </html>
  • v-else元素是否渲染在HTML中,取决于前面使用的是v-if还是v-show指令。

  • v-if为true,后面的v-else不会渲染到HTML;v-show为true,但是后面的v-else仍然可以渲染到HTML中。

v-show 指令
  • v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。

  • 下面我们举个栗子:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title></title>
    </head>
    <body>
    <div id="app">
      <h1>Hello, Vue.js!</h1>
      <h1 v-show="yes">Yes!</h1>
      <h1 v-show="no">No!</h1>
      <h1 v-show="age >= 25">Age: {{ age }}</h1>
      <h1 v-show="name.indexOf('fe') >= 0">Name: {{ name }}</h1>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
    
      var vm = new Vue({
          el: '#app',
          data: {
              yes: true,
              no: false,
              age: 28,
              name: 'fe_cow'
          }
      })
    </script>
    </html>
  • 可能有同学会发现,这不是更上面的v-if没有什么区别么?指示命令换成了v-show

    • 打开浏览器(chrome)按F12,找到Elements,找到你内容的标签,查看没有展现出来的代码变成了<h1 style="display: none;">No!</h1>,发现跟上面的v-if的区别了吧。
    • 如果一个标签要么显示要么隐藏 为了提高代码执行效率可以用v-show,但是如果是多个标签之前切换显示隐藏只能用v-if。
v-for指令
  • v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似:
    • v-for:列表和字典
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <!-- v-for:  列表 和 字典 -->
    <div id="app">
        <ul>
            <!-- i就是各个数据 -->
            <li v-for="i in mylist"> {{ i }}</li>
        </ul>
        <!-- 下标、数据 -->
        <!-- ()书写两个临时变量,第一个表示数据,第二个表示下标 -->
        <ul>
            <li v-for="(i, j) in mylist">{{j+1}}{{ i }}</li>
        </ul>

        <ul>
            <!-- 只有一个临时变量表示的是value值 -->
            <li v-for="i in mydict">{{ i }}</li>
        </ul>
        <ul>
            <!-- 如果小括号写两个临时变量:第一个是value值,第二个是key值 -->
            <li v-for="(i, j) in mydict">{{ j }}:{{i}}</li>
        </ul>
    </div>
    <script>
    var vm = new Vue({
        el:'#app',
        data:{
            mylist: ['邪不压正1', '邪不压正2', '邪不压正3'],
            mydict: {'name':'laowang', 'age':38}
        }
    })
    </script>
</body>
</html>
  • 我们在选项的data属性中定义了一个mylist数组,mydicct字典,然后在#app元素内使用v-for遍历mylist数组和mydict字典。数组可以输出索引,字典也可以输出键值,这点跟python中拆包很像。
v-bind指令
  • v-bind指令:控制html内容控制html属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <!-- 数据显示的方式:控制html内容  控制html属性 -->
    <div id="app">
        <div>{{ num }}</div>
        <div>{{ str }}</div>
        <div>{{ num + 1}}</div>
        <div>{{ str.split('').reverse().join('') }}</div>
        <!-- 三元运算符或三元表达式  条件?条件成立的命令:条件不成立的命令  -->
        <div>{{ bool?'成立':'不成立' }}</div>
        <!-- 完整写法v-bind:html属性   化简写法 :html属性 -->
        <!-- v-xxx  : 都是vue的指令:具有特殊功能的语法规则 -->
        <a v-bind:href="url1" class="box">控制html属性href</a>
        <a :href="url2">控制html属性href 淘宝</a>
    </div>
    <script>
    var vm = new Vue({
        el:'#app',
        data:{
            num:1,
            str:'abcdefg',
            bool:false,
            url1:'http://www.baidu.com',
            url2:'http://www.taobao.com'
        }
    })
    </script>
</body>
</html>
绑定class html属性
  • 将v-bind指令也可以绑定class html属性, 如果isclass1是true的话,就会绑定class1这个类。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- 对象(存到vm对象中,直接标签身上写) 和  数组 -->
        <!-- 取值是true添加这个类,否则不添加 -->
        <div :class="{class1:isclass1, class2:isclass2}">1111111111111</div>
        <div :class="myobject1">222222222</div>
        <!-- 数组 -->
        <div :class="[myclass3, myclass4]">333333</div>
        <!-- ***** 三元运算符 -->
        <div :class="[isclass2?'aa':'bb']">44444444</div>
    </div>
    <script>
    var vm = new Vue({
        el:'#app',
        data:{
            isclass1:true,
            isclass2:false,
            myobject1:{
                active:false,
                current:true
            },
            myclass3:'class3',
            myclass4:'class4'
        }
    })
    </script>
</body>
</html>
v-on指令
  • v-on指令用于给监听DOM事件,它的用语法和v-bind是类似的,例如监听< a>元素的点击事件:

    • < a v-on:click=”doSomething”>
  • 有两种形式调用方法:绑定一个方法(让事件指向方法的引用),或者使用内联语句。

    <!DOCTYPE html>
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <div id="app">
              <p><input type="text" v-model="message"></p>
              <p>
                  <!--click事件直接绑定一个方法 没有参数后面就不需要跟小括号-->
                  <button v-on:click="greet">Greet</button>
              </p>
              <p>
                  <!--click事件使用内联语句 hi 是参数传入进去 有参数就有小括号-->
                  <button v-on:click="say('Hi')">Hi</button>
              </p>
          </div>
      </body>
      <script src="js/vue.js"></script>
      <script>
          var vm = new Vue({
              el: '#app',
              data: {
                  message: 'Hello, Vue.js!'
              },
              // 在 `methods` 对象中定义方法
              methods: {
                  greet: function() {
                      // // 方法内 `this` 指向 vm
                      alert(this.message)
                  },
                  say: function(msg) {
                      alert(msg)
                  }
              }
          })
      </script>
    </html>
    v-bind和v-on的缩写
  • Vue.js为最常用的两个指令v-bindv-on提供了缩写方式。v-bind指令可以缩写为一个冒号,v-on指令可以缩写为@符号

     <!--完整语法-->
     <a href="javascripit:void(0)" v-bind:class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
     <!--缩写语法-->
     <a href="javascripit:void(0)" :class="activeNumber=== n + 1 ? 'active' : ''">{{ n + 1 }}</a>
    
     <!--完整语法-->
     <button v-on:click="greet">Greet</button>
    
     <!--缩写语法-->
     <button @click="greet">Greet</button>                                      
    
v-model 表单数据绑定
  • 每个表单的name代表的是key,value代表输入的值。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
      <!-- 表单数据:双向数据绑定:数据从html中来到vue,又可以从vue传递到html中 -->
      <div id="app">
          <input type="text" v-model="txt">
          <div>{{ txt }}</div>
          <select v-model="sel">
              <option value="0">北京</option>
              <option value="1">上海</option>
              <option value="2">广州</option>
          </select>
          <div>{{sel}}</div>
          <!-- 单选框 -->
          <input type="radio" value="nan" v-model="rad"><input type="radio" value="nv" v-model="rad"><div>{{ rad }}</div>
      </div>
      <script>
      var vm = new Vue({
          el:'#app',
          data:{
              txt:'请输入用户名',
              sel:0,
              rad:'nv'
          }
      })
      </script>
    </body>
    </html>

Vue中的样式绑定:

  • 第一种方式 Vue中的class对象绑定:

    • !this.xxxx :取反的意思
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>Vue中class对象绑定</title>
       <script src="js/vue.js"></script>
       <style>
           .activated{
               color: red;
           }
       </style>
    </head>
    <body>
    <div id="app">
       <div @click="handleDivClick"
            :class="{activated: isActivated}">
           hello world
       </div>
    </div>
    <script>
       var vm = new Vue({
           el: '#app',
           data: {
               isActivated: false
           },
           //!this.isActivated 取反的意思
           methods: {
               handleDivClick: function () {
                   this.isActivated = !this.isActivated
               }
           }
       })
    </script>
    </body>
    </html>
    • 第二种方式 Vue种class中数组:
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>Vue中class数组绑定</title>
       <script src="js/vue.js"></script>
       <style>
           .activated{
               color: red;
           }
       </style>
    </head>
    <body>
    <div id="app">
       <div @click="handleDivClick"
            :class="[activated, activatedOne]">
           hello world
       </div>
    </div>
    <script>
       var vm = new Vue({
           el: '#app',
           data: {
               activated: '',
               activatedOne: 'activated-one'
           },
           // 三元表达式? 如果this.activated不为空字符串的时候,就给它变成空
           methods: {
               handleDivClick: function () {
                   this.activated = this.activated === 'activated'? '':'activated'
               }
           }
       })
    </script>
    </body>
    </html>
    • 第三种方式:通过style对象和数组来表达:

    • 还可以在style数组中给它添加一个样式: :style="[styleObj, {fontSize:'20px'}]"

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>Vue中style 对象和数组绑定</title>
       <script src="js/vue.js"></script>
       <style>
           .activated{
               color: red;
           }
       </style>
    </head>
    <body>
    <div id="app">
       <div @click="handleDivClick"
            :style="[styleObj, {fontSize:'20px'}]">
           hello world
       </div>
    </div>
    <script>
       var vm = new Vue({
           el: '#app',
           data: {
               styleObj: {
                   color: 'black'
               }
           },
           // 三元表达式? 如果this.activated不为空字符串的时候,就给它变成空
           methods: {
               handleDivClick: function () {
                   this.styleObj.color =  this.styleObj.color === 'black'? 'red':'black'
               }
           }
       })
    </script>
    </body>
    </html>

Vue中条件渲染:

  • 每次循环的时候,循环标签中最好都带有:key='item.id'值,会提高性能。

  • 当想要修改数组的内容的时候,不能通过修改下边的vm.list[0] = {id:'111',text:'222'}执行,应该采用·数组的变异方法:(push,pop,shift,unshift,splice,sort,reverse)

    • vm.splice(下标, 删除几条,{新增内容})
    • 通过改变数组的引用vm.list = [{},{},{}]
    • 通过Vue.set方法:Vue.set(vm.对象名, 1下标, 5更改的名字)
    • 通过Vue的实例:vm.$set(vm.对象名, 1下标, 5更改的名字)
  • template:模板占位符

  • 给对象添加数据:

    • Vue.set(vm.对象名, “address”,”beijing’) 就可以了

    • 通过Vue实例方法实现:`vm.$set(vm.对象名, ”address’,’beijing’)

实例生命周期:

  • 每个Vue实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新 DOM 等。同时在这个过程中会自动运行一些叫做生命周期钩子的函数,我们可以使用这些函数,在实例的不同阶段加上我们需要的代码,实现特定的功能。
beforeCreate:
  • 实例初始化之后数据观测 (data observer)event/watcher 事件配置之前被调用。
created:
  • 实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始。
beforeMount:
  • 挂载开始之前被调用:相关的 render 函数首次被调用。
mounted:
  • 实例挂载到dom之后被调用,可以当成是vue对象的ready方法来使用,一般用它来做dom的初始化操作
beforeDestroy:
  • 组件被销毁之前调用。
destroyed:
  • 组件销毁之后调用
beforeUpdate:
  • 数据发生变化前调用。
updated:
  • 数据发生变化后调用 。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VUE实例生命周期函数</title>
    <script src="js/vue.js"></script>
</head>
<body>
 <div id="app">
 </div>
 <script>
     // 生命周期函数就是vue实例在某一个时间点会自动执行的函数
     var vm = new Vue({
         el:'#app',
         template:"<div>{{test}}</div>",
         data: {
             test:'hello word'
         },
         // 在实例初始化之后调用
         beforeCreate: function () {
             console.log("beforCreate")
         },
         //在实例创建完成后立即调用
         created: function () {
             console.log("created")
         },
         // 在挂载开始之前被调用 在有template模板的时候不渲染
         beforeMount: function(){
           console.log(this.$el)
           console.log("beforeMount")
         },
         // 在挂载之后可以调用 在实例中有tempalte模板的时候渲染里面的内容
         mounted: function () {
             console.log(this.$el)
             console.log("mounted")
         },
         // 在组件被销毁之前它会被执行   在控制台打vm.$destroy()就会执行这俩个方法
         beforeDestroy: function () {
             console.log("beforeDestroy")
         },
        // 在组件被销毁之后它会执行
        destroyed:function () {
            console.log("destroyed")
        },
        // 在数据被改变之前会执行 在控制台输入: vm.test="dell"  beforeUpdate 和 updated就会被调用
        beforeUpdate: function () {
            console.log("beforeUpdate")
        },
        // 在数据被改变之后会执行
         updated:function () {
            console.log("updated")
        }
     })
 </script>
</body>
</html>

模板语法:

  • 第一种:插值表达式{{}}

  • 第二种:在 < div v-text=’name’> < /div>

  • 第三种:在< div v-html=’name’> < /div>

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>模板语法</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <div>{{name + 'fe_cow'}}</div>
      <div v-text="name + 'fe_cow'"></div>
      <div v-html="name + 'fe_cow'"></div>
    </div>
    <script>
      var vm = new Vue({
          el:'#app',
          data: {
              name:'fe_cow'
              // name:'<h1>fe_cow</h1>'
          }
      })
    </script>
    </body>
    </html>

计算属性:

  • 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。计算属性还有缓存机制, 计算属性有返回值。例如:

    • 第一种写法:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>计算属性 computed方法  缓存机制</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <div>{{fullName}}</div>
      <div>{{age}}</div>
    
    </div>
    <script>
      var vm = new Vue({
          el:'#app',
          data: {
              firstName: 'Fe',
              lastName: 'Cow',
              age: 27
          },
          // 计算属性的缓存, 在控制台中打vm.age = 28 可以观察看,并没有走fullName这里,因为fullName中的this.firstName 和 lastName都没有发生改变
          computed: {
              fullName: function () {
                  console.log('执行了一次计算')
                  return this.firstName + this.lastName
              }
          }
      })
    </script>
    </body>
    </html>
  • 使用methods方法 差值表达式后面有()也能达到计算属性,但是建议不使用,因为它没有缓存:

    • 第二种写法
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>计算属性 methods 不建议使用 没有缓存机制</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <div>{{fullName()}}</div>
      <div>{{age}}</div>
    
    </div>
    <script>
      var vm = new Vue({
          el:'#app',
          data: {
              firstName: 'Fe',
              lastName: 'Cow',
              age: 27
          },
          methods: {
              fullName: function () {
                  console.log('执行了一次计算')
                  return this.firstName + this.lastName
              }
          }
      })
    </script>
    </body>
    </html>
计算属性的setter 和 getter
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性的setter 和 getter</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <div>{{fullName}}</div>
    <div>{{age}}</div>

</div>
<script>
    var vm = new Vue({
        el:'#app',
        data: {
            firstName: 'Fe',
            lastName: 'Cow',
            age: 27
        },
        computed: {
            // 在控制台打 vm.fullName = 'hello word' 改变了fullName的值,set中的value就会接收到 进行切割,重新给firstName 和 lastName重新赋值 
            fullName:{
                get: function () {
                    return this.firstName + this.lastName
                },
                // value set接收到get中 fullName中的值
                set: function (value) {
                    console.log('进入了Set里面')
                    var arr = value.split(' ')
                    this.firstName = arr[0]
                    this.lastName = arr[1]
                }
            }
        }
    })
</script>
</body>
</html>

侦听属性:

  • 侦听属性的作用是侦听某属性值的变化,从而做相应的操作,侦听属性是一个对象,它的是要监听的对象或者变量,值一般是函数,当你侦听的元素发生变化时,需要执行的函数,这个函数有两个形参,第一个是当前值第二个是变化后的值

    • 下面栗子是侦听data中的fullName,如果firstName发生改变,就会调用watch方法,就会改变fullName的值。
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>监听属性 watch</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <div>{{fullName}}</div>
      <div>{{age}}</div>
    
    </div>
    <script>
      var vm = new Vue({
          el:'#app',
          data: {
              firstName: 'Fe',
              lastName: 'Cow',
              fullName: 'Fe_cow',
              age: 27
          },
          watch: {
              firstName:function(){
                  console.log('执行一次')
                  this.fullName = this.firstName + this.lastName
              },
              lastName: function () {
                  console.log('执行二次')
                  this.fullName = this.firstName + this.lastName
              }
          }
      })
    </script>
    </body>
    </html>

过滤器:

  • Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值v-bind 表达式

    <!-- 在双花括号中 -->
    {{ prize | RMB }}
    
    <!-- 在v-bind中 -->
    <div v-bind:id="rawId | formatId"></div>
    • 过滤器实际上是一个函数,可以在一个组件的选项中定义组件内部过滤器:

    • filters:定义的是局部变量:需要在实例内部定义

    filters:{
    RMB:function(value){
      if(value=='')
      {
        return;
      }
      return '¥ '+value;
    }
    }
    • 或者在创建 Vue 实例之前全局定义过滤器

    • Vue.filter('名字',匿名函数){}:定义全局变量:

    Vue.filter('Yuan',function(value){
    if(value=='')
    {
      return;
    }
    return value+'元';
    });
    • 总体的栗子如下:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
      <!-- 作用:格式化文本用的 -->
      <div id="app">
          <!-- 数据 | 过滤器名字 | 2 |3 -->
          <div>{{ price1 | yuan | RMB}}</div>
          <div>{{ price2 | yuan | RMB}}</div>
      </div>
      <div id="box">
          <div>{{ price1 | RMB }}</div>
          <div>{{ price2  |RMB }}</div>
      </div>
      <script>
      // 全局过滤器:作用于所有对象 -- 要求全局过滤器必须定义再所有对象的上面
      // Vue.filter(名字,function(){})
      Vue.filter('RMB', function(vals){
          if(vals == 0){
              return vals
          }
          return '¥' + vals
      })
    
    
      var box = new Vue({
          el:'#box',
          data:{
              price1:999,
              price2:0
          }
      })
      var vm = new Vue({
          el:'#app',
          data:{
              price1:99,
              price2:0
          },
          filters:{
              // mingzi:function(){}
              yuan:function(vals){
                  if(vals == 0)
                  {
                      return vals
                  }
                  return vals +'元'
              }
          }
      })
      </script>
    </body>
    </html>

组件简介:

  • 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树 :

Component Tree

  • 组件(Component)是Vue.js最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。

    组件的创建和注册

  • 基本步骤:

    • Vue.js的组建的使用有3个步骤:1.创建组件构造器 2.注册组件 3.使用组件。

    • 调用Vue.extend()方法创建组件构造器。

    • 调用Vue.compoent()方法注册组件。
    • Vue实例的作用范围内使用组件。
    • 下面举一个栗子:
    <!DOCTYPE html>
    <html>
      <body>
          <div id="app">
              <!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
              <my-component></my-component>
          </div>
      </body>
      <script src="js/vue.js"></script>
      <script>
    
          // 1.创建一个组件构造器  模板是div标签组成的
          var myComponent = Vue.extend({
              template: '<div>This is my first component!</div>'
          })
    
          // 2.注册组件,并指定组件的标签,组件的HTML标签为<my-component>
          Vue.component('my-component', myComponent)
    
          new Vue({
              el: '#app'
          });
    
      </script>
    </html>

理解组件的创建和注册

  • 接下来我们用以下几个步骤来理解组件的创建和注册:

    • 1.vue.extend()是Vue构造器的扩展,调用vue.extend创建一个组件构造器。
    • 2.vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML。
    • 3.使用Vue.component()注册组件时,需要提供2个参数,第1个参数是组件的标签,第2个参数是组件构造器。
    • 4.组件应该挂载到某个Vue实例下,否则它不会生效。
    <!DOCTYPE html>
    <html>
      <body>
          <div id="app1">
              <my-component></my-component>
          </div>
    
          <div id="app2">
              <my-component></my-component>
          </div>
    
          <!--该组件不会被渲染-->
          <my-component></my-component>
      </body>
      <script src="js/vue.js"></script>
      <script>
          var myComponent = Vue.extend({
              template: '<div>This is a component!</div>'
          })
    
          Vue.component('my-component', myComponent)
    
          var app1 = new Vue({
              el: '#app1'
          });
    
          var app2 = new Vue({
              el: '#app2'
          })
      </script>
    </html>

给组件绑定原生事件:

  • 在子组件中绑定原生事件:@click.native="handleClick"

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>给组件绑定原生事件</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="root">
      <child @click.native="handleClick"></child>
    </div>
    <script>
      Vue.component('child',{
          template: '<div>Child</div>div>'
      })
    
      var vm = new Vue({
          el:'#root',
          methods:{
              handleClick:function () {
                  alert('handleClick')
              }
          }
      })
    </script>
    </body>
    </html>

非父子组件间的传值:

  • .bus

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>非父子组件间传值(Bus/总线/发布订阅者模式/观察者模式)</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="root">
      <child content="Fe"></child>
      <child content="cow"></child>
    
    </div>
    <script>
      Vue.prototype.bus = new Vue()
    
      Vue.component('child',{
          // 进行赋值
          data: function() {
            return {
                selfCountent: this.content
            }
          },
          // 把父组件传递过来的参数 进行校验
          props: {
              content: String
          },
          template: '<div @click="handleClick">{{selfCountent}}</div>div>',
          // 点击子组件触发的事件
          methods:{
              handleClick: function () {
                  this.bus.$emit('change', this.selfCountent)
              }
          },
          mounted: function () {
              var this_ = this
              this.bus.$on('change', function (msg) {
                  this_.selfCountent = msg
              })
          }
      })
    
      var vm = new Vue({
          el:'#root'
      })
    </script>
    </body>
    </html>

Vue中的插槽:

  • 子组件中,引入新的标签,可以在标签中引入slot='head'属性,然后在子组件的template:<slot name='head'></slot>给插槽占位。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue中的插槽</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <body-comtent>
          <div class="head" slot="head">head</div>
          <div class="footer" slot="footer">footer</div>
      </body-comtent>
    </div>
    <script>
      Vue.component('body-comtent', {
          template:'<div>' +
          '<slot name="head"></slot>' +
          '<div class="content">content</div>' +
          '<slot name="footer"></slot>' +
          '</div>'
      })
    
      var vm = new Vue({
          el:'#app'
      })
    </script>
    </body>
    </html>

Vue中的插槽的作用域:

  • 应用场景:在子组件中需要使用循环时,父组件控制子组件:

    • 1:在子组件中使用循环遍历的时候在slot标签中定义 :item=item将数据传递给父组件。
    • 2:父组件通过slot-scope="props"它应该定义在tempalte标签中。
    • 3:父组件在使用的时候{{props.item}}就可以将子组件中的循环数据,传递到父组件中。
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue中的插槽作用域</title>
      <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
      <body-comtent>
          <template slot-scope="props">
              <h1>{{props.item}}</h1>
          </template>
      </body-comtent>
    </div>
    <script>
      Vue.component('body-comtent', {
          data:function(){
              return{
                  list: [1,2,3,4]
              }
          },
          template:'<div><ul><slot v-for="item of list" :item=item></slot></ul></div>'
      })
    
      var vm = new Vue({
          el:'#app'
      })
    </script>
    </body>
    </html>

data 必须是函数:

  • 组件就是vue的实例,所有vue实例中属性和方法,组件中也可以用,但是data属性必须是一个函数,因为组件会重复使用在多个地方,为了使用在多个地方的组件数据相对独立,data属性需要用一个函数来返回值。

    // 定义组件
    Vue.component('simple-counter', {
    template: '<button v-on:click="counter += 1">{{ counter }}</button>',
    data: function () {
          return {
          counter: 0
        }
    }
    })
    
    // 使用组件
    <div id="example-2">
    <simple-counter></simple-counter>
    <simple-counter></simple-counter>
    <simple-counter></simple-counter>
    </div>
    ......
    new Vue({
    el: '#example-2'
    })

组件中< style>标签中 scoped:

  • css: scoped 表示是接下来的css只针对这个组件生效。

  • 记住单文组件写js,必须是模块导出的形式:export default{ }

  • @符:就是src文件夹。

全局注册和局部注册

  • 调用vue.component()注册组件时,组件的注册是全局的,这意味着该组件可以在任意Vue示例下使用。

  • 如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册

    <!DOCTYPE html>
    <html>
      <body>
          <div id="app">
              <!-- 3. my-component只能在#app下使用-->
              <my-component></my-component>
          </div>
      </body>
      <script src="js/vue.js"></script>
      <script>
          // 1.创建一个组件构造器
          var myComponent = Vue.extend({
              template: '<div>This is my first component!</div>'
          })
    
          new Vue({
              el: '#app',
              components: {
                  // 2. 将myComponent组件注册到Vue实例下
                  'my-component' : myComponent
              }
          });
      </script>
    </html>

父组件和子组件

  • 我们可以在组件中定义并使用其他组件,这就构成了父子组件的关系。

    <!DOCTYPE html>
    <html>
      <body>
          <div id="app">
              <parent-component>
              </parent-component>
          </div>
      </body>
      <script src="js/vue.js"></script>
      <script>
    
          var Child = Vue.extend({
              template: '<p>This is a child component!</p>'
          })
    
          var Parent = Vue.extend({
              // 在Parent组件内使用<child-component>标签
              template :'<p>This is a Parent component</p><child-component></child-component>',
              components: {
                  // 局部注册Child组件,该组件只能在Parent组件内使用
                  'child-component': Child
              }
          })
    
          // 全局注册Parent组件
          Vue.component('parent-component', Parent)
    
          new Vue({
              el: '#app'
          })
    
      </script>
    </html>
  • 分析一下代码:

    • 1.var Child = Vue.extend(...)定义一了个Child组件构造器。
    • 2.var Parent = Vue.extend(...)定义一个Parent组件构造器。
    • 3.components: { 'child-component': Child },将Child组件注册到Parent组件,并将Child组件的标签设置为child-component
    • 4.template :'<p>This is a Parent component</p><child-component></child-component>',在Parent组件内以标签的形式使用Child组件。
    • 5.Vue.component('parent-component', Parent)全局注册Parent组件。
    • 6.在页面中使用标签渲染Parent组件的内容,同时Child组件的内容也被渲染出来。
  • Child组件是在Parent组件中注册的,它只能在Parent组件中使用,确切地说:子组件只能在父组件的template中使用。

  • 举两个错误的栗子:

    • 以子标签的形式在父组件中使用:
    • 因为当子组件注册到父组件时,Vue.js会编译好父组件的模板,模板的内容也决定了父组件将要渲染的HTML。
    • <parent-component>…</parent-component>相当于运行时,它的一些子标签只会被当作普通的HTML来执行。
    • 不是标准的HTML标签,会被浏览器直接忽视掉。
    • 在父组件标签外使用子组件
    <div id="app">
      <parent-component>
      </parent-component>
      <child-component>
      </child-component>
    </div>
    

组件注册语法糖

  • 以上组件注册的方式有些繁琐,Vue.js为了简化这个过程,提供了注册语法糖。

  • 使用Vue.component()直接创建和注册组件:

    // 全局注册,my-component1是标签名称
    Vue.component('my-component1',{
      template: '<div>This is the first component!</div>'
    })
    
    var vm1 = new Vue({
      el: '#app1'
    })
  • Vue.component()的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template属性定义组件模板。使用这种方式,Vue在背后会自动地调用Vue.extend()

  • 在选项对象的components属性中实现局部注册:

    var vm2 = new Vue({
      el: '#app2',
      components: {
          // 局部注册,my-component2是标签名称
          'my-component2': {
              template: '<div>This is the second component!</div>'
          },
          // 局部注册,my-component3是标签名称
          'my-component3': {
              template: '<div>This is the third component!</div>'
          }
      }
    })

使用scrip或template标签:

  • 尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。 庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来。
  • 使用< script>标签
<!DOCTYPE html>
<html>
    <body>
        <div id="app">
            <my-component></my-component>
        </div>

        <script type="text/x-template" id="myComponent">
            <div>This is a component!</div>
        </script>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 相当于给template模板定义了scrpt标签,通过id进行一个绑定
        Vue.component('my-component',{
            template: '#myComponent'
        })

        new Vue({
            el: '#app'
        })
        // template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译
    </script>
</html>
  • 使用< script>标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略< script>标签内定义的内容。

  • 使用< template>标签

  • 如果使用<template>标签,则不需要指定type属性。

    <!DOCTYPE html>
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <div id="app">
              <my-component></my-component>
          </div>
    
          <template id="myComponent">
              <div>This is a component!</div>
          </template>
      </body>
      <script src="js/vue.js"></script>
      <script>
    
          Vue.component('my-component',{
              template: '#myComponent'
          })
    
          new Vue({
              el: '#app'
          })
    
      </script>
    </html>
  • 在理解了组件的创建和注册过程后,我建议使用

组件的el和data选项

  • 传入Vue构造器的多数选项也可以用在 Vue.extend()Vue.component()中,不过有两个特例: datael
  • Vue.js规定:在定义组件的选项时,datael选项必须使用函数。

使用Props

  • 组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。

    props基础示例:

  • 下面的代码定义了一个子组件my-component,在Vue实例中定义了data选项。

    var vm = new Vue({
      el: '#app',
      data: {
          name: 'keepfool',
          age: 28
      },
      components: {
          'my-component': {
              template: '#myComponent',
              props: ['myName', 'myAge']
          }
      }
    })
  • 如果我们想使父组件的数据,则必须先在子组件中定义props属性,也就是props: ['myName', 'myAge']这行代码。

  • 定义子组件的HTML模板:

    <template id="myComponent">
      <table>
          <tr>
              <th colspan="2">
                  子组件数据
              </th>
          </tr>
          <tr>
              <td>my name</td>
              <td>{{ myName }}</td>
          </tr>
          <tr>
              <td>my age</td>
              <td>{{ myAge }}</td>
          </tr>
      </table>
    </template>
  • 将父组件数据通过已定义好的props属性传递给子组件:

    <div id="app">
      <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
    </div>
  • 在子组件中定义prop时,使用了camelCase命名法。由于HTML特性不区分大小写,camelCase的prop用于特性时,需要转为 kebab-case(短横线隔开)。例如,在prop中定义的myName,在用作特性时需要转换为my-name

  • 在父组件中使用子组件时,通过一下语法将数据传递给子组件:

<child-component v-bind:子组件prop="父组件数据属性"></child-component>

prop的绑定类型

单向绑定

  • 既然父组件将数据传递给了子组件,那么如果子组件修改了数据,对父组件是否会有所影响呢?

  • 我们将子组件模板和页面HTML稍作更改:

     <div id="app">
    
      <table>
          <tr>
              <th colspan="3">父组件数据</td>
          </tr>
          <tr>
              <td>name</td>
              <td>{{ name }}</td>
              <td><input type="text" v-model="name" /></td>
          </tr>
          <tr>
              <td>age</td>
              <td>{{ age }}</td>
              <td><input type="text" v-model="age" /></td>
          </tr>
      </table>
    
      <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
     </div>
    
    <template id="myComponent">
    
         <table>
    
             <tr>
    
                 <th colspan="3">子组件数据</td>
    
             </tr>
    
             <tr>
    
                 <td>my name</td>
    
                 <td>{{ myName }}</td>
    
                 <td><input type="text" v-model="myName" /></td>
    
             </tr>
    
             <tr>
    
                 <td>my age</td>
    
                 <td>{{ myAge }}</td>
    
                 <td><input type="text" v-model="myAge" /></td>
    
             </tr>
    
         </table>
    
     </template>
    
  • 修改了子组件的数据,没有影响父组件的数据。

  • 修改了父组件的数据,同时影响了子组件。

  • prop默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态 。

双向绑定

  • 可以使用.sync显式地指定双向绑定,这使得子组件的数据修改会回传给父组件。

  • <my-component v-bind:my-name.sync="name" v-bind:my-age.sync="age"></my-component>

    单次绑定

  • 可以使用.once显式地指定单次绑定,单次绑定在建立之后不会同步之后的变化,这意味着即使父组件修改了数据,也不会传导给子组件

  • <my-component v-bind:my-name.once="name" v-bind:my-age.once="age"></my-component>

数据交互:

  • vue.js没有集成ajax功能,要使用ajax功能,可以使用vue官方推荐的axios.js库来做ajax的交互

axios完整写法:

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
  • axios请求的写法也写成get方式post方式

执行get请求:

  • .then就是请求成功.catch就是请求失败
  • 有两种写法,可以用params来进行传参。
// 为给定 ID 的 user 创建请求
// then是请求成功时的响应,catch是请求失败时的响应

axios.get('/user?ID=12345')
// .then 就是请求成功
.then(function (response) {
  console.log(response);
})
// .catch就是请求失败
.catch(function (error) {
  console.log(error);
});

// 可选地,上面的请求可以这样做
axios.get('/user', {
  params: {
    ID: 12345
  }
})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});

执行post请求:

  • 里面的参数就是key, value形式。
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});

ES6语法

  • ES6是JavaScript语言的新版本,它也可以叫做ES2015,之前学习的JavaScript属于ES5,ES6在它的基础上增加了一些语法,ES6是未来JavaScript的趋势,而且vue组件开发中会使用很多的ES6的语法,所以掌握这些常用的ES6语法是必须的 。

变量声明let和const

  • let和const是新增的声明变量的开头的关键字,在这之前,变量声明是用var关键字,这两个关键字和var的区别是,它们声明的变量没有预解析,let和const的区别是,let声明的是一般变量const申明的常量不可修改
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    // alert(num1)
    var num1 = 1
    num1 = 10
    // let const

    // alert(num2)
    let num2 = 2
    num2 = 20

    // alert(num3)
    const num3 = 3   // 常量:不能修改值的变量
    num3 = 30
    </script>
</head>
<body>

</body>
</html>

箭头函数:

  • 可以把箭头函数理解成匿名函数的第二种写法,箭头函数的作用是可以在对象中绑定this,解决了JavaScript中this指定混乱的问题。

  • var fn3(函数名) = (参数) => {命令}

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script>
      // function fn1(a, b){
      //     var rs = a + b
      //     alert(rs)
      // }
      // fn1(1, 2)
      var fn2 = function(a, b){
          var rs = a + b
          alert(rs)
      }
      // fn2(1, 2)
      // var fn3 = (参数) => {命令}
      var fn3 = (a, b) => {
          var rs = a + b
          alert(rs)
      }
      // fn3(1, 2)
      // 一个参数写法
      var fn4 = a =>{
          alert(a)
      }
      // fn4(1)
      // 没有参数写法
      var fn5 = () => {
          alert('ok')
      }
      fn5()
      </script>
    </head>
    <body>
      <!-- 作用:修正this指向问题bug -->
      <!-- 箭头函数是从匿名函数改写而来 -->
    </body>
    </html>

对象的简写

  • javascript对象在ES6中可以做一些简写形式,了解这些简写形式,才能方便我们读懂一些在javascript代码中简写的对象。

  • 下面的栗子:’laowang’的name和’laowang2’的name, key和value相等时,可以保留一个name单词。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script>
      // var laowang = {
      //     name:'laowang',
      //     age:38
      // }
      var name = 'laowang'
      var age = 38
      // var laowang2 = {
      //     name:name,
      //     age:38
      // }
      // es6如果遇到k和v的值相等,省略只保留一个单词也可以
      var laowang2 = {
          name,
          age:38
      }
      alert(laowang2.name)
      alert(laowang2.age)
      </script>
    </head>
    <body>
    
    </body>
    </html>

模块导入import和导出export

  • javascript之前是没有模块的功能的,之前做js模块化开发,是用的一些js库来模拟实现的,在ES6中加入了模块的功能,和python语言一样,python中一个文件就是一个模块,ES6中,一个js文件就是一个模块,不同的是,js文件中需要先导出(export)后才能被其他js文件导入(import)

    // model.js文件中导出
    var person = {name:'tom',age:18}
    export default {person}
    
    // index.js文件夹中导入
    import person from 'js/model.js'
    
    // index.js中使用模块
    person.name
    person.age
    
    /*
    上面导出时使用了default关键字,如果不使用这个关键字,导入时需要加大括号:
    import {person} from 'js/model.js'
    */

页面结构说明:

  • 1.index.html 首先加载的首页面
  • 2.main.js 在加载main.js 文件
  • 3.App.vue 路由
  • 4.各个组件
  • 总结就是:
    • 整个项目是一个主文件index.html,index.html中会引入src文件夹中的main.js,main.js中会导入顶级单文件组件App.vue,App.vue中会通过组件嵌套或者路由来引用components文件夹中的其他单文件组件

组件嵌套:

  • 将单文件组件组合在一起有两种方式,一种是嵌套方式,一种用路由的方式。嵌套的方式代码如下:

    下图示中,假设组件A中要嵌入组件B。

`<template>

    // 在A组件中使用B组件
    <B_zujian></B_zujian>
</template>


<script>
// 先导入B组件,其中'@'表示src目录,组件后的vue扩展名可以省略
import B_zujian from '@/components/B_zjian'

export default{
    name:'A_zujian',
    data:function(){
        return {
            iNum:0
        }
    },
    // 接着在components属性选项中注册
    components:{
        B_zujian
    }
}


</script>`

路由:

  • 可以通过路由的方式在一个组件中加载其他组件,要使用路由功能,需要在main.js中先导入路由的,然后在组件对象中还需要包含它。
import router from './router'

new Vue({
    .....
    router
})
  • 组件中通过路由标签来加载其他的路由:

    • 有简写的办法:
    <!-- 路由标签 -->
    <router-view></router-view>
    
    <!-- 简写成下面一个标签的形式: -->
    <router-view/>
  • 路由标签里面加载哪个组件呢?在router文件中的index.js文件中设置:

     import Vue from 'vue'
     import Router from 'vue-router'
    
    // 导入对应组件 '@' 表示src文件夹
    import MainList from '@/components/MainList'
    import UserList from '@/components/UserList'
    import UpDate from '@/components/UpDate'
    
    // 使用路由模块的固定写法
    Vue.use(Router)
    
    // path为'/'表示路由默认加载的组件
    // 这些路由默认设置的是App.vue中的路由标签加载的组件
    export default new Router({
    routes: [
      {
        path: '/',
        name: 'MainList',
        component: MainList
      },
      {
        path: '/user',
        name: 'UserList',
        component: UserList
      },
      {
        path: '/update',
        name: 'UpDate',
        component: UpDate
      }
    ]
    })
  • 通过链接可以切换路由标签里面对应的组件,链接的地址是上面index.js文件中定义的path值,不过链接标签是"router-link",链接地址用'to'来定义

    <router-link to="/">内容</router-link>
    <router-link to="/user">内容</router-link>
  • 链接地址中可以传递参数,格式如下:

    // name对应的是路由中定义的一个path对应的name属性
    <router-link :to='{name:"UpDate",params:{code:item.code}}'>
  • 有时候需要在组件的js中跳转页面,也就是改变路由,改变路由有下面这些方式:

    // 当前页面重新加载
    this.$router.go('/user');
    
    // 跳转到另外一个路由
    this.$router.push({path:'/user'});
    
    // 获取当前的路由地址
    var sPath = this.$route.path;

数据请求及跨域:

数据请求:

  • 数据请求使用的是ajax,在vue中使用的axios.js,这个文件可以在index.html文件中引入,也可以作为模块导入,在main.js中导入这个模块,然后将它绑定在Vue类的原型上:

    import axios from 'axios'
    Vue.prototype.axios = axios
  • 重点:在组件的js代码中使用axios

    this.axios({......})

跨域请求:

  • vue的自动化工具提供了开发的服务器,我们在这个服务器环境下开发,改动代码可以马上更新显示,错误了还有代码提示,非常方便,但是,如果我们组件中需要数据,而且数据在另一个服务器环境下运行,我们就需要跨域请求数据,vue工具中可以使用代理来跨域请求,设置的方法是:在项目的config文件夹中,打开index.js,在proxyTable一项中设置:

    • ’/apis’ 自定义的代理名
    • target 代理的服务器
    • changeOrigin 是否允许跨域请求
    • pathRewrite 匹配首个页面
    // 'http://localhost:7890' 表示的是要跨域请求的地址
    // 如果请求的地址是:'http://localhost:7890/index_data'
    // 在请求时就可以写成: '/apis/index_data'
    
    '/apis': {
      target: 'http://localhost:7890', 
      changeOrigin: true,
    // 我们是以index开头,所以给它清空就好
      pathRewrite: {
          '^/apis': ''
      }              
    }

    杂文:

  • vue监听回车执行的函数

 @keyup.enter.native
  • 弹性:

    type="flex"
    justify="space-between"  // 留有空白的意思
    :gutter="20" // gutter的实现方式是设置el-col的style
  • label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/82319049