vue组件原生事件以及路由
1.组件
组件就是可以扩展HTML元素,封装可重用的HTML代码,可以将组件看作自定义的HTML元素
1.1组件注册
全局注册:
组件注册时,需要给他一个名字,如下:
Vue.component('my-component-name', { /* ... */ })
# 组件名使用kebab-case (短横线分隔命名)定义时,引用这个元素时使用 <my-component-name>
# 组件名使用 PascalCase (驼峰式命名) 定义时,引用这个元素时使用<my-component-name> 和 <MyComponentName>都可以
局部注册:
通过一个普通的 JavaScript 对象来定义组件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
然后在component选项中定义想要的组件
new Vue({
el: '#app'
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
# 局部注册的组件在其子组件中不可用
全局注册实例:
组件的复用(主体代码):
<body>
<div id="app">
<buttons></buttons>
<buttons></buttons>
<buttons></buttons>
</div>
<hr>
<div id="app2">
<buttons></buttons>
</div>
</body>
<script>
// 组件中data必须是一个函数,第一个参数是我们的定义标签
Vue.component('buttons',{
data:function(){
return{
count:0
}
},
template:`<button v-on:click='count++'>biubiubiu{{ count }}</button>`
}) var app = new Vue({
el:"#app"
}) var app2 = new Vue({
el:"#app2"
})
</script>
效果:

局部注册实例:
(父组件往子组件传值)
<body>
<div id="app">
<bts v-bind:name='fir'></bts>
<bts v-bind:name='sec'></bts>
<bts v-bind:name='thi'></bts>
<hr>
<bts v-for='nums in list' v-bind:name='nums'></bts>
</div>
</body>
<script>
// 这里的buttons属于我们的自定义标签,通过props向子组件传递数据
var myComponent = {
template:`<button v-on:click="cli">{{name}}+{{count}}</button>`,
// 使用props声明,组件需要外边从data给传一个字符串格式的name变量
props:{
name:String
},
data:function(){
return{
count:0,
}
},
methods:{
cli:function(){
this.count += 1
}
}
} // 自定义局部组件
new Vue({
el:'#app',
data:{
list:[
'1',
'2',
'3',
],
fir:'first',
sec:'second',
thi:'third',
},
components:{
bts:myComponent
}
})
</script>
效果:
1.2props
2.组件组织:

该图很好的表明了组件的组织关系对应图,或者说是层级关系
Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,只要先在父级应用中写好各种组件标签,并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现,然后整个应用就算做完了
3.组件中的数据传递(props)
<body>
<div id="app">
<!-- 写死了 -->
<buttons title="My journey with Vue"></buttons>
<buttons title="Blogging with Vue"></buttons>
</div>
<hr>
<!-- 动态传递 -->
<div id="app2">
<buttons
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></buttons>
</div>
</body>
<script>
Vue.component('buttons', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
}) var app = new Vue({
el:"#app",
}) var app2 = new Vue({
el:"#app2",
// 动态传递一个数组
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
]
}
})
</script>
子组件往父组件传值:
<body>
<div id="app">
<p>总数:{{total}}</p>
<bts v-for='nums in list' v-bind:name='nums' v-on:zhi="add"></bts>
</div>
</body>
<script>
// 这里的bts属于我们的自定义标签,通过props向子组件传递数据
var myComponent = {
template:`
<div>
<button v-on:click="cli">{{count}}{{name}}</button>
</div>
`,
// 使用props声明,组件需要外边从data给传一个字符串格式的name变量
props:{
name:String
},
data:function(){
return{
count:0,
}
},
methods:{
cli:function(){
this.count += 1;
// 在组件中通过触发自定义事件向外传递信息
this.$emit('zhi')
}
}
} // 自定义局部组件
new Vue({
el:'#app',
data:{
total:0,
list:[
'只猪','只狗','只兔子',
]
},
components:{
bts:myComponent
},
methods:{
add:function(){
this.total += 1
}
}
})
</script>
效果:

