Vue.js 教程---菜鸟教程

文章目录

  • 教程
  • 安装
  • 起步
  • 模板语法
    • 插值
    • 指令
    • 用户输入
    • 过滤器
    • 缩写
  • 条件语句
  • 循环语句
  • 计算属性
  • 监听属性
  • 样式绑定
  • 事件处理器
  • 表单
  • 组件
  • 组件 - 自定义事件
  • 自定义指令
    • 钩子
  • 路由( vue-router )
  • 过渡 & 动画
    • 过渡
  • Ajax(axios)
    • 安装方法:
    • GET 方法
    • POST 方法
    • 执行多个并发请求
    • axios API
  • 响应接口
  • 实例
    • 导航菜单
    • 编辑文本
    • 订单列表
    • 搜索页面
    • 切换不同布局

教程

本教程主要介绍了 Vue2.x 版本的使用

第一个实例:

<body>
<div id="app">
  <p>{{ message }}p>
div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
script>
body>

Vue.js 教程---菜鸟教程_第1张图片

安装

  • 使用 CDN 方法

起步

每个 Vue 应用都需要通过实例化 Vue 来实现。

语法格式如下:

var vm = new Vue({
  // 选项
})

接下来让我们通过实例来看下 Vue 构造器中需要哪些内容:

<div id="vue_det">
    <h1>site : {{site}}</h1>
    <h1>url : {{url}}</h1>
    <h1>{{details()}}</h1>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: '#vue_det',
        data: {
            site: "菜鸟教程",
            url: "www.runoob.com",
            alexa: "10000"
        },
        methods: {
            details: function() {
                return  this.site + " - 学的不仅是技术,更是梦想!";
            }
        }
    })
</script>

Vue.js 教程---菜鸟教程_第2张图片
在 Vue 构造器中有一个el参数,它是 DOM 元素中的id。在上面实例中 id 为 vue_det,在 div 元素中:

这意味着我们接下来的改动全部在以上指定的 div 内,div 外部不受影响。

接下来我们看看如何定义数据对象。

data 用于定义属性,实例中有三个属性分别为:site、url、alexa。

methods 用于定义的函数,可以通过 return 来返回函数值。

{{ }} 用于输出对象属性和函数返回值。


当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,html 视图将也会产生相应的变化。

<div id="vue_det">
    <h1>site : {{site}}h1>
    <h1>url : {{url}}h1>
    <h1>Alexa : {{alexa}}h1>
div>
<script type="text/javascript">
// 我们的数据对象
var data = { site: "菜鸟教程", url: "www.runoob.com", alexa: 10000}
var vm = new Vue({
    el: '#vue_det',
    data: data
})
// 它们引用相同的对象!
document.write(vm.site === data.site) // true
document.write("
"
) // 设置属性也会影响到原始数据 vm.site = "Runoob" document.write(data.site + "
"
) // Runoob // ……反之亦然 data.alexa = 1234 document.write(vm.alexa) // 1234
script>

Vue.js 教程---菜鸟教程_第3张图片

模板语法

插值

  • 文本
    数据绑定最常见的形式就是使用{{...}}(双大括号)的文本插值:
<div id="app">
  <p>{{ message }}p>
div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
script>

在这里插入图片描述

  • HTML
    使用v-html指令用于输出html代码:
<div id="app">
    <div v-html="message">div>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: '

菜鸟教程

'
} })
script>

Vue.js 教程---菜鸟教程_第4张图片

  • 属性
    HTML属性中的值应使用v-bind指令。

以下实例判断use的值,如果为true使用class1类的样式,否则不使用该类:

<style>
.class1{
  background: #444;
  color: #eee;
}
style>
<body>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js">script>

<div id="app">
  <label for="r1">修改颜色label><input type="checkbox" v-model="use" id="r1">
  <br><br>
  <div v-bind:class="{'class1': use}">
    v-bind:class 指令
  div>
div>
    
<script>
new Vue({
    el: '#app',
  data:{
      use: false
  }
});
script>
body>

Vue.js 教程---菜鸟教程_第5张图片
Vue.js 教程---菜鸟教程_第6张图片

  • 表达式
