MVVM模式
MVVM模式(Model-View-ViewModel),ViewModel是Vue.js的核心,它是一个Vue实例。Vue实例是作用于某一个HTML元素上的,这个元素可以是HTML的body元素,也可以是指定了id的某个元素。从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。
双向绑定:
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--这是我们的View-->
<div id="app">
<p>{{ message }}</p>
<input type="text" v-model="message">
</div>
</body>
<script src="../js/vue/vue.min.js"></script>
<script>
// 这是我们的Model
var exampleData = {
message: 'hello world!'
}
// 创建一个 Vue 实例或 "ViewModel"
// 它连接 View 与 Model
new Vue({
el: '#app',
data:exampleData
})
</script>
</html>
常用指令
Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
Vue.js提供了一些常用的内置指令:
- v-if指令
- v-show指令
- v-else指令
- v-for指令
- v-bind指令
- v-on指令
1、v-if是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法:v-if=”expression”
expression是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式。
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1>hello,vue</h1>
<h1 v-if="yes">yes</h1>
<h1 v-if="no">no</h1>
<h1 v-if="age >= 22">age: {{ age }}</h1>
<h1 v-if="name.indexOf('james') >= 0">name: {{ name }}</h1>
</div>
</body>
<script src="../js/vue/vue.min.js"></script>
<script>
new Vue({
el:'#app',
data:{
yes: true,
no: false,
age: 26,
name: 'curry'
}
})
</script>
</html>
v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。
2、v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1>hello,vue</h1>
<h1 v-show="yes">yes</h1>
<h1 v-show="no">no</h1>
<h1 v-show="age >= 22">age: {{ age }}</h1>
<h1 v-show="name.indexOf('james') >= 0">name: {{ name }}</h1>
</div>
</body>
<script src="../js/vue/vue.min.js"></script>
<script>
new Vue({
el:'#app',
data:{
yes: true,
no: false,
age: 26,
name: 'curry'
}
})
</script>
</html>
表达式为false的元素被设置了style=”display:none”样式。
3、v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。
<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>
<hr/>
<h1 v-show="name.indexOf('keep') >= 0">name: {{ name }}</h1>
<h1 v-else>sex: {{ sex }}</h1>
</div>
</body>
<script src="../js/vue/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data:{
age: 28,
name: 'keepfool',
sex: 'male'
}
})
</script>
</html>
4、v-for指令基于一个数组渲染一个列表,语法:v-for=”item in items”。
items是一个数组,item是当前被遍历的数组元素。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<th>name</th>
<th>age</th>
<th>sex</th>
</tr>
</thead>
<tbody>
<tr v-for="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.sex }}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
people:[{
name: 'James',
age: 33,
sex:'male'
},
{
name: 'curry',
age: 27,
sex: 'female'
},
{
name: 'jack',
age: 22,
sex: 'male'
}]
}
})
</script>
</html>
5、v-bind指令可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),
v-bind:argument=”expression”。v-bind指令作用于元素的class特性上。
6、v-on指令用于给监听DOM事件,它的用语法和v-bind是类似的,例如监听<a>
元素的点击事件:<a v-on:click="doSomething">
。
有两种形式调用方法:绑定一个方法(让事件指向方法的引用),或者使用内联语句。
Greet按钮将它的单击事件直接绑定到greet()方法,而Hi按钮则是调用say()方法。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p><input type="text" v-model="message"></p>
<p>
<button v-on:click="greet">Greet</button>
</p>
<p>
<button v-on:click="say('Hi')">Hi</button>
</p>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
message:'Hello,Vue.js!'
},
methods:{
greet: function(){
alert(this.message)
},
say:function(msg){
alert(msg);
}
}
})
</script>
</html>
7、Vue.js为最常用的两个指令v-bind和v-on提供了缩写方式。v-bind指令可以缩写为一个冒号,v-on指令可以缩写为@符号。
<a href="javascript:void(0)" :class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
<button @click="greet">Greet</button>
8、v-model指令来实现双向数据绑定。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
message: 'hello world!'
}
})
</script>
</html>
过滤器
Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化,由”管道符”指示。
过滤器可以串联:{{ message | filterA | filterB }}
过滤器是JavaScript函数,可以接受参数:{{ message | filterA('arg1',arg2) }}
,message是第一个参数,字符串’arg1”将传给过滤器作为第二个参数,arg2表达式的值将被求值然后传给过滤器作为第三个参数。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
{{ message | capitalize }}
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
message: 'james'
},
filters: {
capitalize : function(value){
if(!value){
return '';
}
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
})
</script>
</html>
Vue实例
每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例来启动的。
var vm = new Vue({
// 选项
})
每个 Vue 实例都会代理其 data 对象里所有的属性,除了 data 属性, Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
})
给一个比如 props 中,或者 data 中被观测的对象添加一个新的属性的时候,不能直接添加,必须使用 Vue.set 方法。
Vue.set 方法用来新增对象的属性。如果要增加属性的对象是响应式的,那该方法可以确保属性被创建后也是响应式的,同时触发视图更新。
计算属性
methods和computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>原始字符串:{{ message }}</p>
<p>计算后反转字符串:{{ reversedMessage }}</p>
<p>使用方法后反转字符串:{{ reversedMethodMessage() }}</p>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
message: 'hello world!'
},
computed: {
//计算属性的getter
reversedMessage: function(){
//this指向vm实例
return this.message.split('').reverse().join('');
}
},
methods:{
reversedMethodMessage: function(){
return this.message.split('').reverse().join('');
}
}
})
</script>
</html>
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{ site }}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'Google',
url:'http://www.google.com'
},
computed: {
site:{
// getter
get: function(){
return this.name + ' ' + this.url;
},
//setter
set: function(newValue){
var names = newValue.split(' ');
this.name = names[0];
this.url = names[names.length - 1];
}
}
}
})
//调用setter,vm.name和vm.url也会被对应更新
vm.site = '百度 http://www.baidu.com';
document.write('name:' + vm.name);
document.write('<br>');
document.write('url' + vm.url);
</script>
</html>
样式绑定
class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<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>
</body>
<script>
new Vue({
el:'#app',
data: {
isActive: true,
hasError: true
}
})
</script>
</html>
直接绑定对象:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div class="static"
v-bind:class="classObject">
</div>
</div>
</body>
<script>
new Vue({
el:'#app',
data: {
classObject: {
active: true,
'text-danger': true
}
}
})
</script>
</html>
数组语法:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:class="[activeClass, errorClass]"></div>
</div>
</body>
<script>
new Vue({
el:'#app',
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script>
</html>
三元表达式:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.text-danger {
width:100px;
height: 100px;
background: red;
}
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script>
</html>
v-bind:style设置样式:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<div v-bind:style="{ color: activeColor,fontSize: fontSize + 'px' }">hello world!</div>
</div>
<script>
new Vue({
el: '#app',
data: {
activeColor: 'red',
fontSize: 30
}
})
</script>
</html>
使用数组将多个样式应用到一个元素上:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<div v-bind:style="[baseStyles,overridingStyles]">hello world!</div>
</div>
<script>
new Vue({
el: '#app',
data: {
baseStyles:{
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight':'bold'
}
}
})
</script>
</html>
其他说明:
1:v-bind动态绑定指令,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值=”表达式”
2:v-bind用于绑定属性和数据 ,其缩写为” : ” 也就是v-bind:id === :id
3:v-model用在表单控件上的,用于实现双向数据绑定,所以如果你用在除了表单控件以外的标签是没有任何效果的。
事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue.js通过由点(.)表示的指令后缀来调用修饰符。
- .stop
- .prevent
- .capture
- .self
- .once
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!--只有事件在该元素本身(而不是子元素)触发回调-->
<div v-on:click.self="doThat">...</div>
<!--click事件只能点击一次,2.1.4版本新增-->
<a v-on:click.once="doThis"></a>
按键修饰符:
按键别名:
- .enter
- .tab
- .delete (捕获 “删除” 和 “退格” 键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta
<input @keyup.enter="submit">
表单
可以用 v-model 指令在表单控件元素上创建双向数据绑定。
输入框:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<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: 'hello world',
message2: '百度地址:www.baidu.com'
}
})
</script>
</html>
多选框:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>单个复选框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多个复选框:</p>
<input type="checkbox" id="baidu" value="baidu" v-model="checkedNames" >
<label for="baidu">baidu</label>
<input type="checkbox" id="ali" value="ali" v-model="checkedNames">
<label for="ali">ali</label>
<input type="checkbox" id="qq" value="qq" v-model="checkedNames">
<label for="qq">qq</label>
<br>
<span>选择的值为: {{ checkedNames }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
checked: false,
checkedNames: []
}
})
</script>
</html>
select列表
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<select name="fruit" v-model="selected">
<option value="">请选择</option>
<option value="baidu">baidu</option>
<option value="google">google</option>
</select>
<div id="output">
选择是:{{ selected }}
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
</html>
修饰符:
1、 .lazy
在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
2、.number
如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:
<input v-model.number="age" type="number">
这通常很有用,因为在 type=”number” 时 HTML 中输入的值也总是会返回字符串类型。
3、.trim
如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:
<input v-model.trim="msg">
组件
组件可以扩展 HTML 元素,封装可重用的代码。
注册全局组件语法格式:
Vue.component(tagName,options)
tagName为组件名,options为配置选项。注册后,使用以下方式来调用组件:
<tagName></tagName>
全局组件
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<hello></hello>
</div>
<script>
//注册组件
Vue.component('hello',{
template: '<h1>hello,vue!</h1>'
})
new Vue({
el: '#app',
})
</script>
</html>
局部组件
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<hello></hello>
</div>
<script>
//注册组件
var Child = {
template: '<h1>hello world,vue!</h1>'
}
new Vue({
el: '#app',
components: {
// <hello>只在父模板可用
'hello': Child
}
})
</script>
</html>
Prop
prop 是父组件用来传递数据的一个自定义属性。父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<child message="hello!"></child>
</div>
<script>
//注册组件
Vue.component('child',{
//声明props
props:['message'],
//也可以在vm实例中像“this.message”这样使用
template: '<span>{{ message }}</span>'
})
new Vue({
el: '#app'
})
</script>
</html>
动态prop
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<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: '<span>{{ message }}</span>'
})
new Vue({
el: '#app',
data:{
parentMsg: '父组件内容'
}
})
</script>
</html>
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
v-bind 指令将 todo 传到每一个重复的组件中:
```
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<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: '<li>{{ todo.text }}</li>'
})
new Vue({
el: '#app',
data:{
sites: [
{text: 'baidu'},
{text: 'ali'},
{text: 'qq'}
]
}
})
</script>
</html>
```
Prop验证,组件可以为 props 指定验证要求。
prop 是一个对象而不是字符串数组时,它包含验证要求:
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
自定义事件
父组件是使用 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: '<button v-on:click="incrementHandler">{{ counter }}</button>',
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>
如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:
<myComponent v-on:click.native="doSomething"></myComponent>
自定义指令
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<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>
</html>
注册局部指令,指令只能在这个实例中使用
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<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>
</html>
钩子
指令定义函数提供了几个钩子函数(可选):
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 编译生成的虚拟节点,查阅 VNode API 了解更多详情。
- oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app" v-aric:hello.a.b="message">
</div>
<script>
Vue.directive('aric', {
bind: function (el, binding, vnode) {
var s = JSON.stringify ;
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: 'hello vue!'
}
})
</script>
</html>
不需要其他钩子函数,可以简写函数。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<div v-aric="{ color: 'red', text: 'vue 案例'}"></div>
</div>
<script>
Vue.directive('aric', function(el,binding){
//简写方式设置文本及背景颜色
el.innerHTML = binding.value.text;
el.style.backgroundColor = binding.value.color;
})
new Vue({
el: '#app'
})
</script>
</html>
路由
Vue.js 路由允许我们通过不同的 URL 访问不同的内容。通过 Vue.js 可以实现多视图的单页Web应用)。
Vue.js 路由需要载入 vue-router 库.
安装
1、直接下载
https://unpkg.com/vue-router/dist/vue-router.js
NPM,淘宝镜像:
cnpm install vue-router
Vue.js + vue-router,将vue-router加进来,然后配置组件和路由映射,再告诉vue-router在哪里渲染它们。
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
</head>
<body>
<div id="app">
<h1>hello vue!</h1>
<p>
<!-- 使用router-link组件来导航 -->
<!-- 通过传入'to'属性指定链接 -->
<!-- <rounter-link>默认会被渲染成一个<a>标签 -->
<router-link to="/foo">go to foo</router-link>
<router-link to="/bar">go to bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染到这里 -->
<router-link></router-link>
</div>
<script>
// 1.定义(路由)组件
// 可以从其他文件 import进来
const foo = { template: '<div>foo</div>'};
const bar = { template: '<div>bar</div>'};
// 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>
</html>