vue基础2

54 阅读8分钟

VUE

2、组件化开发

2.1、认识组件概念

  • 对于学Java的人来说的话,这个词所要表达的意思再熟悉不过了,所谓组件就是:面向对象中的抽象、封装思想,而所谓的组件化就是:把功能用多组件的方式搭配起来编写( 有一个根组件,旗下有N多微型组件 ,粗暴理解就是:SpringCloud中的main()方法可以搭配很多不同功能的注解,main()方法就是根组件,不同功能的注解就是微型组件 ),那这些功能组成的应用程序就是一个组件化应用,因此:这样做之后,好处就是利于维护和提高代码的复用性了
  • 但是对于前端的人来说,这个东西就需要特别解释一下:直接下定义就是 实现应用中局部功能代码和资源的集合
  • 至于为什么要学组件化开发?
    • 一是因为做的应用页面都是很复杂的,如果使用传统的CSS+HTML+JS,那么就会出现很多的js文件,不利于维护和 编写很费力的
    • 二是因为组件化开发可以极好的复用代码、简化项目代码、所以也就提高了运行效率
  • 同时组件又有单文件组件( 真实开发玩的 ) 和 非单文件组件
    • 单文件组件:就是指只有一个组件组成( 即:是一个.vue的文件 )
    • 非单文件组件:就是有N多个组件组成

2.2、非单文件组件

2.2.1、使用组件
 
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>玩一下组件</title>
 
     <script src="../../js/vue.js"></script>
   </head>
 
   <body>
     <!-- 被 vm 实例所控制的区域 -->
     <div id="app">
       <!-- 3、使用组件 -->
       <person></person>
       <hr/>
 
       <hobbys></hobbys>
 
     </div>
 
     <script>
        // 去除浏览器控制台中的警告提示信息
       Vue.config.productionTip = false;
 
       // 玩组件三板斧
       // 1、创建组件
       const person = Vue.extend({
         // 这里在基础篇中怎么玩就怎么玩,相应的也有watch、computed.....
         // 但是:切记:不可以用el和data必须是函数式
         /* 
           不可以用el的原因是:el指向的是具体的容器,这是根组件做的事情,现在这是是小弟
           不可以用data对象式,而必须用函数式:是因为对象是一个引用地址嘛( 玩java的人很熟悉这个对象的事情 )
                              如果用引用一是Vue直接不编译、报错,二是就算可以用对象式,那几个变量都可以
                              指向同一个对象,那么就会产生:一个变量修改了对象中的东西,那么另一个变量指向
                              的是同一个对象,因此:数据也会发生改变
                              而函数式则不会,因为:函数式就会是哪个变量用的,里面的return返回值就是属于哪个变量
         */
 
         // 使用模板,这个就需要直接写在组件里面了,如果:放到div容器的模板中,是会报错的
         template: `
           <div>
             <h2>{{name}}</h2>
             <h2>{{age}}</h2>
             <h2>{{sex}}</h2>  
           </div>
         `,
         // 切记:这里是使用data的另一种写法 —— 函数式,必须用,前面基础篇说过了
         data(){
           return {
             name: '紫邪情',
             age: 18,
             sex: '女'
           }
         }
       })
 
       // 再创建一个组件
       const hobbys = Vue.extend({
         template: `
           <div>
             <h2>{{one}}</h2>
             <h2>{{two}}</h2>
             <h2>{{three}}</h2>  
           </div>
         `,
         data(){
           return {
             one: '抠脚',
             two: '玩',
             three: '酒吧'
           }
         }
       })
 
       // 创建 vm 实例对象
       const vm = new Vue({
         // 指定控制的区域
         el:'#app',
         // 这里面也可以使用这个编写data,和以前一样
         data:{},
 
         // 2、注册组件
         components: {
           // 前为 正式在页面中用的组件名( div模板中用的名字 )  后为组件所在位置
           // person: person,           // 这种同名的就可以简写
 
           // 简写
           person,
           hobbys
         }
        });
     </script>
   </body>
 </html>
 

