Vue

Mr.ZhaoAbout 5 min

1. Vue 基本使用

1. vue-cli 创建项目

## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建Vue项目,选择Vue版本
vue create xxx

2. 插值与指令

详见:模板语法open in new window

3. computed和watch

详见:计算属性与侦听属性open in new window

注意:

  • computed 是有缓存的,data 不变就不会重新计算
  • watch
    • 如何深度监听:设置deep:true
    • 引用类型无法拿到 oldVal

4. class 和 style

详见:绑定样式open in new window

5. 条件

详见:条件渲染open in new window

  • v-if 和 v-show 的区别,以及使用场景 —— 频繁切换用 v-show ,否则用 v-if(不展示的 dom 元素会直接移除)

6. 循环

详见:列表渲染open in new window

  • 遍历数组,遍历对象
  • key
  • v-for 和 v-if 不要一起用
    • v-for 会优先于 v-if 执行
    • 因此 v-if 会在每一个 v-for 中都计算一遍
    • v-if 和 v-for 拆开使用

7. 事件

详见:事件处理open in new window 【注意】vue 事件是被注册到当前 DOM 元素的

  • 传参
  • event 参数
  • 事件修饰符
  • 按键修饰符
  • 【注意】用 vue 绑定的事件,组建销毁时会自动被解绑。自己绑定的事件,需要自己销毁

事件修饰符:

<!-- 阻止单击事件继续冒泡 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

按键修饰符:

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

8. 表单

详见:表单open in new window

  • textarea 要用 v-model

修饰符:lazy number trim

2. Vue 组件使用

详见:生命周期open in new window

详见:组件化编程open in new window

3. Vue 高级特性

1. 自定义 v-model

详见:Vue自定义组件如何实现v-model数据双向绑定open in new window

为了保证数据完整性,Vue在自定义组件的props定义中,只允许父组件向子组件传递数据,子组件不能直接修改props中的数据,在实际项目中有很多需要子组件内部更新属性,并同步给父组件的情况,也就是v-model数据双向绑定,那自定义组件如何实现v-model数据双向绑定呢?

在 Vue 中,自定义组件可以通过 props 传递数据,然后通过 emit 触发事件向父级组件发送更新。这样就可以实现类似 v-model 的双向绑定效果。 具体步骤如下:

  1. 在自定义组件中定义一个 prop 用于接收值,例如:

    props: ['value'] 
    
  2. 在自定义组件中维护该值的内部状态,例如:

    data() {
      return {
        innerValue: this.value 
      }
    }
    
  3. 在自定义组件中定义一个 model 属性,例如:

    model: {
      prop: 'value',
      event: 'input'
    }
    
  4. 然后在内部状态发生变化时触发该事件,例如:

    this.$emit('input', this.innerValue) 
    
  5. 最后,在使用自定义组件的父级组件中,使用 v-model 双向绑定 prop 和 emit,例如:

    <my-component v-model="someValue"></my-component> 
    

这相当于:

<my-component 
  :value="someValue"
  @input="someValue = $event"
></my-component>

通过这 5 个步骤,我们就实现了自定义组件的 v-model 效果,以下是一个完整示例:

父组件:

<template>
  <my-component v-model="message"></my-component>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello' 
    }
  }
}
</script>

自定义组件:

<template>
  <input type="text" :value="innerValue" @input="onInput">
</template>

<script>
export default {
  props: ['value'],
  data() {
    return {
      innerValue: this.value 
    }
  },
  model: {
    prop: 'value',
    event: 'input'
  }
  methods: {
    onInput(e) {
      this.innerValue = e.target.value 
      this.$emit('input', this.innerValue)
    }
  }
}
</script>

2. $nextTick

详见:$nextTickopen in new window

3. slot

详见:插槽open in new window

作用域插槽

即子组件管理数据,父组件通过插槽的作用域来获取。

具名插槽

<!-- NamedSlot 组件 -->
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
<NamedSlot>
  <template v-slot:header> <!-- 缩写 <template #header> -->
    <h1>将插入 header slot 中</h1>
  </template>

  <p>将插入到 main slot 中,即未命名的 slot</p>

  <template v-slot:footer>
    <p>将插入到 footer slot 中</p>
  </template>
</NamedSlot>

4. 动态组件

关键代码如下,其中 TplDemoName 要有定义

<component v-bind:is="TplDemoName"></component>
import TplDemo from '../BaseUse/TplDemo'

export default {
    components: {
        TplDemo
    },
    data() {
        return {
            TplDemoName: 'TplDemo'
        }
    }
}

5. 异步组件

import()函数实现

6. keep-alive

缓存组件

使用<keep-alive></keep-alive>包裹

7. mixin

详见:混入open in new window

【注意】mixin 不是完美的解决方案,它的变量作用域不明确

vue3 的 composition API 也是想解决这个问题

4. Vuex

详见:Vuexopen in new window

5. VueRouter 使用

  • vue-router
  • 动态路由
  • to 和 push
  • hash 和 history
  • 懒加载(配合动态组件)

详见:VueRouteropen in new window