<div id="app">
    {{5+5}}<br>
    {{ ok ? 'YES' : 'NO' }}<br>
    {{ message.split('').reverse().join('') }}
    <div v-bind:id="'list-' + id">菜鸟教程div>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    ok: true,
    message: 'RUNOOB',
    id : 1
  }
})
script>

Vue.js 教程---菜鸟教程_第7张图片

指令

指令是带有 v- 前缀的特殊属性。

指令用于在表达式的值改变时,将某些行为应用到 DOM 上。

如下例子:

<div id="app">
    <p v-if="seen">现在你看到我了p>
    <template v-if="ok">
      <h1>菜鸟教程h1>
      <p>学的不仅是技术,更是梦想!p>
      <p>哈哈哈,打字辛苦啊!!!p>
    template>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    seen: true,
    ok: true
  }
})
script>

这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
Vue.js 教程---菜鸟教程_第8张图片

  • 参数
    参数在指令后以冒号指明。例如,v-bind指令被用来响应地更新HTML属性:
<div id="app">
    <pre><a v-bind:href="url">菜鸟教程a>pre>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    url: 'http://www.runoob.com'
  }
})
script>

在这里插入图片描述

在这里href是参数,告知v-bind指令将该元素的href属性与表达式url的值绑定。

另一个例子是v-on指令,它用于监听 DOM 事件:

在这里参数是监听的事件名。

  • 修饰符
    修饰符是以半角句号.指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent修饰符告诉v-on指令对于触发的事件调用event.preventDefault()

用户输入

  • input输入框中我们可以使用v-model指令来实现双向数据绑定:
<div id="app">
    <p>{{ message }}p>
    <input v-model="message">
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  }
})
script>

Vue.js 教程---菜鸟教程_第9张图片
v-model指令用来在inputselecttextareacheckboxradio等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

按钮的事件我们可以使用v-on监听事件,并对用户的输入进行响应。

以下实例在用户点击按钮后对字符串进行反转操作:

<div id="app">
    <p>{{ message }}p>
    <button v-on:click="reverseMessage">反转字符串button>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
script>

Vue.js 教程---菜鸟教程_第10张图片
Vue.js 教程---菜鸟教程_第11张图片

过滤器

Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。

由"管道符"指示, 格式如下:


{{ message | capitalize }}


<div v-bind:id="rawId | formatId">div>

以下实例对输入的字符串第一个字母转为大写:

<div id="app">
  {{ message | capitalize }}
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'runoob'
  },
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
script>

在这里插入图片描述

缩写

Vue.js 为两个最为常用的指令提供了特别的缩写:


<a v-bind:href="url">a>

<a :href="url">a>

<a v-on:click="doSomething">a>

<a @click="doSomething">a>

条件语句

<div id="app">
    <div v-if="type === 'A'">
      A
    div>
    <div v-else-if="type === 'B'">
      B
    div>
    <div v-else-if="type === 'C'">
      C
    div>
    <div v-else>
      Not A/B/C
    div>
div>
    
<script>
new Vue({
  el: '#app',
  data: {
    type: 'C'
  }
})
script>

在这里插入图片描述

循环语句

v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。

v-for 可以绑定数据到数组来渲染一个列表:

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.name }}
    li>
  ol>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    sites: [
      { name: 'Runoob' },
      { name: 'Google' },
      { name: 'Taobao' }
    ]
  }
})
script>

Vue.js 教程---菜鸟教程_第12张图片


v-for 迭代对象
v-for 可以通过一个对象的属性来迭代数据:

<div id="app">
  <ul>
    <li v-for="(value, key, index) in object">
     {{ index }}. {{ key }} : {{ value }}
    li>
  ul>
div>

<script>
new Vue({
  el: '#app',
  data: {
    object: {
      name: '菜鸟教程',
      url: 'http://www.runoob.com',
      slogan: '学的不仅是技术,更是梦想!'
    }
  }
})
script>

Vue.js 教程---菜鸟教程_第13张图片

计算属性

计算属性关键词: computed。

计算属性在处理一些复杂逻辑时是很有用的。

可以看下以下反转字符串的例子:

<div id="app">
  <p>原始字符串: {{ message }}p>
  <p>计算后反转字符串: {{ reversedMessage }}p>
