组件使用的细节点
用js标签解决标签渲染中的小Bug
1. tbody、ol、ul、select标签内如何放置自定义组件?
- tbody里只能写tr,如果想要放入一个自己的自定义组件呢?该如何实现
- 同理,
ol
ul
里只能写li
,select
里只能写option
,该如何实现自定义组件呢?都可以按照如上方式用属性is
。
2. 子组件的data
在根组件里把data定义成一个对象不会有问题,但是在子组件里定义data,后面的值必须是函数,且返回一个对象,包含你所要的数据。
- 子组件不会像根组件一样只被调用一次,每一个子组件的数据都不应该跟其他组件数据产生冲突,这样可以让每个子组件都拥有自己独立的数据。
data: { return { number: 0; } }
3 通过ref引用来获取DOM节点
-
$ref
指的是JS中所有的引用。 -
$ref.hello
指找到一个叫做hello
的引用。
以计数器为案例,如何计算并显示两个计数器的和?
- 子组件值改变→触发一个事件告诉父组件
Vue中父子组件之间传值
-
父组件通过属性count的形式向子组件counter传值,子组件用props接收。子组件通过事件触发的形式向父组件传值。
-
单向数据流:父组件可以向子组件传递数据,但是子组件不能修改,如果非要修改,就拷贝一个副本修改这个副本。
组件中的参数校验与非Props特性
参数校验
父组件向子组件传递了内容,子组件有权对传入的数据进行约束,将原本值的数组形式
props:['content']
改为对象的形式props:{content:String}
当然也可以约束两个数据类型:
props: { content: [String, Number] }
- required=true表示参数必定要传入,假设不传入会默认为default值。
- validator约束传入属性数据的长度。
Props特性
- 父组件通过属性传递数据进来,子组件就能读取显示出来。
- 属性传递的内容是不会在DOM标签上显示出来的。
非Props特性
- 父组件向子组件传递一个属性,子组件并没有去接收。
- 非Props属性会展示在DOM标签的html属性里。
给组件绑定原生事件
- 监听内部组件向外触发的自定义事件。
- 监听原生事件
native
。
非父子组件之间的传值
光靠Vue是不行的
- Vuex
- 总线机制 发布订阅模式 观察者模式 Bus
兄弟节点,点击Dell的时候,下边的Lee也会变成Dell,相反如是。
- Vue 原型挂一个 Bus 的属性指向Vue实例,那么每个新创建的 Vue 实例都会有一个Bus 属性。
- this 作用域发生变化,先保存一下原来的 this。
- 注意子组件不能修改父组件传递的值,要拷贝一个副本。
<div id="root">
<child content="Dell"><child>
<child content="Lee"><child>
</div>
<script>
Vue.prototype.bus=new Vue()
Vue.component('child',{
data: function() {
return {
selfContent: this.content
}
}
},
props: {
content: String
},
template: `<div @click="handleClick">{{selfContent}}</div>`
methods: {
handleClick: function() {
this.bus.$emit('change',this.selfContent)
}
},
mounted: function() {
var this_ = this
this.bus.$on('change', function(msg) {
this_.content = msg
})
})
var vm = new Vue({
el:"#root"
})
</script>
在Vue中使用插槽
子组件除了展示p标签外,还要展示父组件传递过来的内容。 通过content传值并展示,必须在子组件模板里加一个div标签,且模板里只能有一个根标签,因此还要包裹。再加上如果传递的内容很多,代码太冗余。
<body>
<div id="root">
<child content='<p>Dell</p>'></child>
</div>
<script>
Vue.component('child', {
props:['content'],
template:`<div>
<p>hello</p>
<div v-html="this.content"></div>
</div>`
})
var vm = new Vue({
el:"#root"
})
</script>
</body>
如何优雅地传递?——插槽
<body>
<div id="root">
<child>
<h1>Dell</h1>
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<p>hello</p>
<slot>默认内容</slot>
</div>`
})
var vm = new Vue({
el:"#root"
})
</script>
</body>A
当外部没有传入的时候,slot显示默认值。
具名插槽
- 需求:body-content组件里,内容区域是自己的,header和footer是由外部传递进来的。
作用域插槽
-
子组件实现循环展示列表的功能。让外部决定如何循环。当子组件用slot的时候,会向slot里传递一个item数据。
-
父组件调用子组件的时候,给子组件传递了一个作用域插槽,作用域插槽是
<template></template>
形式的,且插槽要声明从子组件接收的数据都放在哪(props,slot-props="props"
),且要告诉子组件模板信息。
动态组件与v-once指令
- button 点击时,两个child做一个toggle,每次切换都要创建一个组件、销毁一个组件,代码写起来比较麻烦。
动态组件怎么编写?
component
会根据is里面数据的变化,自动加载不同的组件
v-once
- 上述方法是耗费性能的,如果加了v-once指令,就是把你创建的组件放到了内存里,再次切换到它的时候,直接从内存中读取就可以了。有效提高了一些静态内容的展示效率。