vue组件化开发
-
将一个页面分割成若干个组件,一个页面js+css+html,将自己类容分割出来,方便开发,更好了维护我们的代码,每个组件封装自己的js+html+css,样式命名冲突
组件分类
-
页面级组件( 例如详情页页面)
-
基础组件(页面的一部分,例如轮播图)
-
组件的目的为了实现复用
指令和组件
-
在标签内增加的行内属性,实现功能指令
-
组件就是一个自定义(扩展)的标签<hello></hello>,封装代码的,组件的标签名不能破坏原有的html标签
组件:全局组件(不需要引用),局部组件(需要引用)
-
在vue中一个对象就是一个组件
-
在组件中data是一个函数,目的是不受别人干扰,因为组件是独立的
-
使用组件的步骤,
-
1.声明组件,并且引入到当前页面
-
2.在组件的父级模板中调用这个组件
-
组件名称不能和标签相同
-
-
全局组件
-
Vue.component('my-handsone',{ //template只会有一个根元素,而且不能直接放置文本节点 template:'<h1>{{msg}}</a></h1>', data(){ return { //可以用来定义数据 msg:"帅吗", types:[1,2,3] } } }); let vm=new Vue({ el:"#app", data:{} })
- 局部组件
-
先在儿子组件上绑定一个属性名,然后赋值给这个属性 :m="msg",
-
儿子接受父亲传递的数据,用props接收传递的属性名字,例如 props:{m:{type:Array}}
-
-
//一个对象就是一个组件 let webeautiful={ template:'<h1>{{msg}}</h1>', data(){ return { msg:"很帅呀" } } }; let vm=new Vue({ el:"#app", //挂载在vue实例中components components:{ webeautiful } })
组件的数据传递
-
父传子属性传递 子组件通过props接收
-
props的api
-
type 接收数据的类型
-
default 默认数据的值
-
required 必须传递数据 不能和default同时引用
-
validator 自定义验证
-
-
子传父组件,事件触发 $emit->@方法="父组件的方法"
-
平级交互 eventBus 但是不用 -vuex
-
父组件调用子类的方法 ref=>this.$ref.xxx.子类方法
-
slot 插槽 (设置一些空闲的位置等等使用)
父亲传递给儿子数据
-
let vm = new Vue({ el:'#app', template:'<div>父{{msg}}<child :a.sync="msg"/></div>', data:{ msg:'美女' }, components:{ child:{ props:['a'], //<comp :foo="bar" @update:foo="val => bar = val"></comp> template:'<div>child {{a}} <button @click="change">换</button></div>', methods:{ change(){ //固定的写法 //2.3.0版本以后才会用 //用了sync,下面必须用update this.$emit('update:a','丑女'); } } } } })
父亲调用子组件的一些方法
第一步先定义儿子有一个fn方法
methods:{fn(){ console.log("王阿姨好漂亮"); }}
第二步在儿子身上标记一个表示ref
<child ref="msg"></child>
第三步父亲在视图加载完成后,调用儿子的fn方法
mounted(){this.$refs.msg.fn();}
this.$refs.msg 调用儿子身上的msg表示,这时候this.$refs.msg指向的就是儿子的实例
实例.fn() 这就调用到了儿子的fn方法
-
// ref如果写在dom上,表示获取dom,如果写在组件上,表示当前组件的实例 let vm=new Vue({ el:"#app", template:'<child ref="c"></child>', //一定要放在mounted下面,因为mounted方法表示数据和视图渲染完成, mounted(){ //当前的ref指向的是child组件的实例,通过实例调用下面的fn方法 this.$refs.c.fn(); }, components:{ child:{ template:'<div>child</div>', methods:{ fn(){ alert("王阿姨好漂亮") } } } } })
兄弟组件之间的数据通讯(就是平级组件之间的数据通讯)
-
兄弟组件之间数据互通,要借助第三个vue实例
-
eventBus使用起来不好管理,命名冲突,而且复杂,一般不用
-
我们通常叫这个实例叫eventBus
-
let eventBus=new Vue;
-
-
将兄弟发射的自定义事件方法,挂载到eventBus实例上
-
eventBus.$emit('aa',''c');
-
-
然后通过$on方法,将兄弟发射的自定义事件方法绑定里面去
-
后面的回调函数一定要是箭头函数,不改变实例的this,方便赋值
-
例如 eventBus.$on('aa',(data)=>{console.log(data) }
let eventBus=new Vue; //eventBus使用起来不好管理,命名冲突,而且复杂,一般不用 let C={ template:'<div>{{val}}<button @click="ss">变C</button></div>', data(){ return { val:"C" } }, methods:{ ss(){ eventBus.$emit('bb','C'); } }, created(){ // eventBus.$on('aa',(data)=>{ this.val=data; }) } }; let D={ template:'<div>{{val}}<button @click="ee">变D</button></div>', data(){ return { val:"D" } }, created(){ // eventBus.$on("bb",(data)=>{ this.val=data; }) }, methods:{ ee(){ // eventBus.$emit('aa','D'); } } } let vm = new Vue({ el:'#app', //1,找共同父级,时间交互,非常复杂,不采用 template:'<div><C></C><D></D></div>', data:{ }, components:{ C, D } })
使用 slot 分发内容
slot 可以将不同的标签分开发送到指定的节点中
slot 有一个name属性
slot上的name属性,有一个默认值default
没有指定slot名字的都叫default 会塞到name=default的组件内
<div id="app"> <hello> 123 <ul slot="bottom"> <li>我很帅</li> </ul> <ul slot="top"> <li>你丑</li> </ul> 456 </hello> </div> <template id="hello"> <div> <!--slot是vue提供的内置插件,具名slot 在写内容时第一预留出来slot插口,如果没有使用则使用默认内容,没有指定slot名字的都叫default 会塞到name=default的组件内--> <slot name="default">nihao </slot> <slot name="top">这是上</slot> <slot name="bottom">这是下</slot> </div> </template> <script> let vm = new Vue({ el:'#app', components:{ hello:{ template:'#hello' } } }) </script>
vue动画组件 transition
-
transition有一个name属性
-
假设我们name="fade"
-
-
transition动画组件对应三个css样式
-
进入开始 .fade-enter 的样式
-
开始过渡阶段 .fade-enter-active
-
出去终点 .fade-leave-active
-
这三个样式里面,我们可以任意写样式
-
-
-