Vue.js 是当下很火的一个JavaScript MVVM 库,以数据驱动和组件化的思想构建的。相比于 Angular.js ,Vue.js 提供了更加简洁、更易于理解的API,使得大家能够快速地上手并使用。
<div id="app">
<p>{{text}}</p>
</div>
var app = new Vue({
el:"#app" ,
data : {
text: "I love my dog"
}
});
此时,数据与 DOM 已经被绑定在一起,所有元素都是 响应式的
在条件与循环中,可以在 Vue 插入/更新/删除元素时自动应用 过渡效果
属性与方法
每个 Vue 实例都会代理其 data 对象里的所有属性
var data = { a: 1 }
var vm = new Vue({
data: data
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
注意:只有这些被代理的属性是响应的,如果在实例创建之后添加新的属性到实例中,它不会触发视图更新。
除了 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` 改变后调用
})
注意:不要在实例属性或回调函数中(如 vm.$watch(‘a’, newVal => this.myMethod())) 使用箭头函数,因为箭头函数绑定父上下文,所以 this ,不会像预想一样是 Vue 实例,而是 this.myMethod 未被定义。
数据渲染的方式:
- v-text
- v-html
- {{ }}
无论何时,绑定的数据对象属性发生了变化,插值处的内容都会更新
<div id="app">
<p>{{content}}</p>
<p v-text="content"></p>
<p v-html="content"></p>
</div>
var app = new Vue({
el:"#app" ,
data : {
content: "I love my dog"
}
});
三者的区别:
执行下列代码:
<div id="app">
<p>{{ message }}</p>
<p v-text="text"></p>
<p v-html="html"></p>
<div>
<div>
插值表达式:<input type="text" v-model="message"/>
</div>
<div>
v-text 方式:<input type="text" v-model="text"/>
</div>
<div>
v-html 方式:<input type="text" v-model="html"/>
</div>
</div>
</div>
var app = new Vue({
el:"#app",
data:{
message : "hello,word,<b>{{}}</b>通过双括号绑定!",
text : "通过<b>v-text</b>方式绑定,html标签在渲染的时候被源码输出了。",
html : "通过<b>v-html</b>方式绑定,html标签在渲染的时候被解析了。"
}
});
结果如下:
以上三个输入框,在输入的时候,都会同步到对应的渲染。
总之,以下三种情况根据不同的场景决定使用:
1. {{ }} ,值是什么,就原样输出什么。
2. v-text ,同 {{ }} 效果一样,但是 {{ }} 在页面没加载完时,双大括号会显示出来 。建议用v-text。
3. v-html ,会把值中的标签解析,输出到页面
在站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击, 请只对可信内容使用 HTML 插值,绝对不要对用户提供的内容插值
v-once
执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这==会影响到该节点上所有的数据绑定。==
使用 JavaScript 表达式
所有的数据绑定,都可以使用 Javascript 表达式
{{number + 1}}
{{ ok ? 'yes':'no'}}
<div v-bind:id="'list-'+ id"></div>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式
<!--这是语句,不是表达式-->
{{ var a = 1}}
<!--流控制也不会生效,请使用三元表达式-->
{{ if (ok) {return message} }}
只能访问全局变量的一个白名单,如 Math 和 Date ,不应该在模板表达式中试图访问用户定义的全局变量
指令
是带有 v- 前缀的特殊属性。指令属性的值预期是 单一 JavaScript 表达式(除了 v-for)
参数
一些指令能接受一个“参数”,在指令后以 冒号 指明,例如
<a v-bind:href="url"></a>
在这个 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。
修饰符
以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如 ,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault();
控制模块隐藏
- v-if
- v-show
<p v-if="isShow"></p>
<p v-show="isShow"></p>
<script>
new Vue({
data:{
isShow:true
}
})
</script>
两者区别:
v-if
作用:判断是否加载固定的内容,如果为真,则加载;为假,则不加载。
用处:用于权限管理,页面条件加载。
语法:v-if = “判断表达式”
特点:控制元素插进来或删除,而不是隐藏。
v-show:
语法:v-show = “判断表达式”
特点:元素一直都在,但当 v-show 为 false 时,元素 display:none 只是隐藏了而已。
v-if 有更高的切换消耗,而 v-show 有更多的初始化渲染消耗。
因此:如果需要频繁的切换而对安全性无要求,则用 v-show 。如果在运行时,条件不可能改变,则使用 v-if 比较合适。
事件绑定:v-on
<button v-on:click="doThis"></button>
<button @click="doThis"></button> <!--简写-->
<script>
new Vue({
methods:{
doThis:function(){
}
}
});
</script>
渲染循环列表:v-for
<ul>
<li v-for:"item in items">
<p v-text="item.label"></p>
</li>
</ul>
<script>
new Vue({
data:{
item:[
{
label:'apple'
},
{
label:'pear'
}
]
}
});
</script>
可以用 of 替代 in 作为分隔符
若需要循环的是多个元素块,可在元素块外层用 包裹着。
由于 JavaScript 的限制,Vue 不能检测一下变动的数组
1. 当利用索引直接设置一个值时,例如:vm.items[indexOfItem] = newValue
2. 当修改数组的长度时,例如:vm.items.length = newLength
第一个问题的解决方案:
1. Vue.set(example1.items,indexOfItem,newValue)
2. example1.items.splice(indexOfItem,1,newValue)
第二个问题的解决方案:
example1.items.splice(newLength)
属性绑定:v-bind
属性的绑定,不能用 {{}} ,要用 v-bind
<img v-bind:src="imageSrc">
<div :class="{ red:isRed }"></div>
<div :class="[ classA,classB ]"></div>
<div :class="[ classA , { classB: isB, classC: isC }]"></div>
如 class 的绑定,也可以直接绑定数据里的一个对象
<div v-bind:class="classObject"></div>
data:{
classObject:{
active:true,
'text-danger':false
}
}
也可以绑定返回对象的计算属性。
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
new 一个 Vue 对象的时候可以设置,其中最重要的包括三个,data、methods、watch
。其中 data 代表 vue 对象的数据,methods 代表 vue 对象的方法,watch 设置了对象监听的方法。
Vue 对象里的设置通过 html 指令进行关联。
对布尔值的属性也有效–如果条件被求值为 false 的话,该属性会被移除:
<button v-bind:disabled="someDynamicCondition">Button</button>
绑定内联样式
v-bind:style
css 属性名可以是驼峰式或短横分隔命名
<div v-bind:style="{ color:activeColor,fontSize:fontSize + 'px'}"></div>
data: {
activeColor: 'red',
fontSize: 30
}
直接绑定到一个样式对象通常更好,让模板更清晰。
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
过滤器
可被用作一些常用的 文本格式化。过滤器可以用在两个地方 :mustache 插值({{}})和 v-bind 表达式。 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示:
<!--in mustaches-->
{{ message | capitalize}}
<!--in v-bind-->
<div v-bind:id="rawId | formatId"></div>
Vuejs 组件之间的调用:components
Vuejs 组件之间的通信: props
new Vue({
data:{
username:'xxx'
},
props:['msg'],
methods:{
doThis:function(){
console.log(this.msg)
}
}
});
<header msg='something interesting'></header>
<footer><footer>
例子:
App.vue 为父组件, componentA.vue为子组件
//App.vue
<template>
<div id="app">
<p>child tells me {{childwords}}</p>
<component-a msgfromfather="I'm your father" v-on:child-tell-me="listen"></component-a>
</div>
</template>
<script>
import ComponentA from './components/componentA'
export default {
name: 'app',
data(){
return {
childwords:''
}
},
components:{
ComponentA
},
methods:{
listen(msg){
console.log(msg);
this.childwords = msg;
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
//componentA.vue
<template>
<div class="hello">
<h1>{{message}}</h1>
<p>{{msgfromfather}}</p>
<button v-on:click="ClickMe">Click</button>
<button v-on:click="tellfather">tellfather</button>
</div>
</template>
<script>
export default {
data(){
return {
message:'message from ComponentA'
}
},
props:['msgfromfather'],
methods:{
ClickMe(){
console.log(this.msgfromfather);
},
tellfather(){
this.$emit('child-tell-me',this.message);
}
}
}
</script>
<style>
</style>
key
具有唯一值。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为 for 中的每项提供一个唯一 key 属性。
建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。
因为它是 Vue 识别节点的一个通用机制, key 并不特别与 v-for 关联。
created 这个钩子在实例被创建之后被调用:
也有一些其它的钩子,在实例生命周期的不同阶段调用,如 mounted、 updated 、destroyed 。钩子的 this 指向调用它的 Vue 实例。