vue过留痕

简单的vue demo

引入vue.js

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date()
}
})

指令带有前缀v-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(html 属性用v-bind, 缩写:title)
v-bind:title="message"
v-bind:id
v-bind:class="{ active: isActive }"
v-bind: disabled
v-bind:is
v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }
v-for="todo in todos"
v-if="seen"
v-else
(缩写@click)
v-on:keyup.enter // enter是按键修饰符
v-on:click="doSomething('hi', $event)" // 访问原生 DOM 事件
v-model.trim="message" // input,表单输入和应用状态间的双向绑定
v-once // <span v-once> {{ msg }}</span>仅显示一次改变
v-html="rawHtml" data.rawHtml = '<p>hello</p>' // 纯html
b-bind:item = "item" // 父向子传数据

Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $

1
2
3
4
5
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data, vm.$el, vm.$watch

查看http://cn.vuejs.org/v2/api

组件

组件命名规则

建议(小写,并且包含一个短杠)my-component

new Vue是一个实例

Vue.extend 组件构造器 需要传入component进行注册

Vue.component直接注册组件内部已经自动构造了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')

1.你可以作用到Vue.component 这个全局注册方法里

1
2
3
4
5
var apple = Vue.extend({ // var apple = {} 选项对象(自动调用 Vue.extend)
....
})
Vue.component('apple',apple) // 全局注册

2.你可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件

1
2
3
4
5
6
new Vue({
el: '#app', // 仅在此#app下使用
components:{
apple: apple
}
})

3.Vue中简易注册组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- html -->
<ol>
<!-- 创建一个 todo-item 组件的实例 -->
<todo-item></todo-item>
</ol>
<!-- end html -->
<!-- script 全局 注册组件,传入一个选项对象(自动调用 Vue.extend) -->
Vue.component('todo-item', { // 同理全局组件
template: '<li>这是个待办项</li>'
})
<!-- script or 局部 -->
new Vue({
el: '#app', // 仅在此#app下使用
components: {
'todo-item': {
template: '<li>这是个待办项</li>'
}
}
})

路由

1.is动态绑定: 动态组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<component :is="view"></component>
var app = new Vue({
el: '#app',
data: {
view: 'home'
},
created: function() {
// 路由:根据 hash 值切换视图组件(popstate|hashchange)
$(window).on('hashchange', function() {
var view = window.location.hash.replace(/#\/?/, '');
// 路由配置
switch (view) {
case 'login':
self.view = view;
break;
default:
self.view = 'home';
}
}).trigger('hashchange');
}
})

来自: http://cn.vuejs.org/v2/guide/components.html#动态组件

2.把 vue-router 加进来,只需要配置组件和路由映射,然后告诉 vue-router 在哪里渲染它们

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
// 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')

来自: http://router.vuejs.org/zh-cn/essentials/getting-started.html

生命周期钩子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="box">
<input type="text" v-model="msg"><br/>
{{msg}}
</div>
new Vue({
el:'#box',
data:{
msg:'welcome'
},
created:function(){
console.log('实例已经创建,msg变量还未渲染到模板')
},
mounted:function(){
console.log('已经挂载到模板上:msg变量渲染到模板')
},
updated:function(){
console.log('实例更新啦')
},
destroyed:function(){
console.log('销毁啦')
}
});

技巧

等待DOM更新再操作

1
2
3
Vue.nextTick(function () {
// DOM 更新了
})

keep-alive // 把切换出去的组件保留在内存中

v-model

1
2
<input v-model="something"> // 等同于下面
<input v-bind:value="something" v-on:input="something = $event.target.value">

VUE方法属性合集

1
2
3
4
5
6
7
8
9
10
11
12
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {}, // 以来关系变化才变化,有缓存, getter, setter
created:function(){}, // mounted, updated, destroyed
methods: {}, //只要发生重新渲染 {{now()}}
watch: {},
filters: {}
}
})

循环for+if

v-if只能添加在一个元素上,遇到多个元素块(ul),可以把

1
2
3
4
5
6
7
<transition name="fade">
<template v-for="(item, index) in range" v-if="index === cindex">
<ul class="phone_list clearfix">
<li>xx</li>
</ul>
</template>
</transition>
=====  普通情况 =====
1
2
3
4
5
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>

循环里三个参数,value数据值,key键名,index索引,建议加key

1
2
3
4
5
6
7
8
object: {
firstName: 'wu',
lastName: 'xiao'
}
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</div>

组件

父子之间通信

父组件是使用 props 传递数据给子组件
子组件要把数据传递回去,自定义事件
父: $on(eventName) 监听事件,子: $emit(eventName) 触发事件

1
2
3
<table>
<tr is="my-row"></tr> // 注意子组件建议, 而不是<my-row>..</my-row>, 因为受HTML限制,table+tr,ul+li
</table>


实例data是对象, 组件data是函数 data: function() {returen { c: 1}}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<div id="box">
<input type="text" v-model="newItem" v-on:keyup.enter="pushNew" />
<ul>
<li is="my-com" v-for="(item,index) in allItem" v-bind:item="item" v-bind:key="item" v-on:remove="removeThis(index)"></li>
</ul>
</div>
var vm = new Vue({
el:'#box',
data:{
newItem: '',
allItem: []
},
components: {
'my-com': {
props: ['item'],
template: '<li>{{ item }} <button v-on:click="$emit(\'remove\')">x</button></li>'
}
},
methods: {
pushNew: function() {
this.allItem.push(this.newItem)
this.newItem = ''
},
removeThis: function(index) {
this.allItem.splice(index, 1)
}
}
});

使用 Slot 分发内容

父组件模版:

1
2
3
4
<my-component>
<p>这是一些初始内容</p>
<p slot="footer">这是更多的初始内容</p>
</my-component>

子组件模版:

1
2
3
4
5
6
7
<div>
<h2>我是子组件的标题</h2>
<slot name="footer"></slot> //这是更多的初始内容
<slot>
只有在没有要分发的内容时才会显示。 // slot 能显示父组件的内容,这是一些初始内容
</slot>
</div>

来自: http://cn.vuejs.org/v2/guide/components.html

对数组的操作

Vue 包含一组观察数组的变异方法

push()
pop()
shift()
unshift()
splice()
sort()
reverse()
1
2
3
4
5
6
vue不能检测以下变动数组
vm.items[indexOfItem] = newValue
改成example1.items.splice(indexOfItem, 1, newValue)
vm.items.length = newLength
改成example1.items.splice(newLength)

事件修饰符

1
2
3
4
5
.stop <a v-on:click.stop="doThis"></a> 阻止单击事件冒泡
.prevent
.capture
.self
.once

来自http://cn.vuejs.org/v2/guide/events.html

按键修饰符

1
2
3
4
5
6
7
8
9
.enter <input v-on:keyup.enter="submit"> 只有是enter键才促发
.tab
.delete (捕获 “删除” 和 “退格” 键)
.esc
.space
.up
.down
.left
.right

状态管理器

各组件间相互通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
},
increment ({ commit }) { // es5
commit('increment')
}
}
})
操作
// 事件派发: store.dispatch('increment')
// 获取数据
computed: {
count () {
return this.$store.getters.count
}
}

过渡效果

1
2
3
<transition name="fade">
<p v-if="show">hello</p>
</transition>

来自: http://cn.vuejs.org/v2/guide/transitions.html