div>
 
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
script>

实例中声明了一个计算属性reversedMessage

提供的函数将用作属性vm.reversedMessagegetter

vm.reversedMessage依赖于vm.message,在vm.message发生改变时,vm.reversedMessage也会更新。


computed vs methods

我们可以使用methods来替代computed,效果上两个都是一样的,但是computed是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用methods,在重新渲染的时候,函数总会重新调用执行。

<div id="app">
  <p>原始字符串: {{ message }}p>
  <p>计算后反转字符串: {{ reversedMessage }}p>
  <p>使用方法后反转字符串: {{ reversedMessage2() }}p>
div>

<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  },
  methods: {
    reversedMessage2: function () {
      return this.message.split('').reverse().join('')
    }
  }
})
script>

Vue.js 教程---菜鸟教程_第14张图片
可以说使用computed性能会更好,但是如果你不希望缓存,你可以使用methods属性。

监听属性

本章节,我们将为大家介绍Vue.js监听属性watch,我们可以通过watch来响应数据的变化。

以下实例通过使用watch实现计数器:

<div id = "app">
    <p style = "font-size:25px;">计数器: {{ counter }}p>
    <button @click = "counter++" style = "font-size:25px;">点我button>
div>
<script type = "text/javascript">
var vm = new Vue({
    el: '#app',
    data: {
        counter: 1
    }
});
vm.$watch('counter', function(nval, oval) {
    alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
script>

Vue.js 教程---菜鸟教程_第15张图片
Vue.js 教程---菜鸟教程_第16张图片


以下实例进行千米与米之间的换算:

<div id = "computed_props">
    千米 : <input type = "text" v-model = "kilometers">
    米 : <input type = "text" v-model = "meters">
div>
<p id="info">p>
<script type = "text/javascript">
    var vm = new Vue({
    el: '#computed_props',
    data: {
        kilometers : 0,
        meters:0
    },
    methods: {
    },
    computed :{
    },
    watch : {
        kilometers:function(val) {
            this.kilometers = val;
            this.meters = this.kilometers * 1000
        },
        meters : function (val) {
            this.kilometers = val/ 1000;
            this.meters = val;
        }
    }
    });
    // $watch 是一个实例方法
    vm.$watch('kilometers', function (newValue, oldValue) {
    // 这个回调将在 vm.kilometers 改变后调用
    document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
script>

Vue.js 教程---菜鸟教程_第17张图片
以上代码中我们创建了两个输入框,data属性中,kilometersmeters初始值都为0watch对象创建了data对象的两个监控方法:kilometersmeters

当我们在输入框输入数据时,watch会实时监听数据变化并改变自身的值。

$watch实例方法删掉后,千米和米的数据依然会改变,只是少了最下面的那行字
在这里插入图片描述

样式绑定

classstyleHTML元素的属性,用于设置元素的样式,我们可以用v-bind来设置样式属性。


class属性绑定
我们可以为v-bind:class设置一个对象,从而动态的切换class:

实例中将isActive设置为true显示了一个绿色的div块,如果设置为false则不显示:
实例1:

<style>
.active {
	width: 100px;
	height: 100px;
	background: green;
}
style>
head>
<body>
<div id="app">
  <div v-bind:class="{ 'active': isActive }">div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    isActive: true
  }
})
script>

Vue.js 教程---菜鸟教程_第18张图片
以上实例div class为:

我们也可以在对象中传入更多属性用来动态切换多个class

实例2:

text-danger类背景颜色覆盖了active类的背景色:

<style>
.active {
	width: 100px;
	height: 100px;
	background: green;
}
.text-danger {
	background: red;
}
style>
head>
<body>
<div id="app">
  <div class="static"
     v-bind:class="{ 'active': isActive, 'text-danger': hasError }">
  div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
	hasError: true
  }
})
script>

Vue.js 教程---菜鸟教程_第19张图片
以上实例div class为:

我们也可以直接绑定数据里的一个对象:

实例3:

text-danger 类背景颜色覆盖了 active 类的背景色:

<div id="app">
  <div v-bind:class="classObject">div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    classObject: {
      active: true,
      'text-danger': true
    }
  }
})
script>

实例 3 与 实例 2 的渲染结果是一样的。

