1.创建Vue实例?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <script src="vue.js"></script> </head> <body> <div id = 'app'> <h5>site:{{site}}}</h5> <h5>url:{{url}}</h5> <h5>{{details()}}</h5> </div> <script> var app = new Vue({ el:'#app', data:{ site:'菜鸟教程', url:"www.runoob.com", alexa:'10000' }, methods:{ details:function(){ return this.site + '- dream,wake up !' } } }) </script> </body> </html>
每个Vue程序首先使用以下函数创建一个Vue的实例:
var vm = new Vue({details options})
尽管 与MVVM没有关联,但vue的设计模式受其启发,所以我们经常会用vm作为(ViewMode)的缩写,来引用我们的vue实例。
Vue中的数据与方法?
创建vue实例时,它会将data中找到的所有属性添加到vue的反应系统中,当这些属性的值发生变化时,视图将反应、更新,以匹配新值。
//我们的数据对象
var data = { a:1 }
//将对象添加到Vue实例
var vm = new Vue({
data:data
})
//获取实例上的属性
//返回原始数据中的
属性vm.a == data.a // => true
//在实例上设置属性
//也会影响原始数据
vm.a = 2
data.a // => 2
// ...反之亦然
data.a = 3
vm.a // => 3
当数据修改时,视图会重新呈现,
如果你知道你以后需要一个属性,但它开始是空的或不存在的,你需要设置一些初始值。例如:
data:{
newTodoText:'',
visitCount:0,
hideCompletedTodos:false,
todos:[],
error:null
}
模板语法:
插补:
(1)文本:最基本的数据绑定形式是使用“mustache”语法,双花括号的文本差值。
< span >消息:{{msg}} </ span >
mustache将替换msg相应数据对象上的属性值。每当数据对象上的msg的属性值发生变化时,它也会更新。
您还可以使用v-once指令执行不会更新数据更改的一次性插值,但请记住,这也会影响同一节点上的任何其他绑定:
< span v-once >这永远不会改变:{{msg}} </ span >
(2)原始HTML
双花括号将数据对象中的“<a href = 'http://www.baidu.com'>点我</a>”属性解释为纯文本,而不是HTML,要输入真实的HTML,需要使用指令“v-html”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <script src="vue.js"></script> </head> <body> <div id = 'app'> <h5 v-html = 'url'></h5> </div> <script> var app = new Vue({ el:'#app', data: { url: "<a href = 'http://www.cnblogs.com/zsdbk'>message</a>", } }) </script> </body> </html>
注:在网页上动态呈现HTML可能非常危险,因为它很容易导致xss漏洞,所以请对信任的内容进行插值操作。
(3)属性:
Mustaches不能再HTML中使用,但是可以用v-bind指令。
< button v-bind:disabled = “isButtonDisabled” >按钮</ button >
如果数据对象中isButtonDisabled的属性值是null,undefiend,false,那么disabled 属性不会再当前button标签中生效。
(4)使用JavaScript表达式;
vue.js 支持JavaScript中的所有数据绑定功能
例如:
{{ 号 + 1 }}
三元运算:
{{ 好?'是':‘不’}}
{{ message.split(''),reverse(''),join('') }}
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 --> {{ var a = 1 }} <!-- 流控制也不会生效,请使用三元表达式 --> {{ if (ok) { return message } }}
指令(directives):
是带有v-前缀的特殊特性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
<p v-if="seen">现在你看到我了</p>
如果‘seen’的值为真,则在视图中显示所插入的文本内容,否则则不显示此标签。
(1)参数:
v-bind指令可以接收一个参数,并且响应式的更新html特性。
<a v-bind:href="url">...</a>
在这里 href
是参数,告知 v-bind
指令将该元素的 href
特性与表达式 url
的值绑定。
v-on指令用于监听DOM事件。
<a v-on:click="doSomething">...</a>
在这里参数是监听的事件名。
(2)修饰符:
修饰符(modifiers)是以半角句号“.”指明的特殊后缀,用于指出一个指令应该以特殊的方式绑定。
例如,
.prevent
修饰符告诉 v-on
指令对于触发的事件调用 event.preventDefault()
:
<form v-on:submit.prevent="onSubmit">...</form>
用于禁止执行form表单的submit的默认事件。
缩写:
v-
前缀作为一种视觉提示,用来识别模板中 Vue 特定的特性。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v-
前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue.js 管理所有模板的单页面应用程序 (SPA - single page application) 时,v-
前缀也变得没那么重要了。因此,Vue.js 为 v-bind
和 v-on
这两个最常用的指令,提供了特定简写:
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>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
总结:对于任何复杂逻辑,你都应当使用计算属性。
例子:
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } }) 结果: Original message: "Hello" Computed reversed message: "olleH" 这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数:
关于vm:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
你可以打开浏览器的控制台,自行修改例子中的 vm。vm.reversedMessage
的值始终取决于 vm.message
的值。
你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生改变时,所有依赖 vm.reversedMessage
的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。
计算属性缓存VS方法:
我们可以在表达式中定义方法来达到同样的方法;
<p>Reversed message: "{{ reversedMessage() }}"</p> // 在组件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
两种方法的最终结果完全相同:
不同点是:计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值,这意味着 message 的值还没有发生改变,如果多次访问reverseMessage的值,计算属性会立即返回之前的结果,不必要再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:(因为自始至终Date没有改变)
computed: {
now: function () {
return Date.now()
}
}
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
计算属性 vs 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。细想一下这个例子:
<div id="demo">{{ fullName }}</div> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
相比之下,只有数据更新时才会触发更新,所以计算属性使用起来性能更高一点。
计算属性(setter):
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> <script src="vue.js"></script> </head> <body> <div id = 'app'> {{fullName}} </div> <script> var app = new Vue({ el: '#app', data: { firstname: 'Foo', lastname: 'Bar', }, computed: { // 计算属性的getter fullName:{ get: function(){ // 'this'指向 vm 实例 return this.firstname + ' ' + this.lastname }, // 计算属性的setter set:function(newvalues){ var names = newvalues.split(' ') this.firstname = names[0] this.lastname = names[names.length-1] } } } }) </script> </body> </html>
现在再运行 app.fullName = 'John Doe'
时,setter 会被调用,app.firstName
和 app.lastName
也会相应地被更新。
侦听器:
Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。