vue组件
定义Vue组件
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
一 全局组件定义的三种方式
使用 Vue.extend 配合 Vue.component 方法:
1.1 使用 Vue.extend 来创建全局的Vue组件
通过 template 属性,指定了组件要展示的HTML结构
var login = Vue.extend({
template: '<h1>登录</h1>'
});
1.2 使用 Vue.component('组件的名称', 创建出来的组件模板对象)
Vue.component('mycom1', login);
1.3 如果要使用组件,标签形式,引入自己的组件
<mycom1></mycom1>
直接使用 Vue.component 方法:
定义:
Vue.component('mycom2', {
template: '<h1>注册</h1>'
});
使用:
如果要使用组件,标签形式,引入自己的组件
<mycom2></mycom2>
将模板字符串,定义到script标签种:
第二种的基础上方便HTML的编写<script id="tmpl" type="x-template">
<div><a href="#">登录</a> | <a href="#">注册</a></div>
</script>
同时,需要使用 Vue.component 来定义组件:
Vue.component('account', {
template: '#tmpl'
});
注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!
二 组件中展示数据和响应事件
1. 组件可以有自己的 data 数据 和 methods
2. 组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法
3. 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
4. 组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样!!!
在组件中,
data
需要被定义为一个方法,而不是一个对象了。例如:Vue.component('account', {
template: '<h1>这是全局组件 --- {
{msg}}</h1>',
data() {
return {
msg: '组件自己的数据'
}
},
methods:{
login(){
alert('点击了登录按钮');
}
}
});
- 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的
data
属性中的值,需要使用this
来访问;
【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象
- 通过计数器案例演示
三 使用components
属性定义局部子组件
组件实例定义方式:
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: { // 定义子组件
account: { // account 组件
template: '<div><h1>这是Account组件{
{name}}</h1></div>', // 在这里使用定义的子组件
components: { // 定义子组件的子组件
login: { // login 组件
template: "<h3>这是登录组件</h3>"
}
}
}
}
});
</script>
引用组件:
<div id="app">
<account></account>
</div>
四 使用flag
标识符结合v-if
和v-else
切换组件(只能切换2个)
页面结构:
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<my-com1 v-if="flag"></my-com1>
<my-com2 v-else="flag"></my-com2>
</div>
Vue实例定义:
<script>
Vue.component('myCom1', {
template: '<h3>奔波霸</h3>'
})
Vue.component('myCom2', {
template: '<h3>霸波奔</h3>'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {}
});
</script>
五 使用:is
属性来切换不同的子组件,并添加切换动画(通过mode属性)
组件实例定义方式:
// 登录组件
const login = Vue.extend({
template: `<div>
<h3>登录组件</h3>
</div>`
});
Vue.component('login', login);
// 注册组件
const register = Vue.extend({
template: `<div>
<h3>注册组件</h3>
</div>`
});
Vue.component('register', register);
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: { comName: 'login' },
methods: {}
});
使用
component
标签,来引用组件,并通过:is
属性来指定要加载的组件:<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='register'">注册</a>
<hr>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
添加切换样式:
<style>
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(30px);
}
.v-enter-active,
.v-leave-active {
position: absolute;
transition: all 0.3s ease;
}
h3{
margin: 0;
}
</style>
六 父组件向子组件传值
组件实例定义方式,注意:一定要使用
props
属性来定义父组件传递过来的数据<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
msg: '这是父组件中的消息'
},
components: {
son: {
template: '<h1>这是子组件 --- {
{finfo}}</h1>',
props: ['finfo']
}
}
});
</script>
使用
v-bind
或简化指令,将数据传递到子组件中:通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,
以属性绑定的形式,传递到子组件内部,供子组件使用
<div id="app">
<son :finfo="msg"></son>
</div>
data与props的区别
注意1: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,
比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
注意2: data 上的数据,都是可读可写的;
props 中的数据,都是只读的,无法重新赋值
七 父组件向子组件传方法
1.定义一个字面量类型的 组件模板对象
2.创建vue实例,得到ViewModel,加载组件
3.template: 通过指定了一个 Id, 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
4.在app控件中使用事件绑定机制传递方法
5.在子组件template模板中,通过自己的方法–调用传递进来的父组件的方法[this.$emit]
var com2 = {
template: '#tmpl', // 通过指定了一个 Id, 表示 说,要去加载 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
data() {
return {
sonmsg: { name: '小头儿子', age: 6 }
}
},
methods: {
myclick() {
// 当点击子组件的按钮的时候,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
// emit 英文原意: 是触发,调用、发射的意思
// this.$emit('func123', 123, 456)
this.$emit('func', this.sonmsg)
}
}
}
=============================================
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
datamsgFormSon: null
},
methods: {
show(data) {
// console.log('调用了父组件身上的 show 方法: --- ' + data)
// console.log(data);
this.datamsgFormSon = data
}
},
components: {
com2
// com2: com2
}
});
=====================================
<div id="app">
<com2 @func="show"></com2>
</div>
=====================================
<template id="tmpl">
<div>
<h1>这是 子组件</h1>
<input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
</div>
</template>
八 子组件向父组件传值
- 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;
子组件内部通过
this.$emit('方法名', 要传递的数据)
方式,来调用父组件中的方法,同时把数据传递给父组件使用在子组件方法中传入参数
this.$emit('方法名', 123,456) data =123 data2 =456
在父类方法中接收参数
var vm = new Vue({
el: '#app',
data: {
datamsgFormSon: null
},
methods: {
show(data,data2) {
// console.log('调用了父组件身上的 show 方法: --- ' + data + data2)
this.datamsgFormSon = data
}
}
九 评论列表案例
目标:主要练习父子组件之间传值
十 使用 this.$refs
来获取元素和组件(获取dom元素)
<div id="app">
<div>
<input type="button" value="获取元素内容" @click="getElement" />
<!-- 使用 ref 获取元素 -->
<h1 ref="myh1">这是一个大大的H1</h1>
<hr>
<!-- 使用 ref 获取子组件 -->
<my-com ref="mycom"></my-com>
</div>
</div>
<script>
Vue.component('my-com', {
template: '<h5>这是一个子组件</h5>',
data() {
return {
name: '子组件'
}
}
});
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {
getElement() {
// 通过 this.$refs 来获取元素
console.log(this.$refs.myh1.innerText);
// 通过 this.$refs 来获取组件
console.log(this.$refs.mycom.name);
}
}
});
</script>
还没有评论,来说两句吧...