Vue单文件组件的使用

7. 单文件组件的使用

组件有两种:普通组件、单文件组件

普通组件的缺点:

  1. html代码是作为js的字符串进行编写,所以组装和开发的时候不易理解,而且没有高亮效果。
  2. 普通组件用在小项目中非常合适,但是复杂的大项目中,如果把更多的组件放在html文件中,那么维护成本就会变得非常昂贵。
  3. 普通组件只是整合了js和html,但是css代码被剥离出去了。使用的时候的时候不好处理。

将一个组件相关的html结构,css样式,以及交互的JavaScript代码从html文件中剥离出来,合成一个文件,这种文件就是单文件组件,相当于一个组件具有了结构、表现和行为的完整功能,方便组件之间随意组合以及组件的重用,这种文件的扩展名为“.vue”,比如:"Home.vue"。

  1. 创建组件

1552362045478

在组件中编辑三个标签,编写视图、vm对象和css样式代码。

7.1 template 编写html代码的地方

<template>
  <div id="Home">
    <span @click="num--" class="sub">-</span>
    <input type="text" size="1" v-model="num">
    <span @click="num++" class="add">+</span>
  </div>
</template>

7.2 script编写vue.js代码

<script>
  export default {
    name:"Home",
    data: function(){
      return {
        num:0,
      }
    }
  }
</script>

7.3 style编写当前组件的样式代码

<style scoped>
  .sub,.add{
    border: 1px solid red;
    padding: 4px 7px;
  }
</style>

7.4 完成案例-点击加减数字

创建Homes.vue

<template>
  <div class="add_num">
      <span @click="num++">+</span>
      <input type="text" size="2" v-model="num">
      <span @click="num--">-</span>
  </div>
</template>

<script>
  export default{
    name:"AddNum",
    data: function(){
      return {
        num: 0,
      }
    }
  }
</script>

<style scoped>
   .add_num{
      font-size: 32px;
   }
</style>

在App.vue组件中调用上面的组件

<template>
  <div id="Home">
    <span @click="num--" class="sub">-</span>
    <input type="text" size="1" v-model="num">
    <span @click="num++" class="add">+</span>
  </div>
</template>


<script>
  export default {
    name:"Home",
    data: function(){
      return {
        num:0,
      }
    }
  }
</script>

<style scoped>
  .sub,.add{
    border: 1px solid red;
    padding: 4px 7px;
  }
</style>

在开发vue项目之前,需要手动把 App.vue的HelloWorld组件代码以及默认的css样式,清楚。

上面的代码效果:

1552362182984

7.4 组件的嵌套

有时候开发vue项目时,页面也可以算是一个大组件,同时页面也可以分成多个子组件.

因为,产生了父组件调用子组件的情况.

例如,我们可以声明一个组件,作为父组件

在components/创建一个保存子组件的目录HomeSon

1552363669256

在HomeSon目录下,可以创建当前页面的子组件,例如,是Menu.vue

//  组件中代码必须写在同一个标签中
<template>
    <div id="menu">
      <span>{{msg}}</span>
      <div>hello</div>
  </div>
</template>

<script>
  export default {
    name:"Menu",
    data: function(){
      return {
        msg:"这是Menu组件里面的菜单",
      }
    }
  }
</script>

然后,在父组件中调用上面声明的子组件。

1552363770013

最后,父组件被App.vue调用.就可以看到页面效果.

1552363834171

1552363849977

效果:

1552363702858

7.5 传递数据

父组件的数据传递给子组件

例如,我们希望把父组件的数据传递给子组件.

可以通过props属性来进行数据传递.

传递数据三个步骤:

  1. 在父组件中,调用子组件的组名处,使用属性值的方式往下传递数据

    <Menu :mynum="num" title="home里面写的数据"/>
    
    # 上面表示在父组件调用Menu子组件的时候传递了2个数据:
      如果要传递变量[变量可以各种类型的数据],属性名左边必须加上冒号:,同时,属性名是自定义的,会在子组件中使用。
      如果要传递普通字符串数据,则不需要加上冒号:
    
  2. 在子组件中接受上面父组件传递的数据,需要在vm组件对象中,使用props属性类接受。

    <script>
      export default {
        name:"Menu",
        props:["mynum","title"],
        data: function(){
          return {
            msg:"这是Menu组件里面的菜单",
          }
        }
      }
    </script>
    
    // 上面 props属性中表示接受了两个数据。
    
  3. 在子组件中的template中使用父组件传递过来的数据.

    <template>
        <div id="menu">
          <span>{{msg}},{{title}}</span>
          <div>hello,{{mynum}}</div>
      </div>
    </template>
    

效果:

1552364511546

步骤流程:

1552364590540

使用父组件传递数据给子组件时, 注意一下几点:

  1. 传递数据是变量,则需要在属性左边添加冒号.

    传递数据是变量,这种数据称之为"动态数据传递"

    传递数据不是变量,这种数据称之为"静态数据传递"

  2. 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.

    这种情况,在开发时,也被称为"单向数据流"

子组件传递数据给父组件

  1. 在子组件中,通过this.$emit()来调用父组件中定义的事件.

    <template>
        <div>
          <p>Post的子组件</p>
          <h2>{{fnum}}</h2>
          <p>data={{data}}</p>
          <p>fnum={{fnum}}</p>
          <div><input type="text" v-model="fnum"></div>
        </div>
    </template>
    
    <script>
        export default {
            name: "PostSon",
            // 父组件传递数据给子组件: 1. 在父组件中调用子组件的组件名称标签上面声明属性和传递值,2. 在子组件中通过props进行接收
            props:["data","fnum"],  // 接受父组件中传递过来的数据
            // 子组件传递数据给父组件[事件的方式进行传递]:
            watch:{
              fnum(){
                console.log(this.fnum);
                // this.$emit("父元素的自定义事件","要传递的数据");  // 通过this.$emit()方法,子组件可以把数据传递给父组件
    
                this.$emit("postparentdata",this.fnum);
              }
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    
    
  2. 父组件中声明一个和子组件中this.$emit("自定义事件名称")对应的事件属性。

    <template>
        <div>
          <h1>num={{num}}</h1>
          <Son data="我是付组件里面的内容" :fnum="num" @postparentdata="getsondata"></Son>
        </div>
    
    </template>
    
  3. 父组件中,声明一个自定义方法,在事件被调用时,执行的。

    <script>
        import Son from "./PostSon"
        export default {
            name: "Post",
            data(){
              return {
                num: 100,
              }
            },
            components:{
              Son:Son,
            },
            methods:{
              getsondata(message){
                console.log("父组件"+message);
                this.num = message;
              }
            }
        }
    </script>
    
原文地址:https://www.cnblogs.com/ghh520/p/12951708.html