组件小结

  • Vue中使用组件的三板斧

    • 1、创建组件
    • 2、注册组件
    • 3、使用组件( 写组件标签即可 )
  • 如何定义一个组件? 使用Vue.extend( { options } )创建,其中options 和 new Vue( { options } )时传入的哪些option“几乎一样”,区别

    • 1、el不要写 ——— 因为最终所有的组件都要经过一个vm的管理( 根组件 ),由vm中的el决定服务哪个容器
    • 2、data必须写成函数式 ———— 因为可以避免组件被复用时,数据存在引用关系
    • 另外:template选项可以配置组件结构
  • 如何注册组件?

    • 1、局部注册: 靠new Vue的时候传入components选项
    • 2、全局注册:靠Vue。component( '组件名' , 组件 )
2.2.2、使用组件的注意点
  • 1、创建组件时的简写问题
// 1、创建局部组件( 完整写法 )
      const person = Vue.extend({
          template: `
            <div>
                <h2>{{name}}</h2>    
                <h2>{{age}}</h2>
            </div>
          `,
          data(){
              return {
                  name: '紫邪情',
                  age: '女'
              }
          }
      })

      // 简写形式
      const person2 = {
        template: `
            <div>
                <h2>{{name}}</h2>    
                <h2>{{age}}</h2>
            </div>
          `,
        data(){
              return {
                  name: '紫邪情',
                  age: '女'
              }
          }
      }
  • 组件名的问题
    • (1)、组件名为一个单词时
      • 使用全小写字母 / 首字母大小都没问题
    • (2)、组件名为多个单词组成时
      • 全部用小写 / 使用 - 进行分割都没问题
    • (3)、注意组件名别和HTML中的原生标签名一致,会冲突报错,HTML的限制就是上图中看源码中的哪些( 别想着它是小写,你搞大写,也是不行的^ _ ^ ),如果非要用HTML标签名,让人见名知意,那就在原生HTML标签名前加一些特定的词,如:user-input这种【 一般加的前缀都是功能点名称 】,记得千万别用:input、h2....此类名字来命名组件名
  • 3、关于组件在使用时的注意项
    • (1)、可以使用双标签,如:,这种肯定没任何问题
    • (2)、也可以使用自闭合标签,如:,但是这种有坑,这种使用方式需要脚手架支持,否则s数据渲染会出问题

使用组件注意点总结

  • 1、对于组件名
    • 一个单词组成时
      • (1)、全小写,如:person
      • (2)、首字母大写,如:Person
    • 多个单词组成时
      • (1)、全小写,如:myinfo
      • (2)、使用 - 分割,如:my-info
      • (3)、驼峰命名,如:MyInfo,但注意:目前没用脚手架之前最好别用,是因为指不定一会好使,一会不好使

注意事项:

  • (1)、组件名最好别和HTML的标签名一致,从而造成冲突( 非要用,可以采用加词 / 使用 - 分割 )

  • (2)、可以在创建组件时,在里面配置name选项,从而指定组件在Vue开发者工具中呈现的名字

  • 2、关于组件标签( 使用组件 )

    • (1)、使用双闭合标签也行,如:
    • (2)、使用自闭合标签也行,如:

*注意事项:此种方式目前有坑,会出现后续组件不能渲染的问题,所以需要等到后续使用脚手架时才可以

  • 3、创建组件的简写形式 const person = Vue.extend( { 配置选项 } ) 可以简写为 const person = { 配置选项 }