此外,我们也可以在这里绑定返回对象的计算属性。这是一个常用且强大的模式:

实例4:

new Vue({
  el: '#app',
  data: {
    isActive: true,
    error: {
      value: true,
      type: 'fatal'
    }
  },
  computed: {
    classObject: function () {
      return {
  base: true,
        active: this.isActive && !this.error.value,
        'text-danger': this.error.value && this.error.type === 'fatal',
      }
    }
  }
})

Vue.js 教程---菜鸟教程_第20张图片
我们可以把一个数组传给 v-bind:class ,实例如下:

实例 5

以上实例 div class 为:


Vue.js style(内联样式)

我们可以在v-bind:style直接设置样式:

<div id="app">
	<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    activeColor: 'green',
	fontSize: 30
  }
})
script>

以上实例 div style 为:

菜鸟教程

也可以直接绑定到一个样式对象,让模板更清晰:

<div id="app">
  <div v-bind:style="styleObject">菜鸟教程div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'green',
      fontSize: '30px'
    }
  }
})
script>

v-bind:style可以使用数组将多个样式对象应用到一个元素上:

<body>
<div id="app">
  <div v-bind:style="[baseStyles, overridingStyles]">菜鸟教程div>
div>

<script>
new Vue({
  el: '#app',
  data: {
    baseStyles: {
      color: 'green',
      fontSize: '30px'
    },
	overridingStyles: {
      'font-weight': 'bold'
    }
  }
})
script>
body>

事件处理器

事件监听可以使用v-on指令:

<div id="app">
  <button v-on:click="counter += 1">增加 1button>
  <p>这个按钮被点击了 {{ counter }} 次。p>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    counter: 0
  }
})
script>

Vue.js 教程---菜鸟教程_第21张图片
通常情况下,我们需要使用一个方法来调用JavaScript方法。

v-on可以接收一个定义的方法来调用。

<div id="app">
   
  <button v-on:click="greet">Greetbutton>
div>
 
<script>
var app = new Vue({
  el: '#app',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 对象中定义方法
  methods: {
    greet: function (event) {
      // `this` 在方法里指当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
          alert(event.target.tagName)
      }
    }
  }
})
// 也可以用 JavaScript 直接调用方法
app.greet() // -> 'Hello Vue.js!'
script>

用 JavaScript 直接调用方法
Vue.js 教程---菜鸟教程_第22张图片
用 v-on 调用方法,点击显示
Vue.js 教程---菜鸟教程_第23张图片
if(event){alert (event.target.tagName)}
Vue.js 教程---菜鸟教程_第24张图片

除了直接绑定到一个方法,也可以用内联JavaScript语句:

<div id="app">
  <button v-on:click="say('hi')">Say hibutton>
  <button v-on:click="say('what')">Say whatbutton>
div>
 
<script>
new Vue({
  el: '#app',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})
script>

Vue.js 教程---菜鸟教程_第25张图片


事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。

Vue.js 通过由点.表示的指令后缀来调用修饰符。


按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:


<input v-on:keyup.13="submit">

表单

你可以用 v-model 指令在表单控件元素上创建双向数据绑定。

v-model 会根据控件类型自动选取正确的方法来更新元素。

实例中演示了 input 和 textarea 元素中使用 v-model 实现双向数据绑定:

<div id="app">
  <p>input 元素:p>
  <input v-model="message" placeholder="编辑我……">
  <p>消息是: {{ message }}p>
    
  <p>textarea 元素:p>
  <p style="white-space: pre">{{ message2 }}p>
  <textarea v-model="message2" placeholder="多行文本输入……">textarea>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob',
    message2: '菜鸟教程\r\nhttp://www.runoob.com'
  }
})
script>

Vue.js 教程---菜鸟教程_第26张图片


复选框
复选框如果是一个为逻辑值,如果是多个则绑定到同一个数组:

以下实例中演示了复选框的双向数据绑定:

<div id="app">
  <p>单个复选框:p>
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}label>
    
  <p>多个复选框:p>
  <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
  <label for="runoob">Runooblabel>
  <input type="checkbox" id="google" value="Google" v-model="checkedNames">
  <label for="google">Googlelabel>
  <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
  <label for="taobao">taobaolabel>
  <br>
  <span>选择的值为: {{ checkedNames }}span>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    checked : false,
    checkedNames: []
  }
})
script>

