Vue学习分享

介绍:Vue起初是一个构建数据驱动的web界面的库,通过简单的API提供高效的数据绑定和灵活的组件系统,但随着vue生态圈的发展,如vue-router,vue-resource等的推出,vue已经算得上是个轻量级的MVVM框架了,官方定义vue是一套用于构建用户界面的渐进式框架。相较于Angular和React框架,vue的的学习曲线更平稳,这点也是我选择Vue入门的原因。

如何安装?

  • 直接HTML引入 script
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  • vue cli方式
$ npm install vue

Vue的核心思想

vue.jpg
  • 数据驱动

DOM是数据的一种自然映射,手动操作DOM是一件非常繁索且容易出错的事情,而使用vue.js后,就省去了手动操作DOM的步骤,在Vue.js里我们只需要操作数据,vue会通过Directives指令去修改对应的DOM,从而实现数据驱动。

  • 组件化

组件化的目的是扩展HTML元素,封装可重用代码

通过上图,我们可以粗略理解为一个简单的vue应用大概先分两部分:Vue实例、 HTML

第一部分 : vue实例

每个 Vue 应用都是通过创建一个新的 Vue 实例开始,语法如下:

var vm = new Vue({
  // 选项
})

构造器的常用参数属性包含:eldatamethodscomputedwatch生命周期钩子等,具体应用如下:

  • el:提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标,在vue单文件情况下不需要该属性
#挂载到id为app的DOM节点上
el: '#app'
  • data: 用于定义数据属性,当 Vue 实例被创建时,它向 Vue 的响应式系统加入了 data 对象中所有的属性。当这些属性的值变化时,HTML 视图将也会产生相应的变化。
# 实例创建之后,可通过 vm.$data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a。
data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}
  • methods:用于定义的函数,通过 return 来返回函数值。
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
  • computed 用于计算属性,当模板中的逻辑复杂时,代码非常难以看懂理解,可考虑把逻辑写在computed中,我们用 methods 替代 computed,效果一样,但 computed 基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。可以说 computed 性能会更好,除非你不希望缓存。
computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vue 实例
      return this.message.split('').reverse().join('')
    }
  }
  • watch 监听属性来响应数据的变化,当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
  • vue实例还有一系列的生命周期钩子,给了用户在不同阶段添加自己的代码的机会。
    • beforeCreate 在实例初始化之后调用
    • created 在实例创建完成后被立即调用
    • beforemount 在挂载开始之前被调用
    • mounted 实例被挂载后调用
    • beforeupdate 数据更新时调用
    • updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
    • beforeDesgroy 实例销毁之前调用
    • destroyed 实例销毁后调用
new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vue 实例
    console.log('a is: ' + this.a)
  },
  beforeCreate: function () {
    console.log('beforeCreate')
  }
})

备注:

  • 不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a),因为箭头函数并没有 this
  • 当这些数据改变时,视图会进行重渲染。但只有当实例被创建时就已经存在于 data 中的属性才是响应式的;
  • Vue实例针对数据、DOM、资源、组合等都有非常多灵活的属性,具体可查看官方API

第二部分 : HTML

vue实例承载了数据和逻辑相关的内容,那么HTML就是处理我们view相关内容了,Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。

插值表达式

数据绑定最常见的形式就是使用“Mustache”语法 (双大括号)

# 基本形式 ,无论何时,绑定的数据对象上 value 属性发生了改变,插值处的内容都会更新
{{ value }}
# 只需渲染一次数据
{{ *value }}
#可放在HTML标签内
<li data-id='{{id}}'></li>
# 表达式
{{ number / 100 }}
{{ true ? 1 : 0 }}
{{ example.split(",") }}

# !!错误示例(语句并非表达式,条件控件语句也是不支持的)
{{var logo = 'DDEF'}}
{{if (true) return 'DDEF'}}

# 过滤器:
{{ date | formateDate }}
{{ example | toUpperCase}}
指令

指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令的职责是当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。包含v-textv-htmlv-showv-ifv-elsev-else-ifv-forv-onv-bindv-modelv-slotv-prev-cloakv-once,在实际开发中应用非常频繁,下面我们来详细聊聊它们的用法。
v-bind : 动态地绑定一个或多个特性,或一个组件 prop 到表达式。

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- 可用于绑定元素 attribute,响应地更新 HTML 属性:-->
<div v-bind:id="dynamicId"></div>
<div v-bind:id="'list-' + id"></div>
<a v-bind:href="url">8891汽车</a>

<!-- 也可以用于绑定样式:-->
<div v-bind:class="{ active: isActive }"></div>
<div v-bind:class="[ activeClass, errorClass ]"></div>
<div v-bind:class="[ errorClass ,isActive ? activeClass : '' ]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!--修饰符-->
<svg :view-box.camel="viewBox"></svg>
<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>
<!--.sync修饰符会扩展成一个更新父组件绑定值的 v-on 侦听器。-->
<text-document v-bind:title.sync="doc.title"></text-document>

v-show 根据表达式之真假值,切换元素的 display CSS 属性

