vue起步
- vue应用语法格式:
var vm = new Vue({
//选项
})
- vue示例:
<div id="div_test">
<h1>hello : {{first}}</h1>//veu使用{{valuename}}来绑定数据和函数
<h1>world : {{second}}</h1>
<h1>{{details()}}</h1>
</div>
var vm = new Vue({
el: '#div_test',//元素选择器,可以是#class,.id,元素名等等
data: {//定义的属性,属性按照键值对形式定义
first: "hello",
second: "world",
third: "this my first vue!"
},
methods: {//定义的函数
details: function(){
return this.third;
}
}
})
var data = vm.$data;//使用$来调用vue示例的属性和方法
- 数据驱动:当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,html 视图将也会产生相应的变化。
vue模板语法
- Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。
Vue.js 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。
结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。 - 在html里面插值:
- 文本:{{data属性名称}}
- html:v-html = “属性名称”
- html标签属性值:v-bind:标签属性 = “data属性名称”
- 表达式:{{表达式值}},如{{ 5 + 5 }}
- 模板指令:带有 v- 前缀的特殊属性,用于在表达式的值改变时,将某些行为应用到 DOM 上。常用的有以下几个:
- v-show:根据条件来决定是否展示元素
- v-bind:绑定属性值,可以简写为“:”
- v-on:绑定事件,可以简写为“@”,用法:v-on:click = “事件处理”
- v-model:双向数据绑定,用于input、select、textarea、checkbox、radio 等表单控件元素,用法:v-model = “属性名称”
- 过滤器:允许自定义过滤器,被用作一些常见的文本格式化。
- 用法:{{ 被过滤文本 : 过滤规则}}
- 可以多层过滤器嵌套:{{ message : filterA : filterB}}
- 过滤器函数可以接受参数:{{ message : filter(arg1, arg2) }},message是第一个参数
条件与循环
- 条件:
- v-if:表示是否展示所绑定的标签,用法:v-if = “表达式或者属性名称”
- 假如不想在渲染的元素中出现,可以使用<template>来作为载体
- 使用属性 key 来控制可复用的标签
- v-else:if 的 else 块
- v-else-if:if 的 else-if 块,可多次循环使用
- v-show 和 v-if 的区别:
- v-show 无论判断是否为真,都会渲染所在的标签,而v-if只会在判断条件为真的时候才会渲染标签;
- 类似于 display: none 和 visibility: hidden 的区别
- v-if 有更高的切换消耗,v-show 有更高的初始渲染消耗
- 在判断条件发生变化时,比如由真变假,v-show 会修改 display: none 来达到效果,而 v-if 会直接注释掉节点
<div id="app">
<p v-if="check">1</p>
<p v-else>2</p>
<button v-on:click="check = !check">change</button>
</div>
<script>
new Vue({
el: "#app",
data: {
check: false
},
})
</script>
- 循环:
- v-for:
- v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名
- v-for 可以通过一个对象的属性来迭代数据:
- 当提供一个参数时返回值
- 两个参数时返回键、值
- 三个参数时返回索引、值、键
- 返回的值顺序和参数的顺序是相反的
- v-for 可以迭代数组和整数
- v-for:
<div id="app">
<ul>
<li v-for="(number, index) in numbers">
{{ number }}
{{ index }}
</li>
</ul>
</div>
<script>
new Vue({
el: "#app",
data: {
numbers: [1, 2, 3]
},
})
</script>
- 当循环的值都用相同的标签来渲染的时候,比如说:
<div id="app">
<div v-for="(number, index) in numbers">
<p>{{ number }}</p>
<p>{{ index }}</p>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
numbers: [1, 2, 3]
},
})
</script>
可以使用 <temple> 标签来优化,效果不变:
<div id="app">
<template v-for="(number, index) in numbers">
<p>{{ number }}</p>
<p>{{ index }}</p>
</template>
</div>
computed属性
- 关键字:computed
- 基本使用方法:
<div id = "div_test">
<p>{{s}}</p>
<p>{{reverseMessage}}</p>
</div>
var vm = new Vue({
el: "#div_test",
data: {
s: "abcd"
},
computed: {//因为是属性,函数插入的时候不用带(),而methods需要。绑定属性的时候需要带()
reverseMessage: function(){
return this.s.split("").reverse().join("");
}
}
})
- computed默认只带了 get 方法,可以自己手动添加 set 方法:
var vm = new Vue({
el: "#someid",
data: {
message: "someMessage"
},
computed: {
someFunction: {
get: function(){//函数插入默认会调用的方法
return this.message;
},
set: function(value){
this.message = value;
}
}
}
});
vm.someFunction = "otherMessage";//使用set
- 和methods的区别:
- methods是不会缓存的,每次重新渲染页面(data中的数据发生变化)的时候,都会重新调用执行(将 methods 里面的方法全部执行一遍);computed第一次加载完之后会对函数进行缓存,只有相关依赖发生变化时,才会重新取值(只会刷新调用的方法)
- 两者的效果是一样的,但是methods还可以传参数
- 可以说computed性能更好,但是假如不想要缓存,可以用methods代替
监听属性
- 关键字:watch,通过 watch 来响应事件变化
- 基本使用方法:
<div id="div_test">
<p>{{count}}</p>
<input type="button" @click="count++" value="click me">
</div>
第一种:
var vm = new Vue({
el: "#div_test",
data: {
count: 1
},
watch: {
count: function(val){//属性监听会在属性变化后立刻执行,然后页面中的{{count}}才会变化,变量val是变化后的属性值
console.log("count chang to %d", val)
}
//count: '方法名'
//count: {//选项对象
// handler: function(){ ... },
// immediate: true,//是否初始化时立刻执行
// deep: true//是否深入监听每一个元素
//}
}
})
还可以这样使用:
var vm = new Vue({
el: "#div_test",
data: {
count: 1
}
});
vm.$watch("count", function(oldv, newv){//变量oldv、newv分别是变化前的属性值和变化的属性值
console.log("the count from %d change to %d", oldv, newv);
});
- watch函数可以接受一个或者两个参数:
- 一个参数:变化之后的属性值
- 两个参数:变化之前的参数值,变化之后的参数值
样式绑定
- 使用 v-bind 指令绑定属性,绑定类:
<style>
.dmeo{
height: 100px;
width: 100px;
background: blue;
}
</style>
<div id="div_test" v-bind:class="{'demo': active}">当demo为true时将样式demo绑定到div,当然可以传入多个class</div>
var vm = new Vue({
el: "div_test",
data: {
active: true
}
})
- 绑定单个属性:
<div id="div_test" v-bind:style="divStyle">
样式也可以写为v-bind: style="{fontSize: data属性+'px'}"的形式,也可以传入数组[style1, style2]来绑定多个样式
</div>
var vm = new Vue({
el: "div_test",
data: {
divStyle: {
fontSize: 100 + "px"
}
}
})
- “v-bind:style…”冒号后面千万不能打空格,比如“v-bind: style=’…’ ”这样会导致浏览器无法渲染对应标签
- 具体实例
事件处理器
- 使用 v-on 指令
<div id="app">
<p v-bind:class="{ blue:check, 'red':!check}" v-on:click="check=!check">132</p>
</div>
<script>
new Vue({
el: "#app",
data: {
check: true
}
})
</script>
- 事件修饰符:
- .stop:js中的event.stopPropagation()的缩写,用来阻止事件冒泡
- .prevent:js中的event.preventDefault()的缩写,用来阻止事件默认行为
- .capture:在事件捕获阶段监听事件
- .self:只监听发生在标签本身的事件,不监听冒泡的子标签的事件
- .once:每次页面重载后只会执行一次
- 按键修饰符:按下相应按键便会触发事件,可以使用 keyCode 或者别名:
- .enter、.tab、.delete、.esc、.space、.up、.down、.left、.right、.ctrl、.alt、.shift、.meta
- computed 对象内的方法如果在初始化时绑定到元素上的事件会先执行一次这个方法 ,而 methods 内的方法则不会
- 可以使用 $event 访问原生事件对象
表单和双向数据绑定
- 可以用 v-model 指令在表单控件元素上创建双向数据绑定
<div id="app">
<input type="text" v-mode="name">
{{ name }}
</div>
<script>
new Vue({
el: "#app",
data: {
name: ""
}
})
</script>
- 修饰符:
- .lazy:在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步
- .number:将输入的值自动转为数字,如果NaN则返回原值
- .trim:自动过滤用户输入的首尾空格
- 在非表单控件元素上可以使用 .$refs 修饰符来获取元素值:
<div id="app">
<input type="text" ref="test" v-on:keyup="logName">
{{ name }}
</div>
<script>
new Vue({
el: "#app",
data: {
name: ""
},
methods: {
logName: function (event) {
this.name = this.$refs.test.value;
}
}
})
</script>
组件
- 组件可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。
- 组件的 data 选项必须是一个函数(防止组件复用的使用影响之前已经创建好的组件):
Vue.component("my-component", { data: function(){ return { key: value } }, template: "<p>that is a component!<p>" })
- 命名风格:推荐使用w3c标准的自定义组件命名格式:字母全部小写且至少包含一个连接符
- 注册组件:Vue.component(tagName, options)
- 调用组件:<tagName></tagName>
- 创建全局组件:
<div id="div_test"> <my-demo></my-demo> </div>
var comp = { template: "<p>hello world!</p>"//template模型只能有一个根标签 }; //在全局环境注册组件 Vue.component("my-demo", comp); //新建实例使用组件 new Vue({ el: "#div_test" })
- 创建局部组件:
var comp = { template: "<p>hello world!</p>" }; //单个实例下注册的组件 new Vue({ el: "#div_test", components: { "my-demo": comp } })
- template 属性:除了上面的一种,还有另外两种用法:
var vm = new Vue({ el: "#div_test", compoents: {my-zuJian1, my-zuJian2}, template: "</my-zuJian1>";//表示要选择的组件为my-zuJian1 })
<script type="x-template" id="templateDemo"> <p>模板</p> </script> <script> var vm = new Vue({ el: "#div_test", template: "#templateDemo";//表示要选择的组件为id为templateDemo的模板(template中文翻译是模板) }) </script>
- 在全局环境下注册组件用的是 Vue.component ,注册局部组件的使用的 components 属性
- Prop:父组件用来传递数据的一个自定义属性,是你可以在组件上注册的一些自定义特性。
- 自定义事件:父级组件可以通过 prop 来向子组件传递数据,子级组件向父组件传递数据则需要自定义事件来完成(特殊情况下也可以通过 this.$parent 来得到父组件的引用):
<div id="app"> <my-component message="hello"></my-component> </div>
Vue.component("my-component", { props: ["message"], //标准写法应该是: //props: { // message: { // type: String, // require: true // } //} //这样写更加严谨 template: "<p> {{ message }} </p>" }); new Vue({ el: "#app" })
- prop属性是单向绑定的,即子级组件会随着父组件属性的变化而变化
- Vue实例定义了事件接口,可以分别使用 $on(eventName),$emit(eventName) 来监听和触发事件,例如:
<div id="app" v-bind:style="{fontSize: size + 'px'}"> <!--父级组件可以在使用子组件的地方直接使用 v-on 来监听子组件触发的事件,相当于子组件向父组件传递数据--> <!--因为vue有自己的事件系统,所以在父级组件中假如要使用原生的事件,则需要使用.natuve修饰符,因为vue期望的是一个自定义事件--> <my-component v-bind:message="hello" v-on:bigger="test" v-bind:style="{fontSize: size + 'px'}"></my-component> {{ size }} </div>
Vue.component("my-component", { props: ["message"], template: "<button v-on:click=\"$emit('bigger')\"> {{ message }} </button>" }); new Vue({ el: "#app", data: { size: 15 }, methods: { test: function () { console.log(this.size++) } } });
- props验证:可以用于验证绑定的数据的格式,比如:
上面的 props 在将值传递给子组件的时候会对值的类型进行检验,假如符合则传递,不符合会报 undefined 错误(有例外,给Boolean传数字也会通过检验)<div id="app"> <my-component v-bind:num="123" v-bind:bool="ad"></my-component> </div> <script> Vue.component("my-component", { props: { num: Number, bool: Boolean }, template: "<div><p> {{ num }} </p><p> {{ bool }} </p></div>" }); new Vue({ el: "#app" }) </script>
- 可以使用 .native 修饰符来监听原生事件
- 可以检验的基本对象类型有 Boolean、String、Object、Function、Number、Array,以及自定义类型,使用 instanceof 检测
- slot:插槽,可以将组件和组件标签里面的内容包含在一起:
可以包含的内容包括所有模板代码、html、字符串、其它组件等等,假如组件模板里面没有 slot,则使用组件的时候,被组件标签包含的内容都会被抛弃<div id="id-demo"> <test>world</test> </div> <script> Vue.component('test',{ template: `<p>hello <slot></slot></p>`, }); new Vue({ el: '#id-demo', data: { }, methods: { } }) </script>
- 卡槽里面的内容可以访问组件的实例属性(公有作用域),而不能访问组件的私有属性
- 可以在 <slot> 标签里面定义后备内容,当组件标签里没有包含内容的时候,便会渲染后备内容
- 当有多个卡槽的时候,可以给卡槽命名:
不带 name 的卡槽默认名字是 default,可以对 default 进行显示命名控制其中的内容;任何没有被带有 v-slot 包裹的内容都会被当做默认内容<div id="id-demo"> <test> <template v-slot:section1>world</template> <template v-slot:section2>!</template> </test> </div> <script> Vue.component('test',{ template: `<p>hello <slot name="section1"></slot> <slot name="section2"></slot></p>`, }); new Vue({ el: '#id-demo' }) </script>
- 作用域插槽:
- 可以使插槽内容访问子组件里面的数据:
首先将子组件的数据绑定到卡槽的属性上(比如上面的代码中,slot 将数据 user 绑定到自己的属性 user 上),然后父组件使用 v-slot:卡槽名=“自定义卡槽上的绑定属性名” 来使用<div id="id-demo"> <test> <!--v-slot:section="sectionProp" 意味着可以使用sectionProp来访问名字为section的卡槽的所有绑定的属性--> <template v-slot:section="sectionProp">{{ sectionProp.user.sex }}</template> </test> </div> <script> Vue.component('test',{ template: `<p>hello <slot name="section" :user="user">{{ user.name }}</slot></p>`, data: function () { return { user: { name: 'jame', sex: 'man' } } } }); new Vue({ el: '#id-demo', }) </script>
- v-slot 可以使用简写 #,但简写的时候必须指明相应的 slot 的 name,比如上面的可以简写为 #section=‘sectionProp’
- 使用 <component> 组件:渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。可以渲染 html 标签,可以用来渲染动态组件,比如:
<div id="id-demo"> <component :is="'test-' + check"></component> <button @click="check = !check">click</button> </div> <script> Vue.component('test-true',{ template: `<p>hello</slot></p>`, }); Vue.component('test-false',{ template: `<p>world</slot></p>`, }); new Vue({ el: '#id-demo', data: { check: true } }) </script>
- 路由 props 属性:当使用 <router-link> 导航到某一个组件,且使用了 params 来传递参数时,在路由表里设置 props: true 可以使当前路由携带的参数作为目标组件的 props,也可以为下面这种形式:
{
path: ':id',
name: 'Ticket',
component: Ticket,
props: route => { return { id: route.params.id } }//适合 props 是动态时使用
},
{
path: ':id',
name: 'Ticket',
component: Ticket,
props: { id: 'abc' }//适合 props 是动态时使用
}
自定义指令
- Vue 可以使用 directive 属性来自定义指令,基本格式:
//定义全局指令
Vue.directive("commandName", {
钩子函数: function(el, binding, vnode, oldVnode){
.....
}
})
//定义局部指令
new Vue({
el: "#app"
directive: {
commandName: {
钩子函数: function(el, binding, vnode, oldVnode){
.....
}
}
}
...
})
- 自定义指令名称使用的时候要加上“v-on”的前缀
- 钩子函数类型有:
- bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
- inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)
- update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新
- componentUpdated: 被绑定元素所在模板完成一次更新周期时调用
- unbind: 只调用一次, 指令与元素解绑时调用
- 钩子函数参数:
- el: 指令所绑定的元素,可以用来直接操作 DOM
- binding: 一个对象,包含以下属性:
- name: 指令名,不包括 v- 前缀
- value: 指令的绑定值, 例如: v-my-directive=“1 + 1”, value 的值是 2
- oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用
- expression: 绑定值的表达式或变量名。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”
- arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”
- modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }
- vnode: Vue 编译生成的虚拟节点
- oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
vue实例生命周期
- beforeCreate:实例创建之前执行的函数
- created:实例已经创建,但页面还没有展示
- beforeMount:实例在挂载前,页面还没有展示,但虚拟dom已经配置
- mounted:实例挂载后,页面在这个函数之后展示
- beforeUpdate:页面更新触发的方法,实例更新前,虚拟dom已经配置,但页面还没有更新
- updated:实例更新后,页面在这个函数之后更新
- beforeDestroy:实例销毁前
- destroyed:实例销毁后
路由
- 安装路由组件:
cnpm install vue-router --save-dev
- 路由:担任一个类似于中间人的角色,将客户端请求的 url 转发到对应的服务器内的地址
- 基本使用:
import vueRouter from 'vue-router' Vue.use(veuRouter); const router = new vueRouter({ routes: [ { path: '/XXX', name: 'XXX', component: 'XXX' }, //children用于定义子路由,redirect用于定义子路由的默认页面 { path: '/XXX', name: 'XXX', component: 'XXX', redirect: 'ZZZ', children: [{二级路由}, {}] }, { path: '*', redirect: YYY }//默认路由地址 ], mode: "history"//去掉每次切换路径的时候,url会带上#/ }); new Vue({ ... router, ... })
- 使用 <router-view> 和 <router-link>
- <router-view> 用于显示路由切换后的内容,可以在任何子组件中使用
- <router-link> 用于路由跳转,无需重新刷新整个页面
<router-link to="/path">使用路由path</router-link> <router-link :to="{ name: 'XXX' }">使用路由name,也可以是组件自定义data</router-link>
- <router-link> 可以使用 tag 属性自定义最后显示的标签,比如:
<router-link to="/path" tag="div">使用div标签</router-link>
- <router-link> 使用之后会默认使用 .router-link-active 样式,所以可以修改这个样式来渲染正在使用的<router-link>
- 在默认情况下,active class 是包容的,所以比如当使用的路由路径为:/Home/xxx,则 “/” 和 “/Home” 的<router-link>同样也会被渲染,解决方法是声明 exact 属性,这个属性的功能是:只有路径完全符合时,才会渲染 active class
- 可以使用 $router 的方法来跳转到上次浏览的路由或者指定路由,比如:
methods: { back: function () { this.$router.go(-1);//返回上次路由 }, go: function () { this.$router.replace('routerPath');//通过路径返回指定路由 //this.$router.replace({ name: 'routerName' });//通过路由名字返回指定路由 //push()的效果和replace()差不多,不同的地方是replace()将浏览器中的当前条目替换为新路由,而不添加新的条目 //this.$router.push('routerPath') //this.$router.push({ name: 'routerName' }) } }
- 通过 name 和通过 path 来进行页面跳转时,name 能够将 param 和 query 一起传过去,而 path 只能传 query
- 动态路由:当不同用户请求的页面相同,但是路径不同,比如说登录之后的欢迎界面,就可以使用动态路由来实现:
可以使用 $route.params.userName 来获取到变化的部分new Router({ routers: [ { path: '/login/:userName',//动态路由的可变部分以“:”标示 name: 'Login', component: Login } ] })
- $route和$router的区别:
- router:是一个全局属性,包含所有的路由信息
- route:指代当前路由,包含当前路由的所有信息,包括name、params等,可以通过next()来传递这些信息给下一个路由
- 导航守卫:
- 全局前置守卫:在 main.js 中使用 router.beforeEach() 来设置全局前置守卫,每次路由改变前都会进行守卫,比如:
router.beforeEach((to, from, next) => { alert(1);//每次路由改变都会弹出1 });
- 路由复用:在不同的组件中使用同样的路由
//在组件的template中使用的 router-view 使用一个name属性 <template> <div id="app"> <router-view name="meanue"></router-view> </div> </template>
//然后在路由表里面指定组件 new Router({ routers: [ { path: '/', name: 'Home', components: { default: Home, 'meanue': Meanue } } ] })
- 控制滚动行为:使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。
http
- 安装 http 组件:
cnpm install vue-resource --save
- 调用模拟接口
created: function () { this.$http.get("http://jsonplaceholder.typicode.com/users").then((data) => { console.log(data); }) }
- 跨越请求:
过滤器
- 创建过滤器:
//全局过滤器
Vue('filterName', func)
- 使用:
{{ data | filterName }}
- 例子:
<div id="id-demo">
<ul v-for="num in nums">
<li>{{ num | check }}</li>
</ul>
</div>
<script>
Vue.filter('check', function (num) {
if (num > 0)
return num;
else
return -1;
});
new Vue({
el: '#id-demo',
data: {
nums: [5, 6, -8, -2]
}
})
</script>
- filter 可以在双括号表达式和 v-bind 中使用
过渡和动画
- 使用 <transition> 对需要添加动画效果的组件进行包裹:
- 在以下四种情况下可以使用:
- 条件渲染(使用v-if)
- 条件展示(使用v-show)
- 动态组件
- 组件根节点
- 当删除或插入包含在 <transition>组件的元素时,vue会执行以下三步:
- 查看有没有使用css过渡或者动画,假如有则在恰当的时间添加\删除类名
- 查看有没有调用钩子函数,假如有在恰当的时间调用钩子函数
- 假如既没有css过渡也没有钩子函数,则在动画的下一帧立刻执行dom操作
- 在以下四种情况下可以使用:
- 在进入\离开过渡中,共有6个class切换:
- 进入过渡:
- v-enter:在元素进入之前触发,在节点插入dom后立刻删除
- v-enter-active:在元素进入过程中触发
- v-enter-to:在元素进入之后马上触发(v-enter 删除下一帧)
- 离开过渡:
- v-leave:在元素离开之前触发
- v-leave-active:在元素离开的过程中触发
- v-leave-to:在元素离开之后马上触发(v-leave 删除下一帧)
- 进入过渡:
- <transition>的 name 属性:假如不定义name属性,则样式默认的名称是 v-xxx,而定义了name之后,样式的名称变为 样式名-xxx
- css动画和css过渡用法一样,不同之处在于css动画会在触发animation事件后才会删除 v-enter 而不是在节点插入dom后就删除
- 自定义类名:我们可以使用自定义的带有 -class 后缀的类名,比如 v-leave-to-class,优先级要比class高
- 钩子函数:@before-leave、@leave、@after-leave、@leave-cancelled,进入过渡类似
- 初始渲染过渡:使用 appear,使用方法和前面类似
- 滚动行为:
- 路由器的history模式允许在页面改变时,管理页面滚动,可以将每次位置重置为最高位置,或者返回之前路由位置(浏览器后退按钮返回)
mode: 'history', //scrollBehavior函数期望返回值是一个可以有两种不同形式的对象: //{ x: 100, y: 100 } //{ selector: '#foo', offset: { x: 0, y: 200 } } scrollBehavior(to, from, savedPosition){ if (savedPosition){//savedPosition是浏览器历史记录中每个条目自动保存的位置 return savedPosition } if (to.hash){ return{ selector: to.hash } } return{ x: 0, y: 0 } }
混入
- 使用:mixins: [ ]
- 混入的功能是将混入对象的内容合并到自己的组件里面,合并规则有:
- 相同名称的对象合并为一个对象,如data、computed、methods等
- 相同名称的值,只取组件的值,比如data的数据对象、computed和methods的函数对象
- 相同名称的钩子函数都会执行,混入对象的先执行
- 可以使用 Vue.mixins 来进行定义全局混入对象