组件(component),vue.js最强大的功能之一
注:每个组件都是Vue的实例对象
通过Vue的静态方法(component)定义,全可在所有组件中使用。语法如下:
<div id="app"> <!-- 使用组件 --> <my-header></my-header> </div> <script type="text/javascript"> //定义全局组件 Vue.component("my-header",{ template:"<div>我是全局组件</div>" }) let app = new Vue({ el:"#app" }) </script>
在父组件的 components 属性中定义。
组件模板中,必有一个根元素,不能直接写h1、p、span、a等内容
注册组件,组件在哪里使用,就注册到哪里
定义组件时用的驼峰法,使用时将驼峰法转换为帕斯卡命名
<div id="app"> <!-- 4.使用组件 --> <my-header></my-header> </div> <!-- 2.定义组件模板 --> <template id="my-header"> <div> <h3>我是头部局部组件</h3> <p>{{name}}</p> </div> </template> <script type="text/javascript"> //1.定义局部组件 let MyHeader = { template:'#my-header',//组件的模板,#my-header指id为my-header的模板 data(){ return { name:"局部组件"//数据项 } } } let app = new Vue({ el:"#app", //3.注册组件 components:{ MyHeader//将MyHeader 这个组件注册到app根组件中 } }) </script>
组件对象的template属性用来设置组件的模板内容,模板内容有3种写法:
<div id="app"> <my-header></my-header> </div> <script type="text/javascript"> let MyHeader = { template:'<div><h1>我是头部局部组件:{{name}}</h1></div>', data(){ return { name:"局部组件" } } } let app = new Vue({ el:"#app", components:{ MyHeader } }) </script>
<div id="app"> <my-header></my-header> </div> <script type="text/x-template" id="my-header"> <div> <h3>我是头部局部组件</h3> <p>{{name}}</p> </div> </script> <script type="text/javascript"> let MyHeader = { template:'#my-header', data(){ return { name:"局部组件" } } } let app = new Vue({ el:"#app", components:{ MyHeader } }) </script>
组件实例是孤立的,不可在子组件中直接用父组件中的数据(组件特性:高内聚、低耦合)
父组件通过 props 向下传递数据,子组件通过 emit 向上发射事件传递数据
先在父组件中定义数据
在父组件的模板中,通过属性绑定把数据绑定在子组件上,语法:子组件 :变量名=”数据项”
在子组件中定义props属性,用来接收父组件传递的数据
在子组件模板中使用数据
在子组件的函数中使用数据
<div id="app"> {{number}} <!-- 2. 把数据绑定在子组件上 --> <my-collapse :num="number"></my-collapse> </div> <template id="my-collapse"> <div> <!-- 4. 在子组件中使用数据 --> <p>{{num}}</p> <p>{{Say()}}</p> </div> </template> <script type="text/javascript"> let MyCollapse = { template:'#my-collapse', props:{ //3. 接受父组件传递的数据,Numder类型约束,表示传递过来的数值类型 num:{ type:Number, default:0, required:true } }, methods:{ //5. 在子组件的函数中使用数据 Say(){ console.log(this.num) } } } let app = new Vue({ el:"#app", data:{ //1. 定义父组件的数据项 number:1000 }, components:{ MyCollapse } }) </script>
注:子组件上的事件名@addmsg不能使用驼峰法
<div id="app"> <p>{{content}}</p> <!-- 3. 在父组件中接收子组件发射过来的事件 --> <my-collapse @addmsg="receive"></my-collapse> </div> <template id="my-collapse"> <div> <input v-model="msg" type="" name=""> <!-- 2. 在子组件中添加事件监听 --> <button @click="sendMsg">按钮</button> </div> </template> <script type="text/javascript"> let MyCollapse = { template:'#my-collapse', data(){ return { msg:'' } }, methods:{ //1.从子组件向父组件发射事件,参数1:事件名;参数2:传递的数据 sendMsg(){ this.$emit("addmsg",this.msg) } } } let app = new Vue({ el:"#app", data:{ content:'' }, components:{ MyCollapse }, methods:{ //4. 在父组件中定义方法接收子组件传递的事件及数据,参数是子组件传递的数据 receive(d){ return this.content=d } } }) </script>
插槽,即一个占位符,能在不同环境下,传递不同的参数,并得到不同的效果,在Vue中通过slot标签实现
思路:先在子组件中定义一个占位符(插槽),再使用真实的内容替换这个插槽
当子组件模板只有一个无属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的DOM位置,并替换掉插槽本身
<div id="app"> <son> <h3>只是标题</h3> <p>这是段落</p> </son> </div> <template id="son"> <div> <slot></slot> </div> </template> <script type="text/javascript"> let Son = { template:'#son' } let app = new Vue({ el:'#app', components:{ Son } }) </script>
若有多个插槽(占位符),通过name属性加以区分,这种插槽就是具名插槽(可更灵活的管理组件的内容)
<div id="app"> <son> <h3 slot="title">这是标题</h3> <p slot="content">这是段落</p> </son> </div> <template id="son"> <div> <slot name="title"></slot> <slot name="content"></slot> </div> </template>
通过 new Vue() 获得一个对象,即 Vue实例,Vue实例提供如下属性、方法:
<div id="app"></div> <script type="text/javascript"> let app = new Vue({ el:'#app', data:{ name:"David", age:20 } }) console.log(app.$el); console.log(app.$data); </script>
$refs,获取对DOM元素的引用
Vue 侧重于数据驱动,而jQuery侧重于dom,Vue提供了 $refs 属性对dom元素进行灵活的操作,具体使用:
<div id="app"> <a href="" ref="oa">超链接</a> <button @click="setStyle">点击切换</button> </div> <script type="text/javascript"> let app = new Vue({ el:"#app", methods:{ setStyle(){ //找到DOM节点 console.log(this.$refs) console.log(this.$refs.oa) this.$refs.oa.style.textDecoration='none' this.$refs.oa.style.color='red' } } }) </script>
<div id="app"> {{name}} </div> <script type="text/javascript"> let app = new Vue({ el:"#app", data:{ name:"David" } }) app.$mount('#app') </script>
将所有的异步操作,都写在watch里面进行实现
<div id="app"> 出生年月: <input v-model="birthday" type="" name=""><br> 年龄:<p>{{age}}</p> </div> <script type="text/javascript"> let app = new Vue({ el:'#app', data:{ birthday:'', age:0 }, watch:{ birthday(){ setTimeout(()=>{ this.age = new Date().getFullYear()-new Date(this.birthday).getFullYear(); },3000) } } }) </script>
实例化的Vue对象(根组件)以及自定义的组件对象都有生命周期,Vue 设计者为方便调试程序,提供了8个钩子函数:
<div id="app"> {{name}} </div> <script type="text/javascript"> let app = new Vue({ data:{ name:'David' }, beforeCreate(){ alert('beforeCreate') }, created(){ alert('created') }, beforeMount(){ alert('beforeMount') }, mounted(){ alert('mounted') }, beforeUpdate(){ alert('beforeUpdate') }, updated(){ alert('updated') }, beforeDestory(){ alert('beforeDestory') }, destroyed(){ alert('destroyed') } }) app.$mount('#app') app.$destroy('name') </script>
生命周期函数作用:在不同的阶段,做相应的工作
可定义多个组件,再使用 :is 属性动态地在多个组件之间切换
语法:<component v-bind:is=”组件名”></component>
Component 相当于一个占位符,具体显示哪个组件,通过:is指定
<div id="app"> <span @click="currentCom='FirstCom'">第一个</span> <span @click="currentCom='SecondCom'">第二个</span> <component :is="currentCom"></component> </div> <template id="com1"> <div>第一个组件</div> </template> <template id="com2"> <div>第二个组件</div> </template> <script type="text/javascript"> let FirstCom={ template:'#com1', mounted(){ console.log("第一个被渲染") } } let SecondCom={ template:'#com2', mounted(){ console.log("第二个被渲染") } } let app = new Vue({ el:"#app", data:{ currentCom:'' }, components:{ FirstCom, SecondCom } }) </script>
无 keep-alive 组件时,每次切换组件都重新创建一次组件,使用 keep-alive后,会将创建过的组件保存在内存中,以后使用时直接使用,而不会每次重新创建
<div id="app"> <span @click="currentCom='FirstCom'">第一个</span> <span @click="currentCom='SecondCom'">第二个</span> <keep-alive> <component :is="currentCom"></component> </keep-alive> </div> <template id="com1"> <div>第一个组件</div> </template> <template id="com2"> <div>第二个组件</div> </template> <script type="text/javascript"> let FirstCom={ template:'#com1', mounted(){ console.log("第一个被渲染") } } let SecondCom={ template:'#com2', mounted(){ console.log("第二个被渲染") } } let app = new Vue({ el:"#app", data:{ currentCom:'' }, components:{ FirstCom, SecondCom } }) </script>
如对本文有疑问, 点击进行留言回复!!
同事牛逼啊,写了个隐藏 bug,我排查了 3 天才解决问题!
【JavaScript笔记(一)】万丈高楼平地起 - 基本概念篇
轻松解决 org.apache.taglibs.standard.tlv.JstlCoreTLV 困惑
网友评论