Vue.js 教程---菜鸟教程_第27张图片


单选按钮

以下实例中演示了单选按钮的双向数据绑定:

<div id="app">
  <input type="radio" id="runoob" value="Runoob" v-model="picked">
  <label for="runoob">Runooblabel>
  <br>
  <input type="radio" id="google" value="Google" v-model="picked">
  <label for="google">Googlelabel>
  <br>
  <span>选中值为: {{ picked }}span>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    picked : 'Runoob'
  }
})
script>

Vue.js 教程---菜鸟教程_第28张图片


select 列表

以下实例中演示了下拉列表的双向数据绑定:

<div id="app">
  <select v-model="selected" name="fruit">
    <option value="">选择一个网站option>
    <option value="www.runoob.com">Runooboption>
    <option value="www.google.com">Googleoption>
  select>
 
  <div id="output">
      选择的网站是: {{selected}}
  div>
div>
 
<script>
new Vue({
  el: '#app',
  data: {
    selected: '' 
  }
})
script>

请添加图片描述

组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
Vue.js 教程---菜鸟教程_第29张图片
注册一个全局组件语法格式如下:

Vue.component(tagName, options)

tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:


全局组件

所有实例都能用全局组件。

注册一个简单的全局组件 runoob,并使用它:

<div id="app">
    <runoob>runoob>
div>
 
<script>
// 注册
Vue.component('runoob', {
  template: '

自定义组件!

'
}) // 创建根实例 new Vue({ el: '#app' })
script>

Vue.js 教程---菜鸟教程_第30张图片


局部组件

我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:

注册一个简单的局部组件 runoob,并使用它:

<div id="app">
    <runoob>runoob>
div>
 
<script>
var Child = {
  template: '

自定义组件!

'
} // 创建根实例 new Vue({ el: '#app', components: { // 将只在父模板可用 'runoob': Child } })
script>

Vue.js 教程---菜鸟教程_第31张图片


Prop

prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”:

<div id="app">
    <child message="hello!">child>
div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '{{ message }}'
})
// 创建根实例
new Vue({
  el: '#app'
})
script>

在这里插入图片描述


动态 Prop

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:

<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg">child>
    div>
div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '{{ message }}'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
script>

Vue.js 教程---菜鸟教程_第32张图片
以下实例中使用 v-bind 指令将 todo 传到每一个重复的组件中:

<div id="app">
    <ol>
    <todo-item v-for="item in sites" v-bind:todo="item">todo-item>
      ol>
div>
 