<!--根据表达式的值来显示或隐藏HTML元素-->
<!--元素始终被编译,只是简单地基于CSS切换,相比v-if有更高的初始渲染消耗-->
<h1 v-show="ok">Hello!</h1>

v-if 条件判断,根据表达式的值在DOM中生成或移除一个元素

<!--v-if  条件语句-->
<p v-if="seen">现在你看到我了</p>
<!--v-else-->
<div v-if="Math.random() > 0.5"> Now you see me </div>
<div v-else> Now you don't </div>
<!--v-else-if-->
<div v-if="type === 'A'"> A </div>
<div v-else-if="type === 'B'"> B </div>
<div v-else-if="type === 'C'"> C </div>
<div v-else>  Not A/B/C </div>

<!-- v-if 是惰性的,在条件第一次变为真时才开始局部编译,否则什么都不做 . 相比v-show有更高的切换消耗 -->

v-for 循环语句 :

<!--遍历数组,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名-->
<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
<!-- 可选的第二参数,索引-->
<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>

<!--遍历对象-->
<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
<!--可选的第二参数,键名-->
<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>
<!--可选的第三参数,索引-->
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>
<!--为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需为每项提供一个唯一 key 属性-->
<div v-for="item in items" v-bind:key="item.id">
  {{ item.message }}
</div>
<!--v-for里还可以使用值范围-->
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>
#VUE实例部分
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ],
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

备注:当数组出现变动时,Vue是如何检测呢?Vue 将被侦听的数组的变异方法进行了封装,它们能触发实图更新。所以建议尽量避免直接设置数据绑定的数组元素,因为这些变化不会被vue.js检测到,这些被封装过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

相比之下,也有非变异 (non-mutating method) 方法,它们不会改变原始数组,而总是返回一个新数组。

  • filter()
  • concat()
  • slice()

v-on : 用于监听 DOM 事件,并在触发时运行一些 JavaScript 代码

<!-- `greet` 是在vue实例中定义的方法名 -->
<div id="example-2">
 <button v-on:click="greet">Greet</button>
</div>

<!--内联处理器的方法-->
<div id="example-3">
 <button v-on:click="say('hi')">Say hi</button>
 <button v-on:click="say('what')">Say what</button>
</div>


<!--事件修饰符-->
<!-- 阻止单击事件继续传播 -->
<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>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>


<!-- 按键修饰符 -->
<!-- 按键修饰符,只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<input v-on:keyup.13="submit">

Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

v-model : 用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

<!--指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。-->
<input v-model="message" >
<textarea v-model="message" placeholder="add multiple lines"></textarea>
<!--单复选框-->
<input type="checkbox" id="checkbox" v-model="checked">
<!--多复选框 ,绑定到数组 data: {checkedNames: []}-->
<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
</div>
<!--单选框,绑定到 data: {picked: ''}-->
<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
</div>
<!--选择框,绑定到 data: {selected: ''}-->
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
  </select>
</div>
<!--多选选择框,绑定到数组 data: {selected: []}-->
<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
  </select>
</div>

<!--v-model指令后,可添加多个参数(number、lazy、trim)-->
<input v-model.number="age" type="number">
<input v-model.lazy="msg" >
<input v-model.trim="msg">

v-slot: 插槽,主要用于内容分发,插槽内可以包含任何模板代码,包括 HTML、其它组件等

<navigation-link url="/profile">
  Your Profile
</navigation-link>

<!--然后你在 `<navigation-link>` 的模板中可能会写为-->
<a v-bind:href="url" class="nav-link">
  <!--当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。-->
  <slot></slot>
</a>

<!--插槽内可以包含任何模板代码,包括 HTML、其它组件-->
<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 (模板代码)-->
  <span class="fa fa-user"></span> 
  <!-- 添加一个图标的组件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

v-text: 用于更新元素的 textContent

<span v-text="msg"></span>
<!--等价 -->
<span>{{msg}}</span>

v-html : 用于更新元素的 innerHTML

<!--更新元素的 innerHTML,在网站上动态渲染任意 HTML 是非常危险的,容易导致XSS攻击。只在可信内容上使用 `v-html`,永不用在用户提交的内容上。-->
<div v-html="html"></div>

v-pre: 用于跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签

<!--跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。-->
<span v-pre>{{ this will not be compiled }}</span>

v-once : 只渲染元素和组件一次。

<span v-once>这个将不会改变: {{ msg }}</span>

指令会在写HTML时大量应用到,特别是表单处理等,建议多加练习。

组件

组件化的目的是扩展HTML元素,封装可重用代码;组件其实是可复用的 Vue 实例

基础用法 ,组件注册 - 全局注册:

// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  template: '<li>这是组件内容</li>',
})

var app = new Vue(...)
<ol>
  <!-- 创建一个 todo-item 组件的实例 -->
  <todo-item></todo-item>
</ol>

组件注册 - 局部注册:

var ComponentA = {
  template:'<div>局部注册组件的内容</div>'
}

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
  }
})
#局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:
var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

在模块系统中局部注册