2.2.3、组件的嵌套 / 子父组件
  • 很有用啊,真实开发玩的是单文件组件,逃不开这个点的,而且还会有子父组件通信和兄弟组件通信
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     <title>组件嵌套</title>
 
     <script src="../../js/vue.js"></script>
   </head>
 
   <body>
     <!-- 被 vm 实例所控制的区域 -->
     <div id="app">
         <!-- 3、使用组件 -->
         <info></info>
     </div>
 
     <script>
        // 去除浏览器控制台中的警告提示信息
       Vue.config.productionTip = false;
 
       // 1、定义组件
       const person = {
           template: `
             <div>
                 <h2>{{name}}</h2>    
                 <h2>{{sex}}</h2>
             </div>
           `,
           data(){
               return {
                   name: '紫邪情',
                   sex: '女'
               }
           }
       }
 
       const info = Vue.extend({
           template: `
             <div>
                 <h2>{{address}}</h2>    
                 <h2>{{job}}</h2>
                 <!-- 这个组件中使用被嵌套的组件 -->
                 <person></person>
             </div>
           `,
           data(){
               return {
                   address: '浙江杭州',
                   job: 'java'
               }
           },
 
           // 基础组件嵌套 —— 这个组件中嵌套person组件
           /* 
             注意前提:被嵌套的组件 需要比 当前嵌套组件先定义( 如:person组件是在info组件前面定义的 )
                      原因:因为Vue解析模板时,会按照代码顺序解析,如果定义顺序反了
                            就会出现:这里用到的组件 在 解析时由于在后面还未解析从而出现找不到
           */
          components: {
              person,
          }
       })
 
       // 创建 vm 实例对象
       const vm = new Vue({
         // 指定控制的区域
         el:'#app',
         data:{},
 
         // 2、注册组件 —— 由于info组件中 嵌套了 person组件,所以在这里只需要注册 info组件即可
         components: {
             info,
         }
        });
     </script>
   </body>
 </html>
 
  • 另一种嵌套:开发中玩的,我对那个div容器起的id值为app,是有用的
    • 在开发中的嵌套是一个vm管理独一无二的app( 就是application 应用的意思 ),然后由app管理众多小弟
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vm管app,app管众多组件</title>

    <script src="../../js/vue.js"></script>
  </head>

  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app"></div>

    <script>
       // 去除浏览器控制台中的警告提示信息
      Vue.config.productionTip = false;


      // 1、定义组件
      const person = {
          template: `
            <div>
                <h2>{{name}}</h2>    
                <h2>{{sex}}</h2>
            </div>
          `,
          data(){
              return {
                  name: '紫邪情',
                  sex: '女'
              }
          }
      }

      const info = Vue.extend({
          template: `
            <div>
                <h2>{{address}}</h2>    
                <h2>{{job}}</h2>
                <!-- 这个组件中使用被嵌套的组件 -->
                <person></person>
            </div>
          `,
          data(){
              return {
                  address: '浙江杭州',
                  job: 'java'
              }
          },
         components: {
             person,
         }
      })

      // 再定义一个app组件,用来管理其他组件
      const app = {
        //   这个app组件没有其他的东西,就是注册和使用被管理组件而已
          components: {
            //   有其他组件也可以注册在这里面,这里由于info管理了person,所以只注册info即可
              info
          },
          template: `
            <div>
                <info></info>   
            </div>
          `,
      }

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el:'#app',
        data:{},

        // 由于组件被app管理,所以:只注册app组件即可
        components: { app },

        // 使用组件
        template: `
            <div>
                <app></app> 
            </div>
        `,
       });
    </script>
  </body>
</html>

2.2.4、认识VueComponent()函数
  • 1、来看一下组件到底是谁?
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>认识VueComponent</title>

    <script src="../../js/vue.js"></script>
  </head>

  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app"></div>

    <script>
       // 去除浏览器控制台中的警告提示信息
      Vue.config.productionTip = false;

      // 1、定义组件
      const person = Vue.extend({
          template: `
            <div>
                <h2>{{name}}</h2>    
                <h2>{{job}}</h2>
                <h2>{{address}}</h2>
            </div>
          `,
          data(){
              return {
                  name: '紫邪情',
                  job: 'java',
                  address: '浙江杭州'
              }
          }
      })

      const app = {
          components: {person},
          template: `
            <div>
                <person></person>    
            </div>
          `,

      }

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el:'#app',
        data:{},
        components: {app},
        template: `
            <div>
                <app></app>    
            </div>
        `,
       });
    </script>
  </body>
