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

    思维脑图总结:

     

  • 相关阅读:
    计算机硕士工资一览表 08年最新各大IT公司薪水行
    VS2010单元测试
    windows操作系统的快捷键
    关于
    [美国代购] Nexus 6 与 Moto X 询价聊天记录整理
    nginxのerror_logはformat指定できない.
    Give $20/month and provide 480 hours of free education
    如何才可能将一件事情做到最高的效率
    Palindrome Number
    Reverse Integer
  • 原文地址:https://www.cnblogs.com/replaceroot/p/11037757.html
Copyright © 2020-2023  润新知