上篇我们已经详细介绍Vue组件化入门详解中提到过,我们创建的组件在src文件夹下的component文件中。我们知道前段界面由html,css,js组成,与之相似,Vue组件话由template(模板)、script(脚本)、style(样式)组成。
-
template里面写我们需要的模板,但所有写的标签都要用一个仅且只有一个容器存放
-
script 里面存放我们定义的变量以方法,值得注意的是,在Vue中定义存放变量的data容器可以直接用花括号{}包裹起来,但是在组件化中,会报错,因为会造成传址问题,所以Data里面的变量需要放在一个函数里面。
-
style与前端界面一样,设置元素的样式,只是比之前的style 多了一个scoped,带有scoped标明在该style标签里面设置的样式,只会在该文件下有效,即不会对其他文件造成影响。
<template>
<div>
<h1>我是MyCompontent里面的内容</h1>
{{ message }}
</div>
</template>
<script>
export default {
name: "my-compontent",
data:function () {
return{
message:"这是MyComponent里面的测试数据"
}
}
}
</script>
<style scoped>
</style>
在主入口App.vue中,我们需要将上述组件化的Vue导入进来。导入当然要在script中导入
import MyCompontent from '@/components/MyCompontent'
然后在component组建中加入导入的文件名称,之后在模板template中定义的仅且只有一个容器中引用。注意,可以是单标签引用,也可以是双标签引用。两者没有什么区别,只是双标签可以利用插槽传数据
父级往子级传递数据
- 通过属性传参
重新创建一个Person.vue组件
在父级template中将Person文件引入进来,并在div中编写
<person
username="张三"
:height="183"
color="黄色"
></person>
<person
username="李四"
:height="186"
color="黑色"
></person>
在Person标签中添加属性,类似于我们在div中编写行间样式一样。height前面加上: 表示变成动态属性。
由于组件实例的作用域是独立的,这意味着在子组件的模板中不能直接引用父组件的数据,而要子组件使用父组件的数据,我们需要通过子组件的props选项
而props可以直接定义为
props:['username','sex','height'],
也可以类似于Schema定义方式,这样定义类型之后,由于我们在父组件中的height是动态属性,即会根据子组件中的类型进行匹配,所以此时传过来的height数Number类型的值
获取到父组件传过来的数据后,就可以直接在页面中直接使用
props:{
username:{type:String},
sex:{type:String},
height:{type:Number}
}
- 使用插槽方法
这种方法可以直接引用公共部分,如引用公共部分的头部,尾部等
新建一个mySlot组件
在父组件中引用该组件,并在div中编写
<my-slot>
<!--具名插槽-->
<p slot="header">我是头部</p>
<p slot="footer">我是底部</p>
<p>我是插槽里的内容</p>
</my-slot>
在mySlot文件中的div接收从父组件传递过来的数据,用slot标签,而且使用header 、 footer文件时,需要早mySlot 加上name属性
<template>
<div>
<!--这里的标签必须用slot-->
<!--这里引用header footer的时候 用name属性引用-->
<slot name="header"></slot>
<slot>这里是Slot里面的数据</slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {
name: "my-slot"
}
</script>
<style scoped>
</style>
<template>
<div>
<p>姓名是:{{username}}</p>
<p>年龄是:{{sex}}</p>
<p>身高是:{{height}}</p>
</div>
</template>
<script>
export default {
name: "person",
// props:['username','sex','height'],
props:{
username:{type:String},
sex:{type:String},
height:{type:String}
}
}
</script>
<style scoped>
</style>
<template>
<div id="app">
<!--<img src="./assets/logo.png">-->
<!--<HelloWorld/>-->
<!--<MyCompontent></MyCompontent>-->
<!--<Person-->
<!--username="DR"-->
<!--sex="1"-->
<!--height="168xm"-->
<!--></Person>-->
<!--<Person-->
<!--username="RR"-->
<!--sex="2"-->
<!--height="168cm"-->
<!--></Person>-->
<!--<my-slot>-->
<!--<p>这是App里面的mySlot数据1</p>-->
<!--<p slot="header">这是头部</p>-->
<!--<p slot="footer">这是尾部</p>-->
<!--</my-slot>-->
<!--@myfn 是自己传过来的事件-->
<!--fn 是父级接受子级传递过来的数据存放的地址-->
<!--<Emit @myfn="fn"></Emit>-->
<Transition></Transition>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
import MyCompontent from '@/components/MyCompontent'
import Person from '@/components/Person'
import mySlot from '@/components/mySlot'
import Emit from '@/components/Emit'
import Transition from '@/components/Transition'
export default {
name: 'App',
components: {
HelloWorld,
MyCompontent,
Person,
mySlot,
Emit,
Transition,
},
methods:{
//mydata是从父级传递过来的事件、参数
fn:function (mydata) {
console.log(mydata)
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
网友评论