<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '
  • {{ todo.text }}
  • '
    }) new Vue({ el: '#app', data: { sites: [ { text: 'Runoob' }, { text: 'Google' }, { text: 'Taobao' } ] } })
    script>

    Vue.js 教程---菜鸟教程_第33张图片
    注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。


    Prop 验证

    组件可以为 props 指定验证要求。

    为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。

    组件 - 自定义事件

    父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

    我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

    • 使用 $on(eventName) 监听事件
    • 使用 $emit(eventName) 触发事件

    另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

    以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

    <div id="app">
        <div id="counter-event-example">
          <p>{{ total }}p>
          <button-counter v-on:increment="incrementTotal">button-counter>
          <button-counter v-on:increment="incrementTotal">button-counter>
        div>
    div>
     
    <script>
    Vue.component('button-counter', {
      template: '',
      data: function () {
        return {
          counter: 0
        }
      },
      methods: {
        incrementHandler: function () {
          this.counter += 1
          this.$emit('increment')
        }
      },
    })
    new Vue({
      el: '#counter-event-example',
      data: {
        total: 0
      },
      methods: {
        incrementTotal: function () {
          this.total += 1
        }
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第34张图片

    data 必须是一个函数

    上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数:

    data: function () {
      return {
        count: 0
      }
    }
    

    这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例:

    <div id="components-demo3" class="demo">
        <button-counter2>button-counter2>
        <button-counter2>button-counter2>
        <button-counter2>button-counter2>
    div>
     
    <script>
    var buttonCounter2Data = {
      count: 0
    }
    Vue.component('button-counter2', {
        data: function () {
            // data 选项是一个对象,会影响到其他实例
            return buttonCounter2Data
        },
        template: ''
    })
    new Vue({ el: '#components-demo3' })
    script>
    

    Vue.js 教程---菜鸟教程_第35张图片


    自定义组件的 v-model

    组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。

    等价于:

    
    

    以下实例自定义组件 runoob-input,父组件的 num 的初始值是 100,更改子组件的值能实时更新父组件的 num:

    <div id="app">
        <runoob-input v-model="num">runoob-input>
        <p>输入的数字为:{{num}}p>
    div>
    <script>
    Vue.component('runoob-input', {
        template: `
        

    `
    , props: ['value'], // 名为 value 的 prop }) new Vue({ el: '#app', data: { num: 100, } })
    script>

    Vue.js 教程---菜鸟教程_第36张图片
    由于 v-model 默认传的是 value,不是 checked,所以对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

    <div id="app">
        <base-checkbox v-model="lovingVue">base-checkbox> 
         <div v-show="lovingVue"> 
            如果选择框打勾我就会显示。 
        div>
    div> 
    <script>
    // 注册
    Vue.component('base-checkbox', {
     
      model: {
        prop: 'checked',
        event: 'change'  // onchange 事件
      },
      props: {
        checked: Boolean
      },
       
      template: `
        
      `
    })
    // 创建根实例
    new Vue({
      el: '#app',
      data: {
        lovingVue: true
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第37张图片

    自定义指令

    除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。

    下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点:

    <div id="app">
        <p>页面载入时,input 元素自动获取焦点:p>
        <input v-focus>
    div>
     
    <script>
    // 注册一个全局自定义指令 v-focus
    Vue.directive('focus', {
      // 当绑定元素插入到 DOM 中。
      inserted: function (el) {
        // 聚焦元素
        el.focus()
      }
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
    script>
    

    Vue.js 教程---菜鸟教程_第38张图片
    我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:

    <div id="app">
      <p>页面载入时,input 元素自动获取焦点:p>
      <input v-focus>
    div>
     
    <script>
    // 创建根实例
    new Vue({
      el: '#app',
      directives: {
        // 注册一个局部的自定义指令 v-focus
        focus: {
          // 指令的定义
          inserted: function (el) {
            // 聚焦元素
            el.focus()
          }
        }
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第39张图片

    钩子

    钩子函数

    指令定义函数提供了几个钩子函数(可选):

    • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

    • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

    • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

    • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

    • unbind: 只调用一次, 指令与元素解绑时调用。


    钩子函数的参数

    • el: 指令所绑定的元素,可以用来直接操作 DOM 。
    • binding: 一个对象,包含以下属性:
      • name: 指令名,不包括 v- 前缀。
      • value: 指令的绑定值, 例如: v-my-directive=“1 + 1”, value 的值是 2。
      • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      • expression: 绑定值的表达式或变量名。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”。
      • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。
      • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
    • vnode: Vue 编译生成的虚拟节点。
    • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    以下实例演示了这些参数的使用:

    <div id="app"  v-runoob:hello.a.b="message">
    div>
     
    <script>
    Vue.directive('runoob', {
      bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
          'name: '       + s(binding.name) + '
    '
    + 'value: ' + s(binding.value) + '
    '
    + 'expression: ' + s(binding.expression) + '
    '
    + 'argument: ' + s(binding.arg) + '
    '
    + 'modifiers: ' + s(binding.modifiers) + '
    '
    + 'vnode keys: ' + Object.keys(vnode).join(', ') } }) new Vue({ el: '#app', data: { message: '菜鸟教程!' } })
    script>

    Vue.js 教程---菜鸟教程_第40张图片
    有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:

    Vue.directive('runoob', function (el, binding) {
      // 设置指令的背景颜色
      el.style.backgroundColor = binding.value.color
    })
    

    指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:

    <div id="app">
        <div v-runoob="{ color: 'green', text: '菜鸟教程!' }">div>
    div>
     
    <script>
    Vue.directive('runoob', function (el, binding) {
        // 简写方式设置文本及背景颜色
        el.innerHTML = binding.value.text
        el.style.backgroundColor = binding.value.color
    })
    new Vue({
      el: '#app'
    })
    script>
    

    在这里插入图片描述

    路由( vue-router )

    Vue.js 路由允许我们通过不同的 URL 访问不同的内容。

    通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)。


    安装
    1、直接下载 / CDN
    https://unpkg.com/vue-router/dist/vue-router.js

    2、NPM
    推荐使用淘宝镜像:cnpm install vue-router


    简单实例

    Vue.js + vue-router 可以很简单的实现单页应用。

    是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。

    以下实例中我们将 vue-router 加进来,然后配置组件和路由映射,再告诉 vue-router 在哪里渲染它们。代码如下所示:

    <div id="app">
      <h1>Hello App!h1>
      <p>
        
        
        
        <router-link to="/foo">Go to Foorouter-link>
        <router-link to="/bar">Go to Barrouter-link>
      p>
      
      
      <router-view>router-view>
    div>
    
    <script>
    // 0. 如果使用模块化机制编程,導入Vue和VueRouter,要调用 Vue.use(VueRouter)
    
    // 1. 定义(路由)组件。
    // 可以从其他文件 import 进来
    const Foo = { template: '
    foo
    '
    } const Bar = { template: '
    bar
    '
    } // 2. 定义路由 // 每个路由应该映射一个组件。 其中"component" 可以是 // 通过 Vue.extend() 创建的组件构造器, // 或者,只是一个组件配置对象。 // 我们晚点再讨论嵌套路由。 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 创建 router 实例,然后传 `routes` 配置 // 你还可以传别的配置参数, 不过先这么简单着吧。 const router = new VueRouter({ routes // (缩写)相当于 routes: routes }) // 4. 创建和挂载根实例。 // 记得要通过 router 配置参数注入路由, // 从而让整个应用都有路由功能 const app = new Vue({ router }).$mount('#app') // 现在,应用已经启动了!
    script>

    Vue.js 教程---菜鸟教程_第41张图片
    Vue.js 教程---菜鸟教程_第42张图片


    相关属性

    to
    表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

    过渡 & 动画

    过渡

    Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。

    Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。

    语法格式

    
       

    我们可以通过以下实例来理解 Vue 的过渡是如何实现的:

    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js">script>
    <style>
    /* 可以设置不同的进入和离开动画 */
    /* 设置持续时间和动画函数 */
    .fade-enter-active, .fade-leave-active {
        transition: opacity 2s
    }
    .fade-enter, .fade-leave-to /* .fade-leave-active, 2.1.8 版本以下 */ {
        opacity: 0
    }
    style>
    head>
    <body>
    <div id = "databinding">
    <button v-on:click = "show = !show">点我button>
    <transition name = "fade">
        <p v-show = "show" v-bind:style = "styleobj">动画实例p>
    transition>
    div>
    <script type = "text/javascript">
    var vm = new Vue({
    el: '#databinding',
        data: {
            show:true,
            styleobj :{
                fontSize:'30px',
                color:'red'
            }
        },
        methods : {
        }
    });
    script>
    body>
    

    Ajax(axios)

    Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。

    Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。

    安装方法:

    使用 cdn:

    使用 npm:
    npm install axios

    GET 方法

    我们可以简单的读取 JSON 数据:

    <div id="app">
      {{ info }}
    div>
    <script type = "text/javascript">
    new Vue({
      el: '#app',
      data () {
        return {
          info: null
        }
      },
      mounted () {
        axios
          .get('https://www.runoob.com/try/ajax/json_demo.json')
          .then(response => (this.info = response))
          .catch(function (error) { // 请求失败处理
            console.log(error);
          });
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第43张图片

    使用 response.data 读取 JSON 数据:

    <div id="app">
      <h1>网站列表h1>
      <div
        v-for="site in info"
      >
        {{ site.name }}
      div>
    div>
    <script type = "text/javascript">
    new Vue({
      el: '#app',
      data () {
        return {
          info: null
        }
      },
      mounted () {
        axios
          .get('https://www.runoob.com/try/ajax/json_demo.json')
          .then(response => (this.info = response.data.sites))
          .catch(function (error) { // 请求失败处理
            console.log(error);
          });
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第44张图片
    GET 方法传递参数格式如下:

    // 直接在 URL 上添加参数 ID=12345
    axios.get('/user?ID=12345')
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
     
    // 也可以通过 params 设置参数:
    axios.get('/user', {
        params: {
          ID: 12345
        }
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    

    POST 方法

    <div id="app">
      {{ info }}
    div>
    <script type = "text/javascript">
    new Vue({
      el: '#app',
      data () {
        return {
          info: null
        }
      },
      mounted () {
        axios
          .post('/try/ajax/demo_axios_post.php')
          .then(response => (this.info = response))
          .catch(function (error) { // 请求失败处理
            console.log(error);
          });
      }
    })
    script>
    

    Vue.js 教程---菜鸟教程_第45张图片
    POST 方法传递参数格式如下:

    axios.post('/user', {
        firstName: 'Fred',        // 参数 firstName
        lastName: 'Flintstone'    // 参数 lastName
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    

    执行多个并发请求

    function getUserAccount() {
      return axios.get('/user/12345');
    }
    
    function getUserPermissions() {
      return axios.get('/user/12345/permissions');
    }
    axios.all([getUserAccount(), getUserPermissions()])
      .then(axios.spread(function (acct, perms) {
        // 两个请求现在都执行完成
      }));
    

    axios API

    可以通过向 axios 传递相关配置来创建请求。

    axios(config)
    // 发送 POST 请求
    axios({
      method: 'post',
      url: '/user/12345',
      data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
      }
    });
    //  GET 请求远程图片
    axios({
      method:'get',
      url:'https://static.runoob.com/images/runoob-logo.png',
      responseType:'stream'
    })
      .then(function(response) {
      response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
    });
    axios(url[, config])
    // 发送 GET 请求(默认的方法)
    axios('/user/12345');
    

    响应接口

    Vue 可以添加数据动态响应接口。

    例如以下实例,我们通过使用$watch属性来实现数据的监听,$watch必须添加在 Vue 实例之外才能实现正确的响应。

    实例中通过点击按钮计数器会加 1。setTimeout 设置 10 秒后计算器的值加上 20 。

    <div id = "app">
        <p style = "font-size:25px;">计数器: {{ counter }}p>
        <button @click = "counter++" style = "font-size:25px;">点我button>
    div>
    <script type = "text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            counter: 1
        }
    });
    vm.$watch('counter', function(nval, oval) {
        alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
    });
    setTimeout(
        function(){
            vm.counter += 20;
        },10000
    );
    script>
    

    10秒后,计数器的值+20
    Vue.js 教程---菜鸟教程_第46张图片
    点击一下,计数器的值+1
    Vue.js 教程---菜鸟教程_第47张图片
    如果将

    vm.$watch('counter', function(nval, oval) {
        alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
    });
    

    去掉,数值依然会变化,但每次变化时,不会弹出alert。

    实例

    本章节为大家介绍几个 Vue.js 实例,通过实例练习来巩固学到的知识点。

    导航菜单

    <div id="main">
     
        
        
     
        <nav v-bind:class="active" v-on:click.prevent>
     
            
     
            <a href="#" class="home" v-on:click="makeActive('home')">Homea>
            <a href="#" class="projects" v-on:click="makeActive('projects')">Projectsa>
            <a href="#" class="services" v-on:click="makeActive('services')">Servicesa>
            <a href="#" class="contact" v-on:click="makeActive('contact')">Contacta>
        nav>
     
         
     
        <p>您选择了 <b>{{active}} 菜单b>p>
    div>
     
    <script>
    // 创建一个新的 Vue 实例
    var demo = new Vue({
        // DOM 元素,挂载视图模型
        el: '#main',
     
        // 定义属性,并设置初始值
        data: {
            active: 'home'
        },
     
        // 点击菜单使用的函数
        methods: {
            makeActive: function(item){
                // 模型改变,视图会自动更新
                this.active = item;
            }
        }
    });
    script>
    

    Vue.js 教程---菜鸟教程_第48张图片
    Vue.js 教程---菜鸟教程_第49张图片

    编辑文本

    订单列表

    搜索页面

    切换不同布局

    你可能感兴趣的:(vue.js,javascript,前端)