Vue实例
构造器
每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例 启动的:
var vm=new Vue({
//选项
}) //vm(ViewModel 的简称)是Vue的实例,Vue是vm的构造器
在实例化 Vue 时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。
var vm=new Vue({
el:"#app",
data:{
msg:"hallo vue.js"
}
})
所有的 Vue.js 组件其实都是被扩展的 Vue 实例。
属性与方法
每个 Vue 实例都会代理其 data 对象里所有的属性:
<div id="app">{{msg}}</div>
<script>
var shuju={
msg:"hallo vue.js",
};
var vm=new Vue({
el:"#app",
data:shuju,
});
console.log(shuju.msg);
console.log(vm.msg);//两次输出结果一样
注意只有这些被代理的属性是响应的,也就是说值的任何改变都是触发视图的重新渲染。如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
除了 data 属性, Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。例如:
<div id="app">
{{msg}}
<input v-model="age"/>
</div>
<script>
var shuju={
msg:"hallo vue.js",
title:"前端工程师",
age:21
};
var vm=new Vue({
el:"#app",
data:shuju,
});
vm.$data === shutu // -> true
vm.$el === document.getElementById('app') // -> true
vm.$watch('age', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
})
</script>
生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如,实例需要配置数据观测(data observer)、编译模板、挂载实例到 DOM ,然后在数据变化时更新 DOM 。在这个过程中,实例也会调用一些 生命周期钩子 ,这就给我们提供了执行自定义逻辑的机会。 针对vm实例,不同生命周期提供了不同的钩子函数。(created mounted updated destroyed)
<div id="app">
{{msg}}
<input v-model="age"/>
</div>
<script>
var shuju={
msg:"hallo vue.js",
title:"前端工程师",
age:21
};
var vm=new Vue({
el:"#app",
data:shuju,
created:function(){
console.log("created");
},
mounted:function(){
console.log("mounted");
},
updated:function(){
console.log("updated");
},
destroyed:function(){
console.log("destroyed!!");
}
});
</script>
模板语法
插值
纯文本
数据绑定最常见的形式就是使用 “Mustache” 语法(双大括号)的文本插值:
<div id="app">{{msg}}</div>
Mustache 标签将会被替代为对应数据对象上 msg 属性的值。无论何时,绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上所有的数据绑定:
<span v-once>{{ msg }}</span>//这个将不会改变
纯html
双大括号会将数据解释为纯文本,而非 HTML 。为了输出真正的 HTML ,你需要使用 v-html 指令:
<div v-html="rawHtml"></div>
特性
mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:title="msg2">nihao</div>
这同样适用于布尔类特性,如果求值结果是 falsy 的值,则该特性将会被删除:
<button v-bind:disabled="isButtonDisabled">Button</button>
插入表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
指令
指令(Directives)是带有 v- 前缀的特殊属性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
<p v-if="seen">现在你看到我了</p>
v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。
参数
“参数”,在指令名称之后以冒号表示
v-bind 指令可以用于响应式地更新 HTML 属性:
<a v-bind:href="url"></a>
v-on 指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">
修饰符
修饰符(Modifiers)是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
<a v-bind:href="url" v-on:click.prevent="a">百度</a>
过滤器
用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示:
<div id="app">
{{msg|format|daxie}}
<div v-bind:title="msg|format|daxie">dvjs</div>
</div>
<script>
var data={
msg:"hellow World!",
};
var vm=new Vue({
el:"#app",
data:data,
filters:{
format:function(value){
return value.split("").reverse().join("");
},
daxie:function(value){
return value.toUpperCase();
}
}
});
</script>
过滤器可以串联
<div id="app">
{{msg|format|daxie}}<br/>
{{msg|format|daxie}}
<div v-bind:title="msg|format|daxie">dvjs</div>
</div>
过滤器可以接收参数
<div id="app">
{{msg|format(11)|daxie}}<br/>
{{msg|format(22)|daxie}}
</div>
<script>
var data={
msg:"hellow World!",
};
var vm=new Vue({
el:"#app",
data:data,
filters:{
format:function(value,number){
return value.split("").reverse().join("")+number;
},
daxie:function(value){
return value.toUpperCase();
}
}
});
</script>
这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 取值后的值作为第三个参数。
缩写
v-bind缩写
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
v-on缩写
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
计算属性
计算属性
模板内的表达式是非常便利的,但是它们实际上只用于简单的运算。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
这就是对于任何复杂逻辑,你都应当使用计算属性的原因。
getter函数
<div id="app">
{{ReverseMsg}}
<input v-model="msg"/>
</div>
<script>
var data={
msg:"hellow World!",
};
var vm=new Vue({
el:"#app",
data:data,
computed:{
ReverseMsg:{
get:function(){//getter函数
return this.msg.split('').reverse().join('');
},
set:function(newValue){//setter函数
this.msg=newValue.split('').reverse().join('');
},
}
});
</script>
vm.ReverseMsg 的值始终取决于 vm.msg 的值。
计算属性的缓存 vs method方法
我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。相比之下,每当触发重新渲染时,method 调用方式将总是再次执行函数。
<div id="app">
{{ReverseMsg}}
{{ReverseMsg}}
{{ReverseMsg1}}
{{ReverseMsg1}}
</div>
<script>
var a=100;
var b=100;
var data={
msg:"hellow World!",
};
var vm=new Vue({
el:"#app",
data:data,
computed:{
ReverseMsg:{
get:function(){//getter函数
a++;
return a;
},
set:function(newValue){//setter函数
this.msg=newValue.split('').reverse().join('');
},
},
methods:{
ReverseMsg1:function(){
b++;
return b;
}
}
});
</script>
我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。
计算属性 vs Watched 属性
<div class="exp">
{{fullName}}
<input value="text" v-model="firstName">
<input value="text" v-model="lastName">
</div>
<script>
var exp=new Vue({
el:".exp",
data:{
firstName:"Pure",
lastName:"View",
fullName:"PureView"
},
watch:{
firstName:function(val){
this.fullName=val+this.lastName
},
lastName:function(val){
this.fullName=this.firstName+val1
}
}
})
上面代码是命令式的和重复的。将它与计算属性的版本进行比较:
var exp=new Vue({
el:".exp",
data:{
firstName:"Pure",
lastName:"View"
},
computed:{
fullName:function(){
return this.firstName+this.lastName
}
}
})
计算setter
<div class="exp">
{{fullName}}
<input value="text" v-model="firstName">
<input value="text" v-model="lastName">
</div>
<script>
var exp=new Vue({
el:".exp",
data:{
firstName:"Pure",
lastName:"View"
},
computed:{
fullName:{
get:function(){
return this.firstName+this.lastName
},
set:function(newValue){
var name=newValue.split("")
this.firstName=name[0]
this.lastName = name[name.length - 1]
}
}
}
})
</script>
在控制台修改 exp.fullName的值,那么 firstName 和 lastName 的值也会相应的更新
观察 watchers
当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。
<div id="app">
{{msg}}
<input v-model="msg" v-on:keydown="gaibian"/>
</div>
<script>
var data={
msg:""
};
var vm=new Vue({
el:"#app",
data:data,
computed:{
},
methods:{
gaibian:function(){
localStorage.setItem("msg",this.msg);
}
},
watch:{
},
filters:{
},
mounted:function(){
this.msg=localStorage.getItem("msg");
}
});
</script>
<div id="app">
{{msg}}
<input v-model="msg" />
</div>
<script>
var data={
msg:""
};
var vm=new Vue({
el:"#app",
data:data,
computed:{
},
methods:{
},
watch:{
msg:function(newValue){
localStorage.setItem("msg",newValue);
},
},
filters:{
},
mounted:function(){
this.msg=localStorage.getItem("msg");
}
});
</script>
在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。