目录
vue组件
组件系统可以让我们独立的复用小组件来构建大型应用,几乎任何类型的应用界面都可以抽象为一个组件树
前言
- 组件生效于vue的挂载区内,不管是全局还是局部
- 自定义组件的内部不可以写内容,除非你用插槽
- 组件内部,只能有一个根元素
- 组件也可以直接写成自闭标签,但是这样写,那么后面的组件便不再生效
- 决定组件是块级元素还是行级元素与里面的根标签有关
全局组件
含义:所有vue的实例都可以使用的组件
语法:Vue.component(tagName,options)
属性:
- tagName:组件名,其为一个字符串
- options:组件对象(组件对象的value值类型为字符串)
<body>
<div id="a">
<home></home><!-- 组件的使用 -->
</div>
<div id="b">
<home></home>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component('home',{template:"<h1>home</h1>"})/* value为组件内部,只能有一个根元素 */
new Vue({
el:"#a",
})
new Vue({
el:"#b"
})
</script>
组件给组件传值
全局组件内部props属性,里面传一个数组,用来接收组件的变量 ,用于给自定义组件内部传值
<body>
<div id="app">
<home v-for="(item,index) in items" v-bind:study="item" :dex="index"></home>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component("home",{
props:["study","dex"],/* 该属性用于组件内部传值 */
template:"<li>{{study}}——{{dex}}</li>"
})
new Vue({
el:"#app",
data() {
return {
items:["java","前端","linux"]
}
},
})
</script>
组件通信
触发自定义事件:this.$emit("事件名称",参数信息)
<body>
<div id="app">
<home v-for="(item,index) in msg" :item="item" :index="index" v-on:remove="removeMsg(index)"></home><!-- vue对象的内容渲染到组件 -->
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component("home",{
props:['item','index'],//向组件中传值
template:'<li>{{index}}--{{item}}<button @click="remove()">删除</button></li>',
methods: {
//点击button按钮。触发remove事件
remove:function(index){
this.$emit("remove",index)//自定义事件
}
},//注意:组件内部也可以写方法
})
var vm=new Vue({
el:"#app",
data() {
return {
msg:["lala","lili","lan"]
}
},
methods:{
removeMsg:function(index){
this.msg.splice(index,1);//一次删除一个元素
}
}
})
</script>
注意:全局组件定义一定要放到所有vue对象的前面才可对所有vue对象生效
局部组件
含义:只能在特定vue对象挂载区内使用的组件
属性components:组件对象
<body>
<div id="app">
<home></home>
<help></help>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el:"#app",
// 下面的组件只能用在id为app的挂载区
components:{
home:{template:"<h1>home</h1>"},
help:{template:"<p>help</p>"}
}
})
</script>
template标签
<body>
<div id="app">
<!-- template标签本身就是一个根元素 -->
<template>
<div>我是内容一</div>
<div>我是内容二</div>
</template>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el:"#app",
})
</script>
注意:
- template标签只能用在vue挂载区内才可显示组件里面的内容
- 组件是组件,不是标签,不可以通过标签名选择器来修改样式,但是可以在组件中设置id通过id选择器来设置样式
- 用template标签以及内部内容共同构成一个组件,为匿名组件
- template标签组成的匿名组件是一种全局组件,其只要放到有vue挂载的地方就能用
为匿名组件赋予名称
具体做法:为template标签设置一个id属性,在组件中通过选择器的方式进行引入
<body>
<template id="a">
<div>home</div>
</template>
<template id="b">
<div>help</div>
</template>
<template id="c">
<div>add</div>
</template>
<!-- 上面的匿名组件我不想让她显示在vue渲染区 -->
<div id="app">
<home></home>
<help></help>
<add></add>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
var add={template:"#c"}
new Vue({
el:"#app",
components:{
home:{template:"#a"},
help:{template:"#b"},
add
}
})
</script>
vue插槽
前言
插槽标签:<slot></slot>
vue插槽作用
- 父组件向子组件传递内容
- 扩展、复用、定制组件
vue插槽类型
- 默认插槽
- 命名插槽
- 作用域插槽
注意:
- vue的自定义组件内部不可以写内容,如果写了内容则不会生效,但是当组件内部定义了<slot></slot>后slot内部就可以写内容了,甚至可以写标签(也可以解析)
- 组件内部定义了几个插槽,那么组件内部书写的内容便会显示几次(理解:插槽只能有1个就是自定义组件的书写区域,如果定义了多个插槽,那么就会多次显示这个区域书写的内容)
- 插槽里的内容为默认值,如果自定义的组件写内容了,那么默认值将会被覆盖
默认插槽
含义:没有名字的插槽
<body>
<div id="app">
<home><h1>一条狗</h1></home><!-- 可以显示里面的内容了甚至连标签都可以解析 -->
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component("home",{template:"<div>我是<slot>个大神</slot><slot></slot><div>"})/* 如果上面的自定义组件没有书写内容则会使用插槽里的默认值 */
new Vue({
el:"#app",
})
</script>
具名插槽
含义:具有名字的插槽
具名插槽的使用
子组件内部加:
<template v-slot:a>
插槽中你想写的内容
</template>
注意:上面的v-slot:a可以写成#a
注意:如果组件内部定义了具名插槽而没有定义默认插槽的话,那么自定义组件内部仍然不可以写内容
<body>
<div id="app">
<home>只会显示默认值</home>
<home>
<template v-slot:a>
插槽中你想写的内容
</template>
</home><!-- 可以显示里面的内容了甚至连标签都可以解析 -->
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component("home",{template:"<div>我是<slot name='a'>个大神</slot><div>"})
new Vue({
el:"#app",
})
</script>
具名插槽的其他使用方式
<home slot="home"></home>:标识将此组件插入名字为home的插槽
<body>
<div id="app">
<all>
<home slot="home"></home>
<help slot="help"></help>
</all>
</div>
</body>
<script src="./lib/vue.js"></script>
<script>
Vue.component("all",{template:"<div>槽1<slot name='home'></slot>槽2<slot name='help'></slot></div>"})
Vue.component("home",{template:"<div>home</div>"})
Vue.component("help",{template:"<div>help</div>"})
new Vue({
el:'#app'
})
</script>
理解:all组件空出两个具名插槽,home和help组件分别作为具名插槽填入all
作用域插槽
作用:子组件向父组件传递内容
使用:创建vue项目
父组件内部
<!-- 父组件App.vue -->
<template>
<div>
<HelloWorld v-slot:default="slotprops">
{{slotprops.me}}
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
子组件内部
<!-- 子组件HelloWorld内 -->
<template>
<div class="hello">
<slot :me="name"></slot>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
name:"lili"
}
},
}
</script>
理解:
- name的值被me(名字随意起)保存,me的值在slotprops(随意起的名字)中。
- v-slot:接插槽名字;default表示默认插槽