组件化
将页面中公共部分拿出来封装起来的操作
1. data 必须是函数
<template>
<div class="home">
<Nav></Nav>
<Main></Main>
<Foter></Foter>
</div>
</template>
<script>
import Nav from '../components/Nav'
import Foter from '../components/Foter'
import Main from '../components/Main'
export default {
name: 'Home',
components: {
Nav,
Foter,
Main
},
data() {
return {
movies: [
{
id: 1,
title: "西游记",
year: "1997"
}
]
}
}
}
</script>
<style>
</style>
2. 父组件数据传递子组件(props)
从顶层组件将数据传递到子组件展示
父组件 Home.vue
<template>
<div class="home">
<Nav></Nav>
<!-- 向子组件传递movies参数的值,如果不适用 v-bind 子组件变量名 就会被解析成传递的是字符串 -->
<Main :movies="movies"></Main>
<Foter></Foter>
</div>
</template>
<script>
import Nav from '../components/Nav'
import Foter from '../components/Foter'
import Main from '../components/Main'
export default {
name: 'Home',
components: {
Nav,
Foter,
Main
},
data() {
return {
movies: [
{
id: 1,
title: "西游记",
year: "1997"
}
]
}
}
}
</script>
<style>
</style>
子组件 Main.vue
<template>
<div>
<p>{{movies.length}} Titles</p>
<slot></slot>
<ul class="movie-list">
<li v-for="movie in movies" :key="movie.id">
{{movie.title}} - {{movie.year}}
<span class="float-right">
<a class="imdb" :href="'https://www.imdb.com/find?q=' + movie.title" target="_blank"
title="Find this movie on IMDb">IMDb</a>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Main',
// movies 父组件在使用该组件时,需要使用 该 变量名= 的方式传递数据进来,(可以理解成将值赋值给movies这个变量)
//props: ['movies'] // 数组写法
// 对象写法,可以类型限制,设置默认值
props: {
// 对象或者数组是default 需要是个方法
movies: {
type: Array,
default() {
return []
}
}
}
}
</script>
<style>
</style>
3. 子组件数据传递给父组件(自定义事件)
从底层组件通过事件将必要条件传递给父组件,父组件对数据更新之后展示
子组件 Main.vue
<template>
<div>
<p>{{userInfo.length}} Titles</p>
<slot></slot>
<ul class="movie-list">
<li v-for="movie in userInfo" :key="movie.id">
{{movie.title}} - {{movie.year}}
<span class="float-right">
<a class="imdb" :href="'https://www.imdb.com/find?q=' + movie.title" target="_blank"
title="Find this movie on IMDb">IMDb</a>
<button @click="btnClick(movie)">点击我将把内容传递给父组件</button>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Main',
// props: ['movies'] // 数组写法
// 对象写法,可以类型限制,设置默认值
props: {
// 对象或者数组是default 需要是个方法
userInfo: {
type: Array,
default() {
return []
}
}
},
methods: {
btnClick: function (arg) {
// console.log(arg)
// 发射事件,给父组件, (事件名称, 参数), 事件名称推荐始终使用 kebab-case 的事件名。
this.$emit('item-click', arg)
}
}
}
</script>
<style>
</style>
父组件 Home.vue
<template>
<div class="home">
<Nav></Nav>
<!-- item-click 为子组件发送过来的方法名 mainClick 为父组件监听该事件的方法-->
<Main :userInfo="movies" @item-click="mainClick"></Main>
<Foter></Foter>
</div>
</template>
<script>
import Nav from '../components/Nav'
import Foter from '../components/Foter'
import Main from '../components/Main'
export default {
name: 'Home',
components: {
Nav,
Foter,
Main
},
data() {
return {
movies: [
{
id: 1,
title: "西游记",
year: "1997"
}
]
}
},
methods: {
// 该方法的作用打印 子组件传递的内容
mainClick: function (item) {
console.log(item)
}
}
}
</script>
<style>
</style>
4. 父组件访问子组件
父组件 Home.vue
<template>
<div class="home">
<Nav></Nav>
<!-- item-click 为子组件发送过来的方法名 mainClick 为父组件监听该事件的方法-->
<Main :userInfo="movies" @item-click="mainClick" ref="main"></Main>
<button @click="refLog">ref访问子组件</button>
<Foter ref="foter" ></Foter>
</div>
</template>
<script>
import Nav from '../components/Nav'
import Foter from '../components/Foter'
import Main from '../components/Main'
export default {
name: 'Home',
components: {
Nav,
Foter,
Main
},
data() {
return {
movies: [
{
id: 1,
title: "西游记",
year: "1997"
}
]
}
},
methods: {
// 该方法的作用打印 子组件传递的内容
mainClick: function (item) {
console.log(item)
},
// $refs 访问子组件, 需要在组件上加上 ref="变量名"
refLog: function () {
console.log(this.$refs)
}
}
}
</script>
<style>
</style>
5. 子组件访问父组件 对象
子组件 Main.vue
<template>
<div>
<p>{{userInfo.length}} Titles</p>
<slot></slot>
<ul class="movie-list">
<li v-for="movie in userInfo" :key="movie.id">
{{movie.title}} - {{movie.year}}
<span class="float-right">
<a class="imdb" :href="'https://www.imdb.com/find?q=' + movie.title" target="_blank"
title="Find this movie on IMDb">IMDb</a>
<button @click="btnClick(movie)">点击我将把内容传递给父组件</button>
<button @click="fater">访问父组件</button>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Main',
// props: ['movies'] // 数组写法
// 对象写法,可以类型限制,设置默认值
props: {
// 对象或者数组是default 需要是个方法
userInfo: {
type: Array,
default() {
return []
}
}
},
methods: {
btnClick: function (arg) {
// console.log(arg)
// 发射事件,给父组件, (事件名称, 参数), 事件名称推荐始终使用 kebab-case 的事件名。
this.$emit('item-click', arg)
},
fater: function () {
// 访问父组件
console.log(this.$parent)
}
}
}
</script>
<style>
</style>