Vue实例

1
2
3
4
5
6
7

var vm = new  Vue({
    el: "#app",
    data: {
        a: 100
    }
})

el: 对应的元素 data: 数据

Vue实例有很多方法如

  • $watch: 监控变量,可定义回调函数
1
2
3
vm.$watch('a', function(newVal, oldVal){
    
})

生命周期

6f2c97f045ba988851b02056c01c8d62.png

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路由导航

基本标签

  • router-link
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
6
// 带有路径的对象
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