Vue.js 组件
组件(Component)是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
<template> div id="app"> <!-- 使用自定义组件 --> runoob></> </div> > script> import Vue from 'vue' // 注册组件 Vue.component(runoob,{ template: <h1>自定义组件!</h1> }) var count=1; export default { name: Appreturn{ } },methods:{ },} style scopedstyle>
也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:
Child { template: } :Child },1)">>
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
child msg="hello,cyy"child Vue.component(childmsg],template:<span>{{msg}}</span>>
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
input type="text" v-model="info"v-bind:msg<span>template content: {{msg}}</span>{ info:'' } },1)">>
以下实例中使用 v-bind 指令将 item传到每一个重复的组件中:
v-for="(item,index) in list" :key="index" v-bind:msg="item.name"<span>{{msg}}<br></span>{ list:[ { name:cyy1 },{ name:cyy2cyy3 } ] } },1)">>
注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
组件可以为 props 指定验证要求。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
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
}
}
}
})
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type 可以是下面原生构造器:
String
Number
Boolean
Array
Object
Date
Function
Symbol
type 也可以是一个自定义构造器,使用 instanceof 检测。
父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
我们可以使用 v-on 绑定自定义事件,每个 Vue 实例都实现了事件接口(Events interface),即:
- 使用
$on(eventName)
监听事件 - 使用
$emit(eventName)
触发事件
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。
@add-count="addCount"p>{{total}}<button @click="addNum">click me</button>{ num:0this.num+=; .$emit(add-count); } } }) { total:.total; } },1)">>
如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:
my-component v-on:click.native="doTheThing"my-component>
子组件通过 $emit 触发父组件的方法时,如果需要传递参数,可在方法名后面加可选参数,参数以逗号隔开。
比如 $emit("FunctionName") 当要传递参数时 :$emit("FunctionName",[arg1,arg2...])。
除了默认设置的核心指令( v-model 和 v-show ),Vue 也允许注册自定义指令。
下面我们注册一个全局指令 v-focus,该指令的功能是在页面加载时,元素获得焦点:
也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:
focus:{ inserted:(el){ el.focus(); } } } } >
-
update
: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。 -
componentUpdated
: 被绑定元素所在模板完成一次更新周期时调用。
钩子函数的参数有:
- 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 }
。
-
name: 指令名,不包括
- vnode: Vue 编译生成的虚拟节点。
-
oldVnode: 上一个虚拟节点,仅在
update
和componentUpdated
钩子中可用。
v-cyy:hello.a.b="msg"自定义指令cyy cyy(el,binding,vnode){ el.innerHTML` 指令名:${JSON.stringify(binding.name)}<br/> 指令的绑定值:${JSON.stringify(binding.value)} 指令绑定的前一个值:${JSON.stringify(binding.oldValue)} 绑定值的表达式或变量名:${JSON.stringify(binding.expression)} 传给指令的参数:${JSON.stringify(binding.arg)} 一个包含修饰符的对象:${JSON.stringify(binding.modifiers)} 虚拟节点的键值:${Object.keys(vnode).join()} `; } }) export { msg:i am cyy>
v-cyy:backgroundColor="styleCls">this is a textbinding.value.backgroundColor; } }) export { styleCls:{ backgroundColor:pink } } },1)">>
指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:
v-cyy="{text:text,color:color}"binding.value.text; el.style.colorbinding.value.color; } }) export { text:orange } },1)">>
cnpm install vue-router
<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。
以下实例中我们将 vue-router 加进来,然后配置组件和路由映射,再告诉 vue-router 在哪里渲染它们。代码如下所示:
使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
App.vue
> 通过传入 `to` 属性指定链接. --> <router-link> 默认会被渲染成一个 `<a>` 标签 router-link to="/">home pagerouter-link="/next">next page 路由匹配到的组件将渲染在这里 router-view export { } },1)">>
router/index.js
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' //1. 定义(路由)组件,可以从其他文件 import 进来 const Next = { template: '<div>next</div>' } const routes = [ { path: '/Next'default new Router({ routes })
效果图
点击过的导航链接都会加上样式 class ="router-link-exact-active router-link-active"。
to
表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
字符串 --> ="home">Home 渲染结果 a hrefa 使用 v-bind 的 JS 表达式 v-bind:to="'home'" 不写 v-bind 也可以,就像绑定别的属性一样 :to 同上 ="{ path: 'home' }" 命名的路由 ="{ name: 'user',params: { userId: 123 }}">User 带查询参数,下面的结果为 /register?plan=private ="{ path: 'register',query: { plan: 'private' }}">Register>
replace
设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。
="{ path: '/abc'}" replace>
append
设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
="{ path: 'relative/path'}" append>
tag
有时候想要 <router-link>
渲染成某种标签,例如 <li>
。 于是我们使用 tag
prop 类指定何种标签,同样它还是会监听点击,触发导航。
="/foo" tag="li">fooli>
active-class
设置 链接激活时使用的 CSS 类名。可以通过以下代码来替代。
._active{ background-color : red; } > v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1= "{ path: '/route2'}" tag = "span">Router Link 2>
注意这里 class 使用 active_class="_active"。
exact-active-class
配置当链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代。
exact-active-class >
event
声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。
event = "mouSEOver">
以上代码设置了 event 为 mouSEOver ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。
exact-active-class 和 active-class 的区别
router-link 默认情况下的路由是模糊匹配,例如当前路径是 /article/1 那么也会激活 <router-link to="/article">,所以当设置 exact-active-class 以后,这个 router-link 只有在当前路由被全包含匹配时才会被激活 exact-active-class 中的 class,例如:
="/article" active-class="router-active">
当用户访问 /article/1 时会被激活为:
="#/article" class="router-active" rel="nofollow">
而当使用:
exact-active-class>
当用户访问 /article/1 时,不会激活这个 link 的 class:
>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。