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 ...
随机推荐
- ul+js模拟select+改进
html: <div class="select_box"> <input type="text" value="还款方式" ...
- 互联网轻量级框架SSM-查缺补漏第一天
简言:工欲其事必先利其器,作为一个大四的准毕业生,在实习期准备抽空补一下基础.SSM框架作为互联网的主流框架,在会使用的基础上还要了解其原理,我觉得会对未来的职场会有帮助的.我特意的买了一本<J ...
- Java ConcurrentHashMap的小测试
今天正式开始自己的分布式学习,在第一章介绍多线程工作模式时,作者抛出了一段关于ConcurrentHashMap代码让我很是疑惑,代码如下: public class TestClass { priv ...
- typeScript入门(一)构建环境和数据类型
最近入坑v-cli 3.0,发现ts越来越常用了,于是开始入坑学习. 1.构建ts环境 npm install -g typescript Mac和vscode用户可以用以下方式构建tsdemo项目 ...
- Django组件——分页器(paginator)
一.视图层 from django.shortcuts import render # Create your views here. from .models import Book from dj ...
- SQLAlchemy的使用---增删改查
#通过SQLAlchemy对数据库进行增删改查 # 想要操作数据库 先要打开数据库连接 from create_table import engine # 创建会话 - 打开数据库连接 from sq ...
- Web前端面试指导(十二):::before 和:before有什么区别?
题目点评 这个问题看来很简单,但如果之前没有琢磨这个问题,给人感觉也是门头一垂,听到这个题目就懵逼了,因为原来从来没有注意过这个问题,即便有注意这个问题也不能很好的回答清楚.回答的技巧就是从相同点和不 ...
- (一)svn介绍
项目管理中的版本控制问题 通常软件开发由多人协作开发,如果对代码文件.文档等没有进行版本控制,将会出现很多问题: 备份多个版本,占用磁盘空间大 解决代码冲突困难 容易引发BUG 难于恢复至以前正确版本 ...
- [C# 网络编程系列]专题八:P2P编程
引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...
- jvm 的性能调优
一个描述的比较生动的博客:JVM内存区域划分Eden Space.Survivor Space.Tenured Gen,Perm Gen解释 地址:https://www.cnblogs.com/sg ...