vue-基础5——组件
组件的注册
https://cn.vuejs.org/v2/guide/components-registration.html
<body>
<div id="box">
<navbar></navbar>
</div>
<script type="text/javascript">
// vue 组件 :扩展html元素
//组件是一个孤岛,无法(直接)访问到外部的 data,methods.......
//将来可以通过通信方式来进行沟通
//全局组件定义方式
Vue.component("navbar",{
template:`
<div>
<nav style="background:yellow;">
<button @click="handleClick()">返回</button>
<navbarchild1></navbarchild1> //全局注册的子组件
<navbarchild2></navbarchild2> //局部注册的子组件
<ul>
<li>11111</li>
<li>22222</li>
</ul>
{{myname}}
</nav>
<div>最外层必须有root element</div>
</div>
`,
components:{
//局部定义组件
navbarchild2:{
// data(){}
watch: {},
template:`<div style="background:blue;">我是局部定义的,其他人休想得到我</div>`
}
},
methods: {
handleClick(){
console.log("返回功能")
}
},
//组件中 data必须是一个方法, return 返回对象
//保证data不会相互影响
data(){
return {
myname:"我是导航栏",
}
}
})
//全局定义的
Vue.component("navbarchild1",{
template:`
<div style="background:red;">
1.不要吐槽此时的组件,我虽然没有高亮,虽然没有代码提示,
但是这个时间,能用上我,也是一种好的选择
2.样式这个时候只能先写行内样式
3.之后单文件组件 都会解决这些问题。
</div>
`
})
new Vue({
el:"#box",
methods: {
},
watch: {
},
computed: {
},
})
</script>
</body>
组件编写方式与Vue实例的区别
*自定义组件需要有一个root element
*父子组件的data是无法共享
*组件可以有data,methods,computed....,但是data 必须是一个函数
组件通信
(1)父传子
父传子的方式非常简单,在父组件上绑定一个属性,在子组件上用props接受就可以了
<body>
<div id="box">
<!-- 首页中引入的 -->
<navbar mytitle="home" :myshow="false" :mytext="text"></navbar>
<!-- 列表页面引入的 -->
<navbar mytitle="list" :myshow="true" :mytext="text"></navbar>
<!-- 购物车页面引入的 -->
<navbar mytitle="shopcar" :myshow="true" :mytext="text"></navbar>
</div>
<script>
//home
Vue.component("navbar",{
template:`
<nav>
<button v-if="myshow">返回</button>
<span>我是导航--{{mytitle}}-{{mytext}}</span>
<button v-show="myshow">主页</button>
</nav>
`,
//接受父组件传来的属性 mytitle myshow
// props:["mytitle","myshow"]
//属性验证
props :{
mytext:String,
mytitle:String,
myshow:Boolean //接受的myshow必须是boolean类型 Array Number
}
})
// root compoennt
new Vue({
el:"#box",
data:{
text:"我是在父组件中定义"
}
})
</script>
</body>
(2)子传父
子串父的实现方式是在父子身上绑定一个函数,在触发子组件身上的函数时,调起父组件的函数并为其传数据
<body>
<div id="box">
<my-child @kerwinevent1="handleEvent1" @kerwinevent2="handleEvent2"></my-child>
<!-- <myChild></myChild> -->
</div>
<script>
Vue.component("myChild",{
template:`
<div>
child-<button @click="handleClick()">click</button>
</div>
`,
data(){
return {
text:"child定义的状态"
}
},
methods: {
handleClick(){
//把text状态传到父组件中
//触发,分发
this.$emit("kerwinevent2",100000)
this.$emit("kerwinevent1",this.text)
}
},
})
//root component
new Vue({
el:"#box",
data:{
},
methods:{
handleEvent1(data){
console.log("收到钱了-11111",data)
},
handleEvent2(data){
console.log("收到钱了-22222",data)
}
}
})
</script>
</body>
(3)ref
ref放在标签上, 拿到的是原生节点
ref放在组件上, 拿到的是组件对象,通信功能
<body>
<div id="box">
<input type="text" ref="mytext"/>
<button @click="handleClick()">click</button>
<child ref="mychild"></child>
</div>
<script type="text/javascript">
Vue.component("child",{
data(){
return {
childtext:"child定义的"
}
},
template:`<div>
child -{{childtext}}
</div>`
})
//子组件
new Vue({
el:"#box",
methods: {
handleClick(){
console.log(this.$refs.mychild.childtext)
this.$refs.mychild.childtext= "22222222222"
}
},
})
</script>
</body>
(4)中央事件总线-bus
<body>
<div id="box">
<child1></child1>
<child2></child2>
</div>
<script type="text/javascript">
//中央事件总线
var bus = new Vue() //中央事件总线 bus.$on bus.$emit
Vue.component("child1",{
template:`
<div>
child1-<button @click="handleClick()">click</button>
</div>
`,
methods: {
handleClick(){
//
bus.$emit("kerwinevent","来自child1的问候")
console.log("emit触发bus事件")
}
},
})
Vue.component("child2",{
template:`
<div>
child2
</div>
`,
mounted() {
console.log("自动被调用, 等child上树就会被执行 立即监听事件")
bus.$on("kerwinevent",(data)=>{
console.log("child2函数被执行",data)
})
},
})
var vm = new Vue({
el:"#box",
methods: {
},
})
</script>
</body>
动态组件
https://cn.vuejs.org/v2/guide/components.html#%E5%8A%A8%E6%80%81%E7%BB%84%E4%BB%B6
<body>
<div id="box">
<keep-alive>
<component :is="type"></component>
</keep-alive>
<footer>
<ul>
<li @click="type='home'">首页</li>
<li @click="type='list'">列表</li>
<li @click="type='shopcar'">购物车</li>
</ul>
</footer>
</div>
<script type="text/javascript">
Vue.component("home",{
template:`<div>
home -<input type="text"/>
</div>`
})
Vue.component("list",{
template:`<div>
list
</div>`
})
Vue.component("shopcar",{
template:`<div>
shopcar
</div>`
})
new Vue({
el:"#box",
data:{
type:"home"
}
})
</script>
</body>
浙公网安备 33010602011771号