您的位置:首页 > Web前端 > Vue.js

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

2018-09-02 20:50 1331 查看

Vue.js 介绍

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

什么是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属性指向
      View
      el: '#app'
      表示该Vue实例将挂载到
      <div id="app">...</div>
      这个元素;data属性指向
      Model
      data: 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-if
      v-show
      添加一个“else块”。
      v-else
      元素必须立即跟在
      v-if
      v-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-bind
    v-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)是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()
      中,不过有两个特例:
      data
      el
    • Vue.js规定:在定义组件的选项时,
      data
      el
      选项必须使用函数。

    使用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 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。

    阅读更多
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: