[Vue] 单文件组件

579 阅读3分钟

基于:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili

组件定义:实现界面局部功能代码和资源的集合

单文件组件 顾名思义,就是使用一个文件来表示组件,是一个以 .vue 后缀结尾的文件。

文件命名规则

  1. 由一个单词组成:
    例如:school.vueSchool.vue

  2. 由两个或以上单词组成:
    例如:my-school.vueMySchool.vue
    一般在开发过程中,我们使用 大驼峰(Upper Camel Case)的命名方式,即 每个单词的首字母大写,目的是与 vue 开发者工具 中的展示对接.

实操

在文件夹内建立一个名为 School.vue 的文件:

image.png

一个标准的组件应有三个元素:结构(html)、样式(css)、数据 逻辑 交互(JavaScript). 为了迎合这三个常见的属性,vue 为我们设计了三个标签:<template> <style> <script>,而且每个标签内的注释的写法都是不同的.

<template>
  <div>
    <!-- 结构 -->
  </div>
</template>

<script>
  // 数据、逻辑、交互
</script>

<style>
  /* 样式 */
</style>

这样一来,我们便可以将一个组件所要用到的一切放置于一个 .vue 文件里,结构清晰、简单明了.

现在,我们向组件里加入一些内容:

<template>
  <div class="demo">
    <h2>学校名称:{{schoolName}}</h2>
    <h2>学校地址:{{address}}</h2>
    <button @click="showName">点我提示学校名</button>
  </div>
</template>

<script>
  export default {
    // 详细看下方的 **组件暴露**
    name:'SchoolName',
    //name项不可以只写 School,vue会报错,需要写成类似这样的大驼峰形式
    data(){
      return {
        schoolName:'sgg',
        address:'北京',
      }
    },
    methods: {
      showName() {
        alert(this.schoolName)
      }
    },
  }
</script>

<style>
  .demo{
    background-color: orange;
  }
</style>

组件暴露

  • 分别暴露
    export const school = Vue.extend(...)
    
  • 统一暴露
    const school = Vue.extend(...)
    export {school}
    
  • 默认暴露
    const school = Vue.extend(...)
    export default school
    //或
    export default Vue.extend(...)
    
    Vue.extend 关键字可以省略 我们这里使用的是 默认暴露,因为在其他需要引入的时候只需要 import xxx from xxx,而使用其他暴露方式在引入的时候需要 import {xxx} from xxx,在这里我们只暴露一个组件,所以选择 默认暴露

再照猫画虎地写一个 Student.vue 的组件:

<template>
  <div>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生年龄:{{age}}</h2>
  </div>
</template>

<script>
export default {
  name: 'StudentName',
  data() {
    return {
      name: '张三',
      age: 18
    }
  }
}
</script>

App.vue

写完 School.vueStudent.vue 之后,我们还需要一个控制所有组件的组件 App.vue

<template>
  <div> 
    <!-- 模板里需要有一个根元素 -->
    <School></School>
    <Student></Student>
  </div>
</template>

<script>
  //引入组件
  import School from './School'
  import Student from './Student'
    //结尾的 .vue 可以省略不写

  export default {
    name: 'App',
    //注册组件
    components: {
      School,
      Student
    }
  }
</script>

.vue 文件中,输入 <v 按下回车可以直接生成如下模板:

<template>
  
</template>

<script>
export default {

}
</script>

<style>

</style>

使用组件

在编写完 School.vueStudent.vueApp.vue 三个 .vue 结尾的文件后,我们还需要建立 main.js 文件来使用组件:

import Vue from 'vue';
import App from './App.vue';

new Vue({
  el: '#root',
  
  //render函数,下面有解释
  render: h => h(App),
})

render 函数

在上面的 main.js 中,我们 new Vue 时没有写 componentstemplate 配置项,而是直接使用 render: h => h(App) 这样一句箭头函数 . 原因是在 main.js 中的第一行 import Vue from 'vue' 的时候 我们实际上引入的是 /node_modules/vue/dist/vue.runtime.esm.js 这个文件(vue/package.json 中的 module 有写到,esm 表示 ES Module);这个 js 文件仅包含 vue核心 而不包含 模板编译器,所以无法解析写在 .js 文件中的 template ,这也是为什么我们需要在 main.js 中使用 vue 给我们提供的 render 函数。下面是 render 函数的完整写法:

//使用render解析html语句
render(createElement) {
    return createElement('h1','Hello World!')
}

image.png

//使用render解析组件模板
render(createElement) {
    return createElement(App)
}
//写成箭头函数:
render: h => h(App)

之后 我们还需要一个用以展示页面的 index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SingleFileComponents</title>
</head>
<body>
  <div id="root">
    <!-- <App></App> -->
    <!-- 在 App.vue 中配置了 template 项则不需要写<App> -->
  </div>
</body>
</html>

放入脚手架中运行

看一下我们所创建的文件:

image.png

_files 内的 App.vuemain.js 替换掉项目内 /src 下的 App.vuemain.js

image.png

修改一下 App.vueimport 的路径:

  //引入组件
  import School from './components/School'
  import Student from './components/Student'
    //结尾的 .vue 可以省略不写

再将 Student.vueSchool.vue 放入 /src/components 内:

image.png

使用自己编辑的 index.html 替换掉 /public 下的 index.html .

进入项目文件夹,启动 npm run serve

image.png


大致结构图:

image.png