了解更多详情请访问 https://cn.vuejs.org/v2/guide/index.html
一、组件
组件是一种封装可复用的集合,通过组件化,将更好的完成繁杂的需求
组件化特点,具体如下:
1.拥有唯一性的组件名称,方便调用;
2.以组件名称为 HTML 元素标签形式存在,扩展了 HTML;
3.组件可以复用,且组件与组件之间互不干涉;Vue中使用组件的三大步骤:
1.定义组件(创建组件)
2.注册组件(分为全局注册和局部注册)
3.使用组件(写组件标签)
二、注册组件
局部注册:在实例选项中注册局部组件,这样组件只能在这个实例中使用
全局注册:所有实例都能用全局组件
<div id="root"><!-- 第三步:编写组件标签 --><hello></hello><hr><h1>{{msg}}</h1><hr><!-- 第三步:编写组件标签 --><student ></student></div></body><script>Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。//第一步:创建student组件const student = Vue.extend({template:`<div><h2>学生姓名:{{studentName}}</h2><h2>学生年龄:{{age}}</h2></div>`,data(){return{studentName:'张三',age:18}}})//第一步:创建hello组件const hello = Vue.extend({template:`<div><h2>你好啊!{{name}}</h2></div>`,data(){return{name:'Tom'}}})//第二步:全局注册组件Vue.component('hello',hello)//创建vmnew Vue({el:'#root',data:{msg:'你好啊!'},//第二步,注册组件(局部组件)components:{student}})</script>
注意:
1.
Vue.extend()是一个基础构造器(全局 API),意图创建一个子类;2.
Vue.component()是注册组件,参数 1 为名称,参数 2 为extend();3.
data必须写成函数,避免组件被复用时,数据存在引用关系。
三、组件的嵌套
组件和组件之间可以嵌套,形成一种父子关系的组件
<div id="root"></div></body><script>Vue.config.productionTip = false//定义student组件const student = Vue.extend({name:'student',template:`<div><h2>学生姓名:{{name}}</h2><h2>学生年龄:{{age}}</h2></div>`,data(){return {name:'张三',age:18}}})//定义school组件const school = Vue.extend({name:'school',//嵌套student组件template:`<div><h2>学生名称:{{name}}</h2><h2>学生地址:{{address}}</h2><student></student></div>`,data(){return{name:'张三',address:'北京'}},//注册组件(局部)components:{student}})//定义hello组件const hello = Vue.extend({template:`<h1>{{msg}}</h1>`,data(){return{msg:'holle vue'}}})//定义app组件const app = Vue.extend({//嵌套school、hello组件template:`<div><hello></hello><school></school></div>`,//注册组件(局部)components:{school,hello}})new Vue({template:'<app></app>',el:"#root",//注册组件(局部)components:{app}})</script>
四、组件的 props 通信
1.组件的 props
1.组件的父子关系中,当设置一个独立组件时,这个组件就是
new Vue()的子组件;2.当我们需要通过子组件显示父组件
data值的时候,需要通过props属性传值
<div id="root"><student text="李四"></student>//也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:<student v-bind:text="message"></student></div><script>//去掉警告Vue.config.productionTip = false;//局部组件const childComponent = Vue.extend({data() {// 子组件和父组件都有 message 属性,同时调用并不冲突;顺序也可控;return {message : '局部组件'}},//使用传过来的texttemplate : `<div>{{text}} {{message}}</div>`,// 声明 propsprops : ['text']});//数据对象const dataObj = {message : '张三三',};//创建一个Vue对象//父组件const root = new Vue({el : '#root',data:dataObj,// data(){// return{// message: '张三三',// }// },components : {'student' : childComponent},});</script>
2.组件的 props 单向数据流
1.父组件的 data 值更新后通过 props 选项交给子组件进行渲染,反之则不行;
2.这就是单向数据流(单向下行绑定),不能通过子组件来改变父组件的状态;
3.这样做的是为了防止父组件发生改变后,数据流变得难以理解;
4.父组件更新时,子组件所有 props 值也会更新,你不能改变子组件的 props 值
<div id="root"><html-a v-bind:count="count"></html-a></div><script>//去掉警告Vue.config.productionTip = false;//局部组件const childComponent = Vue.extend({data() {return {message : '子组件',}},template : `<button v-on:click="count++">{{count}}</button>`,props : ['count'],})//创建一个Vue对象//父组件const root = new Vue({el : '#root',data : {count : 5},components : {'html-a' : childComponent},});</script>
注意:
以上内容,会正确改变了 props 的值,也渲染到视图中,但控制台报错;
意为:不可以直接修改 props 值,可以通过数据或计算属性来解决;
<div id="root"><html-a v-bind:count="count"></html-a></div><script>//去掉警告Vue.config.productionTip = false;//局部组件const childComponent = Vue.extend({//通过使用 data 数据更改data() {return {message : '子组件',childCount : this.count}},template : `<button v-on:click="clickChildCount">{{changedChildCount}}</button>`,props : ['count'],//通过使用计算属性和方法数据更改computed: {changedChildCount() {return this.childCount;}},methods: {clickChildCount() {this.childCount++}}})//创建一个Vue对象//父组件const root = new Vue({el : '#root',data : {count : 5},components : {'html-a' : childComponent},});</script>
3.组件的 props 验证
1.之前
props选项通信采用的是数组方式,其实还有第二种方式:对象;2.通过对象模式进行传递数据,可以对数据类型进行验证,支持的类似有:
Sting.Number.Boolean.Function.Object.Array.Symbo
<div id="root"><student name="李四" sex="女" :age="18"></student></div><script>//去掉警告Vue.config.productionTip = false;//局部组件const childComponent = Vue.extend({//通过使用 data 数据更改data(){console.log(this)return{msg:'我是一个学生',myAge:this.age}},template : `<div><h1>{{msg}}</h1><h2>学生姓名:{{name}}</h2><h2>学生性别:{{sex}}</h2><h2>学生年龄:{{myAge+1}}</h2><button @click="updateAge">尝试修改收到的年龄</button></div>`,methods: {updateAge(){this.myAge++}},//简单声明介绍// props:['name','age','sex']//接收的同时对数据进行类型限制// props:{// name:String,// age:Number,// sex:String// }//接收的同时对数据进行类型限制props:{name:{type:String,//name的类型是字符串required:true,//name是必须要的},age:{type:Number,default:18//默认值},sex:{type:String,required:true}}})//父组件const root = new Vue({el : '#root',data : {count : 5},components : {'student' : childComponent},});</script>
五、组件的自定义事件
父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
- 使用
$on(eventName)监听事件- 使用
$emit(eventName)触发事件另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
<div id="root">{{message}}<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on)--><html-a v-on:child="parentFn"></html-a></div><script src="../js/vue.js"></script><script>//去掉警告Vue.config.productionTip = false;//子组件const childComponent = Vue.extend({data() {return {name : 'Mr.Lon'}},template : `<div><button v-on:click="childClick">点我把名字传给父组件</button></div>`,methods : {childClick() {//触发子组件实例身上的child事件this.$emit('child', this.name)}}})//父组件const root = new Vue({el : '#root',data : {message : 'Hello, Vue!'},components : {'html-a' : childComponent},//方法methods : {parentFn(name) {this.message = name;console.log('子组件传递给父组件!' + name);}}});</script>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号