Vue实例
1
2
3
4
5
6
7
|
var vm = new Vue({
el: "#app",
data: {
a: 100
}
})
|
el: 对应的元素
data: 数据
Vue实例有很多方法如
1
2
3
|
vm.$watch('a', function(newVal, oldVal){
})
|
生命周期
Vue对象定义的时候可以以属性的方式定义生命周期钩子
1
2
3
4
5
6
|
var vm = new Vue({
created: function(){
console.log('created');
},
})
|
插值
- 文本插值使用
{{ msg }}
- html元素插值使用
v-html
, 如<p v-html="msg"></p>
- 特性使用v-bind动态绑定,如
<p v-bind:class="classAtrr">hi</p>
- js表达式
- 如算术运算
{{ number + 1}}
- 三元表达式
{{ ok ? 'Yes' : 'No' }}
- 函数运算
{{ msg.split(' '),reverse().join('') }}
指令
指令是带有v-
前缀的特殊特性
- v-text=“val”: 更新元素的textContent, <span v-text-“msg”> 等价于 {{msg}}
- v-if=‘boolean exp’, 根据表达式的值来有条件的渲染元素, 可以和v-else-if、v-else结合
- v-show=‘boolean exp’, 会渲染元素,但会根据表达式来切换CSS属性display
- v-for=‘iterators exp’, 基于Iterrable多次渲染元素
- v-on:event=“method”, 缩写为
@
- v-bind:arrOrProp=“xxx”, 绑定class/stypel/src等属性,缩写为
:
- v-model: 表单控件绑定
组件
组件指可复用的Vue实例
属性
- props: 自定义属性,可以利用v-bind来动态船体 prop
- template: 组件模板
- data: 必须是一个函数,以便每个实例都有一份独立的数据拷贝
- computed: data中计算性的属性放在这里,相比methods,computed属性会有缓存,只有依赖项改变时才会重新计算结果
- created: 实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
this
指向 vm 实例
- mounted: el 被新创建的 vm.$el 替换, 挂在成功
- render:
- watch: 数据变化时执行异步或开销较大的操作时
实例 property
$refs: 一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例, 仅可读
$router: 路由器,.push("/")访问根目录
$route: 当前路由,可以被watch来监听路由变化, 只读
$store: 全局单例状态树
Vuex状态管理
全局单例管理共享状态
store 数据对象,相当于vue.data
getters
通过属性访问,相当于计算属性, 会有缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
|
通过方法访问可以方便查询store数据,没有缓存
1
2
3
4
5
6
7
8
|
getters: {
// ...
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
|
Mutation
更改store的唯一方法,在mutations中声明回调函数,使用commit来触发
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
store.commit('increment')
|
提交除了使用commit 也可以使用mapMutations来将其生设为方法
mutation必须是同步函数
Actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
// 可以使用参数结构来简化代码
// actions: {
// increment ({ commit }) {
// commit('increment')
// }
}
})
|
action提交的是mutation而不是直接更改状态
store.dispatch('increment')
action可以包含任意异步操作
1
2
3
4
5
|
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
|
Mudules
使用modules将store分割成模块,每个模块拥有自己的state、mutation、acttion等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
|
默认情况模块内部的getter、actition和mutation等是注册在全局的,可以添加namespaced: true
使其成为带命名空间的模块
在带命名空间里可以使用rootState
访问全局内容
注册
- 全局注册
Vue.component(’name’, options)
- 局部注册
1
2
3
4
5
6
|
var ComponentA = {...}
new Vue ({
components: {
'component-a': ComponentA,
},
})
|
单文件组件
三大部分
1
2
3
4
5
6
7
8
|
<template>
</template>
<script>
</script>
<style scoped>
</style>
|
Vue-Ruter路由导航
基本标签
1
|
<router-link to="/about">Go to About</router-link>
|
用来想a标签一样创建链接,但可以不重新加载页面
- router-view
显示与url对应的组件,可以放到你想布局的任何地方
路由匹配
1
2
3
4
5
6
7
8
|
const User = {
template: '<div>User {{ $route.params.id }}</div>',
}
const routes = [
// 动态段以冒号开始
{ path: '/users/:id', component: User },
]
|
嵌套路由
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 User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// 当 /user/:id/profile 匹配成功
// UserProfile 将被渲染到 User 的 <router-view> 内部
path: 'profile',
component: UserProfile,
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 将被渲染到 User 的 <router-view> 内部
path: 'posts',
component: UserPosts,
},
],
},
]
|
编程式路由
导航到其他位置
使用<router-link to="...">
标签时,内部其实调用的是router.push
方法
1
2
3
4
5
|
// 带有路径的对象
router.push({ path: '/users/eduardo' })
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })
|
替换当前位置
router.relace 类似于router.push,当不会向history添加新纪录
1
2
3
|
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })
|
横跨历史
类似于window.history.go(n)
1
2
3
4
5
6
7
8
|
// 向前移动一条记录,与 router.forward() 相同
router.go(1)
// 返回一条记录,与router.back() 相同
router.go(-1)
// 前进 3 条记录
router.go(3)
|
命名视图
当想同级展示多个视图时,可使用命名视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<router-view class="view left-sidebar" name="LeftSidebar"></router-view>
<router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
components: {
default: Home,
// LeftSidebar: LeftSidebar 的缩写
LeftSidebar,
// 它们与 `<router-view>` 上的 `name` 属性匹配
RightSidebar,
},
},
],
})
|
reference