#这样 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用了
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
  components: {
    ComponentA,
    ComponentC
  },
  // ...
}
组件-数据传递:

props:props 可以是数组或对象,用于接收来自父组件的数据。

  • 数组模式
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
  • 对象模式
//若想每个prop 都指定的值类型。可以用对象形式列出prop,属性的名称和值分别是prop 各自的名称和类型
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}
  • Prop 验证 ,我们可为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。
Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

类型检查 : type 可以是下列原生构造函数中的一个:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

给 prop 传入数据 - 示例:

<!--传入一个静态的值-->
<blog-post title="My journey with Vue"></blog-post>
<!--通过 v-bind 动态赋值-->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 传入数字,这是一个 JavaScript 表达式而不是一个字符串-->
<blog-post v-bind:likes="42"></blog-post>
<!-- 传入布尔值,包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>
<!--即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue-->
<blog-post v-bind:is-published="false"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>
<!-- 传入数组,即便数组是静态的,我们仍然需要 `v-bind` 来告诉 Vue-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>
<!-- 传入对象,即便对象是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<blog-post
  v-bind:author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
></blog-post>
<!--传入对象所有属性 post: {id: 1,title: 'kevin'}-->
<blog-post v-bind="post"></blog-post>
<!--等价于-->
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

组件中,data必需是函数,因为它是引用类型,如果继续使用对象,则会在组件复用时相互影响:

# 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
data: function () {
  return {
    count: 0
  }
}
组件通信
  • 父传子props

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

  • 子传父$emit,可以使用 $emit 触发父组件的自定义事件
// 父组件
Vue.component('parent', {
  template:`
    <div>
      <child :message="message" v-on:getChildData="getChildData"></child>
    </div>
  `,
  data() {
    return {
      message: 'hello'
    }
  },
  methods:{
    // 执行子组件触发的事件
    getChildData(val) {
      console.log(val);
    }
  }
});

// 子组件
Vue.component('child', {
  template:`
    <div>
      <input type="text" v-model="myMessage" @input="passData(myMessage)">
    </div>
  `,
  props:['message'], 
  data() {
    return {
      // 这里是必要的,因为你不能直接修改 props 的值
      myMessage: this.message
    }
  },
  methods:{
    passData(val) {
      // 数据状态变化时触发父组件中的事件
      this.$emit('getChildData', val);
    }
  }
});
    
var app=new Vue({
  el: '#app',
  template: `
    <div>
      <parent />
    </div>
  `
});

  • 非父子组件 : vuex,这部分暂时还没深入学习,以后再展开详解。

单文件组成

使用 Vue.componen 来定义全局组件,然后用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素,在复杂的项目中会以下明显缺点:

  • 全局定义 (Global definitions) : 强制要求每个 component 中的命名不得重复
  • 字符串模板 (String templates) : 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) : 当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤 (No build step) : 只能用 HTML 和 ES5 JavaScript,而不能使用预处理器,如Babel

针对以上缺点,vue提供了文件扩展名为 .vue 的 single-file components(单文件组件) 为以上所有问题提供了解决方法,并且可以用 webpack 等构建工具,好在vue提供了脚手架工具Vue CLI 官方地址

安装Vue CLI

npm install -g @vue/cli
# OR
yarn global add @vue/cli
# 检查其版本是否正确
vue --version

现在就可以通过Vue CLI创建工程,然后根据我们的需求配置并生成项目

vue create demo

# vue create 命令有一些可选项,具体可查看
vue create --help
# 也能通过 vue ui 命令以图形化界面创建和管理项目
vue ui

.vue文件结构如下:

<template>...</template>
<script>...</script>
<style>...</style>

现在我们获得:

  • 完整语法高亮
  • CommonJS 模块
  • 组件作用域的 CSS

至此,VUE的一些基本用法都已经有大概的了解,后面还有更多知识要学习,比如前面工程化vue第三方库等等。

vue生态之vue-router

Vue.js路由,允许我们通过不同的 URL 访问不同的内容,从而实现多视图的单页Web应用
CDN方式

https://unpkg.com/vue-router/dist/vue-router.js

NPM方式安装

cnpm install vue-router

vue-router应用示例:<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。
to 属性为目标地址, 即要显示的内容。

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
 
<div id="app">
  <p>
    <!-- <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>

JS部分

// 0. 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
 
// 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')

<router-link> 相关属性

to : 目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>

<!-- 使用 v-bind 的 JS 表达式 ; 不写 v-bind 也可以,就像绑定别的属性一样-->
<router-link v-bind:to="'home'">Home</router-link>
<router-link :to="'home'">Home</router-link>
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

replace :设置 replace 属性后,点击时会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。

<router-link :to="{ path: '/abc'}" replace></router-link>

append :设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

<router-link :to="{ path: 'relative/path'}" append></router-link>

tag : 有时候想要 <router-link> 渲染成某种标签,例如 <li>。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

active-class :链接激活时使用的 CSS 类名。可以通过以下代码来替代。
exact-active-class : 链接被精确匹配的时候应该激活的 class

<router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>

event : 声明可以用来触发导航的事件

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容