组件间传值(生成一个空vue对象bus):
各个组件内部要传输的数据或者要执行的命令信息,靠bus来通信。
<body>
<div id="app">
<bt></bt>
<hr>
<nums></nums>
</div> </body>
<script>
var bus = new Vue();
var app = new Vue({
el:'#app',
data:{
name:'bt'
},
components:{
bt:{
template:`<button v-on:click='check'>点我</button>`,
methods:{
check(){
bus.$emit('things')
}
}
},
nums:{
template:`<div>{{num}}</div>`,
data:function(){
return {
num: 0
} },
mounted:function(){
// 该组件中this指num实例
var _this = this;
console.log(_this);
// 监听bus
bus.$on('things', function(){
// 在这个作用域中 this 指的是 bus
console.log(this.num) // undefined
// 修改num组件中的num值
// 此时this是谁?
// this.num += 1; // 有问题
_this.num += 1;
})
} }
} })
</script>
在第一个组件中的methods方法里,通过bus.$emit()方法发射事务
在第二个组件实例化的钩子中(mounted)中,通过bus.$on监听自家$emit触发的事件
4.插槽:(使用自定义标签<slot>元素达到目的的)
插槽是占位置的!!!
插槽多了可以起名字,进行区分! --> <span slot='heihei'>嘿嘿!</span>
<body>
<div id="app">
<alert-box>
Something bad happened.
</alert-box>
</div>
</body>
<script>
Vue.component('alert-box', {
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
`
})
new Vue({
el:"#app"
})
</script>
效果:

5.将原生事件绑定到组件(.naive修饰符)
如果想在一个组件的根元素上直接监听一个原生事件,这时候就可以使用v-on的.naive修饰符
实例0(不推荐使用):
<body>
<div id="app">
<ztzsb v-on:click='hehe'></ztzsb>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
name: 'ztz',
age: 24
},
components: {
ztzsb: {
template: `<button v-on:click='shangkele'>赵天柱 逃课!</button>`,
methods:{
shangkele:function(){
this.$emit('click')
}
}
}
},
methods:{
hehe:function(){
alert(123);
}
}
})
</script>
</html>
实例1:
<body>
<div id="app">
<ztz v-on:click.native='hehe'></ztz>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{}, components:{
ztz:{
template:`<button>赵天柱 逃课!</button>`
},
},
methods:{
hehe:function(){
alert(123);
}
}
})
</script>
</html>
再看看下面的实例2:
<body>
<div id="app">
<ztz></ztz>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{},
components:{
ztz:{
template:`<button v-on:click='hehe'>赵天柱 逃课!</button>`,
methods:{
hehe(){
alert(123);
}
}
},
}
})
</script>
## 实例1和2两者效果一模一样,一个是在根元素上进行事件绑定,一个是在局部组件上进行绑定
6.总结
1. Vue组件
0. 组件注意事项!!!
data属性必须是一个函数! 1. 注册全局组件
Vue.component('组件名',{
template: ``
}) var app = new Vue({
el: '#app'
})
2. 注册局部组件
var app = new Vue({
el: '#app',
components:{
局部组件名:{
template: `...`
}
}
})
3. 传值
1. 父组件 --> 子组件
1. 父组件通过 v-bind:变量='值'
2. 子组件需要通过props 声明我需要的变量
2. 子组件 --> 父组件
子组件通过触发自定义事件的方式向外传递信息
1. 子组件: this.$emit('自定义事件')
2. 父组件: v-on:自定义事件='方法名' 3. 组件间传值
1. 补充:Vue实例的生命周期钩子函数(共8个)
1. beforeCreate --> 数据属性声明但没有赋值
2. created --> 数据属性赋值
3. beforeMount --> 页面上的 {{name}} 还没有被渲染
4. mounted --> 页面上的 {{name}} 被替换成真正的内容
... 2. 基于bus对象实现 4. 插槽(slot)
插槽是占位置的!!!
插槽多了可以起名字,进行区分! --> <span slot='heihei'>嘿嘿!</span>
<alert>根本不显示</alert> 5. 组件的注意事项:
1. 特殊的组件需要使用is语法声明一下 比如 table、select、ul等内部使用的组件
2. 捕获子组件的原生事件
7.Vue.Router
Vue Router 是 Vue.js 官方的路由管理器
将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们,实现异步ajax界面切换效果(页面不刷新)
# 例,注意vue-router.js的引入方式
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<body>
<div id="app">
<!-- 路由入口 -->
<router-link to='/index'>index页面</router-link>
<router-link to='/home'>home页面</router-link>
<hr>
<!-- 路由出口 -->
<router-view></router-view>
</div>
</body>
<script>
// 路由,数组包含两个路由
const routess = [
{path:'/index',component:{template:`<div><h2>index页面</h2></div>`}},
{path:'/home',component:{template:`<div><h2>home页面</h2></div>`}},
]
// 生成实例,routes是关键字,它的值必须是一个数组
const routerObj = new VueRouter({
routes:routess
}) new Vue({
el:'#app',
// 路由实例挂载到vue实例中,router是关键字
router:routerObj
})
</script>
</body>
</html>
效果:

7.1路由动态匹配
我们有一个 User 组件,对于 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个目的
一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,如下

实例:
<body>
<div id="app">
<!--路由的入口-->
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/user/index">index页面</router-link>
<router-link to="/user/home">home页面</router-link>
<hr>
<p>666</p>
<!--路由的出口-->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
<p>999</p>
</div>
<script>
//写路由
const routeArray = [
{ path: '/user/:name',
component: {template: `<h3>这是{{$route.params.name}}的主页页面!</h3>`}
}
]
//生成路由实例
const routerObj = new VueRouter({
routes: routeArray
})
var app = new Vue({
el:'#app',
//router是关键字,它的值必须是数组
router:routerObj //将路由实例挂载到vue实例中
})
</script>
效果:

7.2嵌套路由(子路由)
URL 中各段动态路径按某种结构对应嵌套的各层组件,如下:
实例(关键点在于使用append拼接路由):
<div id="app">
<router-link to="/user/index">index</router-link>
<router-link to="/user/home">home</router-link>
<hr>
<router-view></router-view>
</div>
<script>
// 生成路由数组
const routeArray = [
{
path: '/user/:name',
component: {
//append表示当前路由拼接url,比如/user/home/info
//router-view对应子路由的template的内容
template: `<div>
<h3>这是{{$route.params.name}}的主页页面!</h3>
<hr>
<router-link to='info' append>用户详细信息</router-link>
<router-view></router-view>
</div>`
},
// 定义子路由
children:[
{
path: 'info',
component:{
template: `
<div>
<h1>大傻逼</h1>
</div>
`
}
},
]
}
]
//生成VueRouter实例
const routerObj = new VueRouter({
//routes是关键字参数,它必须对应一个数组
routes: routeArray
})
var app = new Vue({
el:'#app',
data:{},
//router是关键字,它的值必须是数组
router:routerObj //将路由实例挂载到vue实例中
})
</script>
效果:

总结:
1. Vue全家桶
Vue + VueRouter + VueX
2. VueRouter https://router.vuejs.org/zh/
1. 基本使用
1. 必须导入vue-router.js文件
2. 要有VueRouter()实例
3. 要把VueRouter实例挂载到Vue实例中 4. 路由的入口
<router-link to='/index'>index页面</router-link>
5. 路由的出口
<router-view></router-view>
2. 路由的参数
1. path: '/user/:name' --> 匹配路由
$route.params.name --> 取值 2. /user/alex?age=9000 --> url中携带参数
$route.query.age --> 取出url的参数 3. 子路由
children:[
{
path: '',
component: {
template: `...`
}
}
] <router-link to='info' append></router-link>
vue组件原生事件以及路由的更多相关文章
- vue组件添加事件@click.native
1,给vue组件绑定事件时候,必须加上native ,否则会认为监听的是来自Item组件自定义的事件 2,等同于在子组件中: 子组件内部处理click事件然后向外发送click事件:$emit(&q ...
- vue组件---自定义事件
首先简单回顾下组件事件及组件的复用 demo1:按钮事件 <div class="button_area"> <button-area></butto ...
- vue组件之事件
自定义事件 通过prop属性,父组件可以向子组件传递数据,而子组件的自定义事件就是用来将内部的数据报告给父组件的. <div id="app3"> <my-com ...
- vue组件中—bus总线事件回调函数多次执行的问题
在利用vue组件进行事件监听时发现,如果对N个vue组件实例的bus总线绑定同一事件的回调函数,触发任意组件的对应事件,回调函数至少会被执行N次,这是为什么呢? 为此,调研了普通对象的事件绑定和触发实 ...
- vue组件事件(极客时间Vue视频笔记)
vue组件核心:事件 <body> <div class="app"> <todo-list></todo-list> {{mess ...
- Vue-native绑定原生事件
首先介绍一下是什么意思: 意思就是当你给一个vue组件绑定事件时候,要加上native!如果是普通的html元素!就不需要 <div id = "app"> <m ...
- [Vue]组件——使用.native和$listeners将控件的原生事件绑定到组件
1.方法1:.native修饰符 1.1.native修饰符:将原生事件绑定到组件的根元素上 <base-input v-on:focus.native="onFocus"& ...
- vue怎么给自定义组件绑定原生事件
下面主要以4个示例Demo演示(示例代码JS引用的Vue CDN),建议小伙伴直接复制示例代码运行查看, 赶时间的小伙伴可直接往下拉,看示例demo4 注:全局或局部注册的组件称为子组件,其中声明的 ...
- vue自定义组件添加原生事件监听
注:全局或局部注册的组件称为子组件,其中声明的组件名称(如下demo中的child)是一个自定义组件 Demo1-直接给父组件添加事件监听 <!DOCTYPE html> <html ...
随机推荐
- HDU 1800——Flying to the Mars——————【字符串哈希】
Flying to the Mars Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- ajax返回数据之前的loading等待
首先,我们通过ajax请求,向后台传递参数,然后后台经过一系列的运算之后向前台返还数据,我希望在等待数据成功返还之前可以展示一个loading.gif图 不废话,在页面上执行点击事件(<a sc ...
- SQL Server Profiler(转载)
SQL Server Profiler工具 一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收 ...
- 初学Hadoop之计算TF-IDF值
1.词频 TF(term frequency)词频,就是该分词在该文档中出现的频率,算法是:(该分词在该文档出现的次数)/(该文档分词的总数),这个值越大表示这个词越重要,即权重就越大. 例如:一篇文 ...
- web.config节点
1.clientCache 源码: <system.webServer> <staticContent> <clientCache cacheControlMode=&q ...
- PHP 文件锁和常用文件函数
文件锁 bool flock ( int handle, int operation [, int &wouldblock] );flock() 操作的 handle 必须是一个已经打开的文件 ...
- Csharp:TinyMCE HTML Editor in .NET WindowsForms
/// <summary> /// /// </summary> public partial class Form2 : Form { private mshtml.IHTM ...
- clearfix为什么用display:table,而不用display:block
我们都知道clearfix一般这么写: .clearfix:before,.clearfix:after{ content:""; display:table; } .clearf ...
- 有关background 背景图片不能显示
首先有两个概念 绝对路径,从根目录为起点到你所在的目录: 相对路径,从一个目录为起点到你所在的目录. 例如: ┍ A文件夹 C -| ...
- TiDB, Distributed Database
https://www.zhihu.com/topic/20062171/top-answers
