Vue3 学习笔记04-组件基础与单文件组件、props实现父传子

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用。

通常一个应用会以一棵嵌套的组件树的形式来组织:

 

 

 例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。

1 single-file components (单文件组件)

现在我们获得:

典型案例:

父组件:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3 + Vite" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';
export default{
  name:'App',
//注册组件 components:{ HelloWorld, } }
</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>

子组件:

<template>
  <h1>{{ msg }}</h1>

  <p>
    <a href="https://vitejs.dev/guide/features.html" target="_blank">
      Vite Documentation
    </a>
    |
    <a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
  </p>

  <button type="button" @click="state.count++">
    count is: {{ state.count }}
  </button>
  <p>
    Edit
    <code>components/HelloWorld.vue</code> to test hot module replacement.
  </p>
</template>

<script setup>
import { defineProps, reactive } from 'vue'

defineProps({
  msg: String
})

const state = reactive({ count: 0 })
</script>

<style scoped>
a {
  color: #42b983;
}
</style>

效果图:

2. props实现父传子的基础任务

prop一般用于父组件向子组件进行单向通信(父向子传值),传递的可以是字符串、也可以是表达式、也可以是一个对象,也可以是一个数组,甚至是一个布尔值。

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // 或任何其他构造函数
}

首先,在父组件的标签上定义属性,值就是要传递的数据。

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld title="Hello lucky"></HelloWorld>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';
export default{
  name:'App',
  components:{
    HelloWorld,
  }
}

</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>

然后,在子组件通过props属性接收传递过来的值。

<template>
  <h1>{{ title }}</h1>

  <p>
    <a href="https://vitejs.dev/guide/features.html" target="_blank">
      Vite Documentation
    </a>
    |
    <a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
  </p>


  <p>
    Edit
    <code>components/HelloWorld.vue</code> to test hot module replacement.
  </p>
</template>

<script>

export default{
  props:{
    title: String
  },
}

</script>

<style scoped>
a {
  color: #42b983;
}
</style>

效果图:

参考文献:https://quanyi.blog.csdn.net/article/details/94920082

3.props综合大案例

父组件:

<template>
  <HelloWorld 
        :pMsg='msg'
        :pExpression='msgExpA+msgExpB'
        :pObj='msgObj'
        :pObjMsg='msgObj.msg3'
        :pArray='msgArray'
        :pIsBoolean='isMsg'></HelloWorld>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';
export default{
  name:'App',
  components:{
    HelloWorld,
  },
  data () {
            return {
                title:'这是父组件',
                msg:'我是父组件单向传过来的数据',
                msgExpA:'props也可以是一个表达式:我是表达式A',
                msgExpB:',我是表达式B',
                msgObj:{
                    msg1:'props也可以是一个对象',
                    msg2:'另外,props也可以单传一个对象中的任一属性:',
                    msg3:'我是props对象中的属性msg3'
                },
                msgArray:[
                    {
                        id:1,
                        msg:'props也可以是一个数组',
                    },
                    {
                        id:2,
                        msg:'一般结合v-for来循环渲染',
                    },
                    {
                        id:3,
                        msg:'使用v-for时别忘了给key赋值哦~',
                    }
                ],
                isMsg:true
            }
          }
}


</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>

子组件:

<template>
    <h1>{{title}}</h1>
    <h1>{{pMsg}}</h1>
    <h1>{{pExpression}}</h1>
    <h1>{{pObj.msg1}}</h1>
    <h1>{{pObj.msg2}}</h1>
    <h1>{{pObjMsg}}</h1>
    <br/>
    <ul>
        <li v-for='item in pArray' :key='item.id'>
            <h1>{{item.msg}}</h1>
        </li>
    </ul>
    <h1>props也可以是布尔类型,一般结合v-if和v-else使用</h1>
    <h1 v-if='pIsBoolean'>当你看见我,说明pIsBoolean是true</h1>
    <h1 v-else>当你看见我,说明pIsBoolean是false</h1>
</template>

<script>

export default{
  props:['pMsg','pExpression','pObj','pObjMsg','pArray','pIsBoolean'],
        data () {
            return {
                title:'这是子组件'
            }
        }
}

</script>

<style scoped>
a {
  color: #42b983;
}
</style>

效果图:

参考文献:https://blog.csdn.net/gavincz/article/details/81038834

posted @ 2021-07-23 19:21  雨后观山色  阅读(537)  评论(0编辑  收藏  举报