</html>

2.3、单文件组件

  • 就是只有一个文件嘛,xxxx.vue
  • 而xxxx就是前面说过的组件命名
    • 单个单词:全小写、首字母大写
    • 多个单词:用 - 进行分割、大驼峰命名
    • 而开发中最常用的就是:首字母大写和大驼峰命名
2.3.1、疏通单文件组件的编写流程
  • 前提:如果自己的编辑器是vscode,那么就给编辑器安装vetur插件,然后重启vscode,这个插件就是为了能够识别xxxx.vue文件的;如果自己是用的IDEA编辑器来写的vue,那么安装了vue.js插件之后,不用安装其他的插件都可以的
2.3.1.1、创建xxxx.vue文件
  • 这个创建的就是单文件组件,前面玩非单文件组件,不是有三板斧吗,对照来看
  • 创建了xxx.vue之后,是一个空文件,里面要写的东西就三样(模板template、交互script、样式style ),里面内容也对照非单文件组件来看

<template>
  <div class="temp">
    <!-- 这里面就是模板 以前在非单文件组件中用的template选项是怎么写的,这里面就是怎么写的-->
    <h2>{{name}}</h2>
  </div>
</template>


<script>
// 这里面就是交互( data、methods、watch、computed..... )
// 就是非单文件组件中的定义组件
/*    const person = vue.extend({
        // 这里就最好配置name选项了,一般都是当前创建的xxxx.vue中的xxxx名字即可
        name: 'Person',
        data() {
            return {
                name: '紫邪情'
            }
        },
        // 这里面还可以写什么methods、watch.....之类的
    })
*/

// 但是:上面是对照非单文件组件来写的,在这个单文件中其实换了一下下
// 1、这个组件是可以在其他地方复用的,所以:需要把这个组件暴露出去,然后再需要的地方引入即可
/* 
    这里需要使用到js中模块化的知识
    export暴露 import引入嘛
    但是:export暴露有三种方式
        1、分别暴露  export const person = vue.extend({ 配置选项 }),
            就是在前面加一个export而已
            可是:根据前面非单文件的知识来看,这个是可以进行简写的
            export person {}
        2、统一暴露 就是单独弄一行代码,然后使用 export { 要进行暴露的名字 },多个使用 , 逗号隔开即可
        3、默认暴露( vue中采用的一种,因为引入时简单 )  export default 组件名{ 配置选项 }
            但是:组件名就是当前整个文件,所以可以省略
            默认暴露引入: import 起个名字 from 它在哪里
            而其他的暴露方式在引入时会有点麻烦
*/

// 正宗玩法
export default {
  name: 'Person',
  data() {
    return {
      name: '紫邪情'
    }
  },
 
// 再配置其他需要的东西也行 如:methods、watch、computed.....
}
</script>



<style>
/* 这里面就是template中的样式编写, 有就写,没有就不写 */
.temp{
  color: purple;
}
</style>

2.3.1.2、注册组件到app中
  • vm管app,app管其他的小弟,所以需要一个app组件,创建一个app.vue
 <template>
   <div>
       <!-- 使用app管理的组件 -->
       <person></person>
   </div>
 </template>
 
 <script>
     // 引入定义的person组件(要是有其他组件要引入那是一样的套路)
     // 1Person.vue这个名字不正规啊,我只是为了排序才加了一个1
     import person from "./1Person.vue"  
 
     export default {
         name: 'App'
         // 注册引起来的组件
         components: {person}  // 完成了引入和注册之后,在这里面就可以用引入的组件了
     }
 </script>
 
 <style>
 /* app是为了管理其他所有的组件,所以这个style其实不写也行( 按需要来吧 ) */
 </style>
