• Vue.js 第4章 组件与路由


    组件

    • 什么是组件:组件就是一些标签结构的封装,同时为这些结构添加需要的业务逻辑,设置你想要的样式

      • 一个组件中一般可以设置:结构,功能和样式

    • 为什么要使用组件:

      • 使用方便

      • 复用

    组件的创建和使用
    • 组件的分类:

      • 全局组件:在vm实例外通过Vue.component来创建的组件,在当前vm实例指定的app模板范围内都能使用

      • 子组件:在组件内部通过components属性来创建的组件

    • 在vue中如何创建组件

      • 组件是可复用的 Vue 实例:这句话告诉我们组件就是一个vue实例,那么就意味着在之前创建vue实例中的配置成员在组件中似乎都能写,也就说明了如何配置Vue实例就如何配置组件实例

      • 通过Vue.component(名称,{配置})来创建组件

      • 在页面中通过组件名称来使用,使用的时候就像使用标签一样

      • 重点说明:在vm实例外来创建

    <!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>Document</title>
      <script src="./js/vue.js"></script>
    </head>
    
    <body>
      <!-- 创建父组件模版 -->
      <template id="father">
        <div>
          <h2>我是爸爸</h2>
          <!-- 将子组件放在这里 -->
          <son></son>
    
        </div>
      </template>
    
      <!-- 创建子组件模版 -->
      <template id="son">
        <h2>我是儿子</h2>
      </template>
      <div id='app'>
        <!-- 将父组件放在这里 -->
        <father></father>
      </div>
      <script>
        // 创建一个父组件
        Vue.component('father', {
          template: '#father',
          data(){
            // 注意:这里如果写了data函数,内部就必须return一个对象(没有数据就写个空对象),否则服务器会爆炸!
            return {
            }
          },
    
          // 使用components创建子组件
          components: {
            // 子组件名称
            son:{
              template: '#son',
              data(){
                return {}
              }
            }
          }
        })
        var vm = new Vue({
          el: '#app',
          data: {}
        })  
      </script>
    </body>
    
    </html>
    创建并使用组件
    • 在Vue中如何使用组件,重点关注使用的细节

    • 常见错误:

     

    原因

    你的组件的确没有定义

    你定义了,但是定义的位置不对,如放在vm实例后定义就会出现这个错误

    重点:在组件中如何添加更多 配置

    到底可以添加那些配置

      之前vm实例可以添加的配置这边基本上都能添加,除了el

      el在之前的作用是指定模板,在组件中指定模板是通过template属性

     

    配置具体应该如何进行

      template:指定模板

      在template属性中直接创建模板

      使用template标签创建模板,在template属性中指定

      创建模板结构,设置标识id

    <template id='lwtemp'>
        <p style="color: red">我是隔壁老王~~~~!!!!</p>
    </template>

    在template属性中指定这个模板

     Vue.component('laowang', {
         // 指定模板
         // 没有语法高亮,没有代码提示,没有层次结构,不方便修改
         template: "#lwtemp"
     })

    细节:

    这个错误告诉我们组件只能有一个根元素,如果有多个则会出现这个错误,如何解决,将这多个元素再包含在到一个根元素中

     data:

    • 可以定义当前组件中使用到的变量

    • data必须是一个函数

      • 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

      • 如果不是一个函数,那么有可能造成组件复用的时候,多个组件指向同一个对象,造成操作其中任何一个组件,其它组件会有莫名其妙的变化

      • 函数有作用域,在一个函数中生成的数据与其它的函数没有关系,如果使用函数,就可以做到一个组件内部的数据操作不会影响其它的组件,同时也不会影响组件的复用

      • data函数中必须返回 一个对象

    在函数中必须返回一个对象

    错误信息

      

    原因:你在组件中使用到了某些成员,但是这个成员在组件中却没有定义

    1.组件是一个单独的结构,一个组件默认不能使用另外一个组件中定义的成员

    原因:组件中的Data选项必须是一个函数,这个函数还必须返回 一个对象,我们定义的数据必须写在这个返回的对象中

     

    原因:data函数必须返回一个对象,如果没有成员,也需要返回一个{}

    • methods:

    • mounted:

    • watch:

    • computed:

    // vm外面创建组件
    Vue.component('laowang', {
        // 指定模板
        // 没有语法高亮,没有代码提示,没有层次结构,不方便修改
        template: "#lwtemp",
        // 添加设置数据
        data(){
            return {
                age:0,
                myname:'隔壁老李'
            }
        },
        methods:{
            sayHi(){
                alert('你好啊')
            }
        },
        mounted(){
            alert('页面打开立刻执行')
        },
        computed:{
            myage(){
                return this.age - 0 + 10
            }
        }
    })
    组件的组织结构

    以后真正进行开发的时候,页面可能会比较的复杂,经常会看到元素嵌套的场景出现,如果你将一些结构封装为组件,那么势必会造成组件的嵌套,这样就产生了一个组件相关的组织结构

    • 什么是父组件,什么是子组件

      • 外层组件就可以认为是父组件

      • 父组件中创建的组件就可以认为是这个父组件的子组件

      • 父子只是一个组织结构布局

    • 为什么会出现父子组件这种结构

    • 创建父子组件

      • 先创建父组件

      • 在父组件内部通过components创建子组件

      • 子组件的创建方式和父组件完全一致

    Vue.component('father', {
         template: '#father',
         data() {
             return {
                 fname: '老王'
             }
         },
         // 通过components属性来创建子组件,它是一个对象
         components: {
             // 定义一个一个的子组件
             // 3.定义第一个子组件son
             son: {
                 // 4.可以写与父组件相同的成员
                 template: '#son',
                 data() {
                     return {
                         sname: '小王'
                     }
                 }
             }
         }
     })
    • components的两个作用

      • 创建子组件

      • 组件注册:如果你从其它地方引入一个组件那么就必须先注册才能使用

    • 使用子组件

      • 在某个父组件中创建的子组件只有在这个父组件中可以使用

      • 所谓在父组件中使用是指在这个父组件的模板中使用

    <!-- 2.父组件模板 -->
    <template id='father'>
        <div class="father">
            <p>我是父组件:{{fname}}</p>
            <son></son>
        </div>
    </template>

    由于上面的组件的组织结构,在真正进行开发的时候,我们经常需要实现不同的组件之间的数据交互,那么就必须要实现组件之间的数据传递

    在一个组件中定义的数据只有在当前组件中可以使用

    父子组件之间的数据传递

    父传子

    • 父组件中数据要传递给子组件来使用

    • 如果要实现父传子,子组件需要做什么

      • 在子组件中定义props属性,它是一个独立的属性

      • props是一个数组

      • 在props中定义的成员就相当于在data中定义的成员

      • 在props一般就是你想定义的属性的名称,它们的类型是字符串

      • 这个props相当于一个父组件为子组件赋值的接口,在父组件中可以为子组件的props中定义的成员赋值

    • 如果要实现父传子,在父组件中需要做什么

      • 父组件中要使用子组件

      • 在父组件中使用子组件的位置,使用v-bind为子组件中的prop属性赋值

    子传父

    • 大致了解子传父的场景

    • 通过this.$emit可以发射事件

    • 子传父在子组件中需要做什么

      • 添加按钮事件,在事件处理函数中去发射一个事件

      • 发射事件并传入相应的数据,它是通过事件发射向父组件传递数据

    • 子传父在父组件中又需要做什么

      • 父组件中进行指定事件的监听

      • 发现有指定的事件发射,就监听并进行处理

      • 在父组件中使用子组件的位置使用v-on进行监听,在监听处理函数中有一个默认的参数,这个参数就是从子组件事件发射时传递的数据

    兄弟组件之间的传值

    • 查看使用场景

    • 为什么不能再使用this

      • this是指向当前组件,意味着事件只能由father组件进行监听,与我们要求不相合

      • this我们知道它的本质就是一个vue实例,那么我们能不能直接创建一个全局的Vue实例来进行这个场景的事件发射呢?

    • 创建事件总线:new Vue()

      • 事件总线就是说明所有事件都能通过它来进行发射和监听

      • 说白了,事件总线就是一个单独的全局的Vue实例

    • 源组件中需要做什么事情

      • 发射事件,传递数据

    • 目标组件需要做什么事情

      • 监听事件,接收数据

    父传子demo

    <!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>Document</title>
      <script src="./js/vue.js"></script>
    </head>
    
    <body>
      <!-- 创建父组件模版 -->
      <template id="father">
        <div>
          <h2>告诉儿子明天去{{surfing}}!</h2>
          <son :surfing="surfing"></son>
        </div>
      </template>
      
      <!-- 创建子组件模版 -->
      <template id="son">
        <h2>我爸爸告诉我明天去{{surfing}}</h2>
      </template>
      <div id='app'>
        <father></father>
      </div>
      <script>
        // 创建父组件
        Vue.component('father',{
          template: '#father',
          
          data(){
            return {surfing:'海上冲浪'}  
          },
          methods: {
            
          },
          // 创建子组件
          components: {
            son:{
              template: '#son',
              props: ['surfing'],
              data(){
                return {}
              },
              methods: {
                
              }
            }
          }
        })
        var vm = new Vue({
          el: '#app',
          data: {}
        })  
      </script>
    </body>
    
    </html>

    子传父demo

    <!-- 
      思路:
        1.子组件发射事件,传递数据
        2.父组件中使用子组件的位置进行监听,通过v-on:事件名='事件处理函数'
     -->
    <!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>Document</title>
      <script src="./js/vue.js"></script>
    </head>
    
    <body>
      <!-- 创建父组件模板 -->
      <template id="father">
        <div>
          <h2>I am Father,我儿子的女朋友是:{{gfname}}</h2>
          <son v-on:emitname='getname'></son>
        </div>
      </template>
    
      <!-- 创建子组件模版 -->
      <template id="son">
        <div>
            <h2>I am Son</h2>
            <button @click="sendName">点我发送女朋友杨幂给我爸爸</button>
        </div>
      </template>
      <div id='app'>
        <father></father>
      </div>
      <script>
        // 创建父组件
        Vue.component('father', {
          template: '#father',
          data() {
            return {
              gfname: ''
            }
          },
          methods: {
            getname(data){
              console.log(data)
              this.gfname = data;
            }
          },
          // 创建子组件
          components: {
            son: {
              template: '#son',
              data() {
                return {
                  gfname: '杨幂'
                }
              },
              methods: {
                sendName(){
                  // $emit可以发射事件
                  // this.$emit(事件名称,事件参数(数据))
                  // 注意:在子组件函数中发射一个事件并不需要关心谁去做监听
                  this.$emit('emitname',this.gfname)
                }
              }
            }
          }
        })
        var vm = new Vue({
          el: '#app',
          data: {}
        })  
      </script>
    </body>
    
    </html>

    兄弟组件传值demo

    <!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>Document</title>
      <script src="./js/vue.js"></script>
    </head>
    
    <body>
      <!-- 创建父组件模版 -->
      <template id="father">
        <div>
          <alex></alex>
          <roger></roger>
        </div>
      </template>
    
      <!-- 创建2个兄弟组件模版 -->
      <template id="alex">
        <div>
            <h2>我要告诉我兄弟今天去{{dosomething}}</h2>
            <button @click="tellinfo">点击发送短信</button>
        </div>
      </template>
    
      <template id="roger">
        <h2>WoW,我兄弟告诉我今天要去{{dosome}},好兴奋!</h2>
      </template>
      <div id='app'>
        <father></father>
      </div>
      <script>
        //创建事件总线bus实例
        var bus = new Vue();
    
        // 创建父组件
        Vue.component('father',{
          template: '#father',
          data(){
            return {}
          },
          methods: {
            
          },
          // 创建2个兄弟组件
          components: {
            alex: {
              template: '#alex',
              data(){
                return {
                  dosomething: '钓鱼',
                }
              },
              methods: {
                tellinfo(){
                  // 使用事件总线来发送事件
                  bus.$emit('emitname', this.dosomething)
                }
              }
            },
            roger:{
              template: '#roger',
              data(){
                return {
                  dosome:'??'
                }
              },
              methods: {
    
              },
              mounted () {
                bus.$on('emitname', data=>{
                  console.log(data)
                  this.dosome = data
                })
              }
            }
          }
        })
    
        var vm = new Vue({
          el: '#app',
          data: {}
        })  
      </script>
    </body>
    
    </html>

    路由

    可以实现导航跳转(页面跳转)的一种方式,在vue组件的跳转都是通过路由来实现的

    https://router.vuejs.org/zh/

    • 为什么要使用路由

      • 因为我们不想实现页面的跳转

      • 但是我们又想展示不同的页面的不同的内容

    • 我们要做什么

      • 我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们

    • 基本路由的添加方式

      • 你得路由如何添加:它是一个单独的结构

      • 通过VueRouter进行路由对象的创建

      • 通过routes进行路由配置

      • 路由和组件如何映射

      • 如何指定你组件内容的展示区域

    • 如何使用路由

      • 挂载路由=注入路由

      • 添加router-view结构,指定路由映射组件的展示区域

    demo

    <!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>Document</title>
      <script src="./js/vue.js"></script>
      <script src="./js/vue-router.js"></script>
    </head>
    
    <body>
    
      <div id='app'>
        <router-link to="/index">首页</router-link>
        <router-link to="/product">产品页</router-link>
        <h3>路由匹配到的组件将渲染在这里</h3>
        <div style="600px; height: 400px; border: solid">
          <router-view></router-view>
        </div>
      </div>
      <script>
        // 每个路由对象映射着一个单独的组件,所以我们第一步创建好组件
        // 1.创建几个组件
        var Index = Vue.component('index', {
          template: '<div>首页</div>'
        })
        var Product = Vue.component('product', {
          template: '<div>产品</div>'
        })
        // 2.创建路由对象,创建之前不要忘了引入vue-router.js文件
        // 通过new VueRouter()来创建路由对象,在构造函数中添加路由配置
        var router = new VueRouter({
          // 3.添加路由配置
          // 我们可以配置多个路由,所以使用routes来进行多个路由的配置
          routes: [
            // 4.添加单个路由配置,俺哥路由都是以对象的方式存在,对于单个路由一般我们
            //会配置下面几个属性
            {
              name: 'Index',
              path: '/index',
              component: Index
            },
            {
              name: 'Product',
              path: '/product',
              component: Product
            }
          ]
        })
    
        var vm = new Vue({
          el: '#app',
          // 5.注入/挂载路由
          router: router,
          data: {}
        })  
      </script>
    </body>
    
    </html>

    思维脑图总结:

     

  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/replaceroot/p/11037757.html
Copyright © 2020-2023  润新知