2.3.1.3、将app和vm绑定起来
  • 新建一个main.js文件,创建这个文件的目的:一是让app和vm绑定,二是浏览器并不能识别.vue文件,所以根本展示不了,因此:需要将.vue文件转成js文件,这样浏览器就能解析了

 // 1、引入app组件
 import App from "./2App.vue"
 
 // 2、把app组件和vm进行绑定
 new Vue({
     // 这里面和以前一样写法,当然:这里的el值绑定的是容器id,怕误会改成root也行
     el: '#App',
     components: {App}
 })
2.3.1.4、创建容器
  • 前面app组件和vm绑定了,但是vm中指定的el值,它绑定的容器还没有啊,因此:创建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>创建el容器</title>
 
     <!-- 
         记得要引入js,而此时就需要引入两个js,一个是main.js,一个是vue.js 
         可是:在解析下面的容器时,可能会导致js渲染不及时出问题
         因此:引入js最好放在下面容器的后面引入
     -->
 </head>
 <body>
 
     <div id="App">
         <!-- 
             2、使用app组件,可以在这里使用,也可以不在这里使用
             直接在app.vue中使用template选项进行使用
         -->
         <App></App>
     </div>
     
 
     <!-- 
         1、引入js 
             vue.js是因为:main.js中new vue()需要它,所以:先引入vue.js
             其次再引入main.js
     -->
     <script src="../../../js/vue.js"></script>
     <script src="./3Main.js"></script>
 </body>
 </html>
  • 而整个流程按照解析的逻辑来看就是如下流程
    • 1、进入index.html,创建了div id = "App"容器,然后引入vue.js,再引入main.js
    • 2、但是:引入main.js,去main.js里面开始解析时,发现:需要引入App.vue,所以:接着引入App.vue
    • 3、进入App.vue,又发现需要引入Person.vue
    • 4、将所有东西都引入完了之后,就可以依次进行渲染了( 逻辑就不说明了 ),而经过上面的逻辑梳理之后会发现:main.js就是入口,是从main.js开始引入,从而把其他的东西也给引入进来了
2.3.2、认识脚手架 vue cli
2.3.2.1、使用nodejs配置脚手架
  • 前提:保证自己的电脑有nodejs,玩后端的人要是不了解nodejs的话,就把它理解为服务器,低配版的tomcat,

  • nodejs的配置很简单,官网进行下载、一直next、最后修改环境变量

    • 有个注意点:选择安装目录时,别把nodejs安装到系统C盘了,不然很大可能出现权限不足,无法操作的问题,特别是:如果自己的电脑没升级,还是家庭版的而不是专业版的,这种问题更常见 出现这种问题就需要切换到管理员身份运行cmd才可以进行安装vue-cli了,甚至有时会奇葩点:需要在管理员身份下运行npm clean cache –force
    • 然后再进入到C盘的用户目录下的appdata/roaming下把一个叫做nom-cache这个缓存文件删了,最后再用管理员身份运行npm clean cache –force清除缓存,搞完这些才可以安装vue cli脚手架
  • nodejs官网: nodejs.org/en/download…

  • 设置淘宝镜像地址 npm install -g cnpm --registry=https://registry.npm.taobao.org 或者 npm config set registry http://registry.npm.taobao.org

2.3.3、认识ref属性
2.3.4、props配置-获取外传数据
  • 功能:让组件接收外部传进来的数据
    • (1)、传递数据
    • (2)、接收数据
      • 1)、只接收 props: ['name']
      • 2)、接收数据 + 数据类型限定
      props: { name:String }
    • (3)、接收数据 + 数据类型限定 + 必要性限制 + 数据默认值
    props: { type:String, required:true, default:'紫邪情' 注:一个数据字段不会同时出现required和defautle }
  • 注意:props中的数据是只读的,Vue底层会监测对props的修改,如果进行了修改,就会发出警告
    • 如果业务需要修改,则:把props中的数据复制一份到data中,然后去修改data中的数据就可以了

    • 须知:vue中优先使用props中的数据,然后再使用data中的数据( 可以使用data中的名字和props中的名字一样,然后去渲染,发现渲染出来的数据是props中的 )