Vue.js 相关知识(组件)【分分快三计划】

作者:分分快三计划
props: ['parentmsg']

2. 全局组件

通过Vue的静态方法(component)定义,全可在所有组件中使用。语法如下:

<div id="app">
    <!-- 使用组件 -->
    <my-header></my-header>
</div>
<script type="text/javascript">
   //定义全局组件
   Vue.component("my-header",{
       template:"<div>我是全局组件</div>"
   })
   let app = new Vue({
        el:"#app"
  })
</script>

 注意事项:

  1. 如果使用 Vue.component 注册组件的时候,组件名称使用了驼峰命名,则在引用组件的时候,需要把大写的驼峰改为小写的字母,同时,两个单词之间使用 “-” 连接
  2. 如果不使用驼峰,则直接拿名称来使用即可;

父向子传递方法(methods)

7.2 Vue实例方法

  • $mount,手动设置挂载点

      

        {{name}}
    </div>
    <script type="text/javascript">
        let app = new Vue({
            el:"#app",
            data:{
                name:"David"
            }
        })    
        app.$mount('#app')
    </script>
    
  • $watch,侦听器,监听数据项、计算属性值的变化,一旦值变化,则自动调用$watch方法

将所有的异步操作,都写在watch里面进行实现

  <div id="app">
        出生年月:
        <input v-model="birthday" type="" name=""><br>
        年龄:<p>{{age}}</p>
    </div>
    <script type="text/javascript">
        let app = new Vue({
            el:'#app',
            data:{
                birthday:'',
                age:0
            },
            watch:{
                birthday(){
                    setTimeout(()=>{
                        this.age = new Date().getFullYear()-new Date(this.birthday).getFullYear();
                    },3000)
                }
            }
        })        
    </script>

子组件引用父组件的值:

 1     <div id="app">
 2         <com1></com1>
 3     </div>
 4     <script>
 5 
 6             Vue.component
 7             var vm = new Vue({
 8                 el:'#app',
 9                 data:{
10                     msg:"heelo !"
11                 },
12                 methods:{
13                 },
14                 components:{
15                     com1:{
16                         template:'<h1>这是子组件---{{msg}}</h1>'
17                     }
18                 }
19             })
20         </script>

执行结果:

分分快三计划 1

默认情况下子组件是不能引用父组件的属性和对象的,我们可以在引用子组件的时候,通过属性绑定的形式(v-bind)的形式,把需要传递给子组件的数据,以属性绑定的形式传递到子组件内部,供子组件使用,并且在props中声明该属性(props中的数据都是通过父组传递过来的,这里的数据是只读的),代码如下:

 1     <div id="app">
 2         <com1 v-bind:parentmsg="msg"></com1>
 3     </div>
 4     <script>
 5         Vue.component
 6         var vm = new Vue({
 7             el: '#app',
 8             data: {
 9                 msg: "heelo !"
10             },
11             methods: {
12             },
13             components: {
14                 data() {
15                     return {
16                         title: '123',
17                         content: 'pppp'
18                     }
19                 },
20                 com1: {
21                     props: ['parentmsg'],
22                     template: '<h1>这是子组件---{{parentmsg}}</h1>'
23                 }
24             }
25         })
26     </script>
<component :is="comName"></component><!--component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称-->
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册</a>

3.2 定义组件模板

组件模板中,必有一个根元素,不能直接写h1、p、span、a等内容

 为什么组件中的data必须要是一个方法,演示如下:

Html代码:

  <div id="app">
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
  </div>
  <template id="tmpl">
    <div>
      <input type="button" value=" 1" @click="increment">
      <h3>{{count}}</h3>
    </div>
  </template>

javascript代码:

    var dataObj = { count: 0 }
    //这是一个计数器的组件, 身上有个按钮,每当点击按钮,让data中的count值 1
    Vue.component('counter', {
      template: '#tmpl',
      data: function () {
        // return dataObj
        return { count: 0 }
      },
      methods: {
        increment() {
          this.count  
        }
      }
    })
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {}
    });

调用测试结果如下 :

分分快三计划 2

每个计数器的count是独立的,如将将返回的值改为:

        return dataObj
        //return { count: 0 }

结果为:

分分快三计划 3

每个组件的count是共享的,组件的data必须是一个方法,且必须返回一个对象。要解决的问题就是提高组件的复用性,防止组件与组件之间成员干扰。

③在 被控制的 #app 外面,使用 template 元素,定义组件的HTML模板结构

6.1 单个插槽

当子组件模板只有一个无属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的DOM位置,并替换掉插槽本身

    <div id="app">
        <son>
            <h3>只是标题</h3>
            <p>这是段落</p>
        </son>
    </div>
    <template id="son">
        <div>
            <slot></slot>
        </div>
    </template>
    <script type="text/javascript">
        let Son = {
            template:'#son'
        }
        let app = new Vue({
            el:'#app',
            components:{
                Son
            }
        })        
    </script>

分分快三计划 4

此时只是声明了一个叫com1的组件,如果要在vue实例中使用组件,还需要通过以下方式来注册组件:

   Vue.component('myCom1', com1)

④创建私有组件

5.2 子传父

  • 在子组件中添加事件监听,通过$emit从子组件向父组件发射一个事件
  • 在父组件中接收子组件发射过来的事件,格式:<子组件 @子组件事件名=”父组件要执行的方法”>
  • 在父组件中定义方法接收子组件传递的事件及数据

注:子组件上的事件名@addmsg不能使用驼峰法

<div id="app">
    <p>{{content}}</p>
    <!-- 3. 在父组件中接收子组件发射过来的事件 -->
    <my-collapse @addmsg="receive"></my-collapse>
</div>
<template id="my-collapse">
    <div>
        <input v-model="msg" type="" name="">
        <!-- 2. 在子组件中添加事件监听 -->
        <button @click="sendMsg">按钮</button>
    </div>    
</template>
<script type="text/javascript">
    let MyCollapse = {
        template:'#my-collapse',
        data(){
            return {
                msg:''
            }
        },
        methods:{
            //1.从子组件向父组件发射事件,参数1:事件名;参数2:传递的数据
            sendMsg(){
                this.$emit("addmsg",this.msg)
            }
        }
    }
    let app = new Vue({
        el:"#app",
        data:{
            content:''
        },
        components:{
            MyCollapse
        },
        methods:{
            //4. 在父组件中定义方法接收子组件传递的事件及数据,参数是子组件传递的数据
            receive(d){
                return this.content=d
            }
        }
  })
</script>

 私有组件:

  <template id="tmpl2">
    <h1>这是私有的 login 组件</h1>
  </template>

    var vm2 = new Vue({
      el: '#app2',
      components: { // 定义实例内部私有组件的
        login: {
          template: '#tmpl2'
        }
      },
    })

①给节点或组件写下ref标记,并起名字,ref="myh3"

7. 深入理解 Vue 实例

通过 new Vue() 获得一个对象,即 Vue实例,Vue实例提供如下属性、方法:

组件的切换:

<body>
  <div id="app">
    <a href="" @click.prevent="flag=true">登录</a>
    <a href="" @click.prevent="flag=false">注册</a>
    <login v-if="flag"></login>
    <register v-else="flag"></register>
  </div>
  <script>
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })
    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        flag: true
      },
      methods: {}
    });
  </script>
</body>

演示结果如下,默认显示登录组件,点击注册切换到注册组件,点击登录切换的登录组件。

分分快三计划 5

 

 

 

缺点分析:如果在一个需求中需要切换更多的组件,这种方式不利于扩展。

    <!-- Vue提供了component ,来展示对应名称的组件 -->

    <!-- component 是一个占位符, “:is”是属性,可以用来指定要展示的组件的名称 -->

  <div id="app">
    <a href="" @click.prevent="comName='login'">登录</a>
    <a href="" @click.prevent="comName='register'">注册</a>
    <component :is="comName"></component>
  </div>
  <script>
    // 组件名称是字符串
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })
    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' //当前component中的 :is 绑定的组件的名称
      },
    });
  </script>
<login v-if="flag"></login>
<register v-else="flag"></register>
<a href="" @click.prevent="flag=false/true">注册</a>

4. template 语法规则

组件对象的template属性用来设置组件的模板内容,模板内容有3种写法:

  • 直接写在字符串中

    <my-header></my-header>
    

  • 将模板内容写在template标签中(例子)

  • 将模板内容写在script标签中

    <my-header></my-header>
    

Vue.js 组件

  • 模块化:是从代码逻辑的角度进行划分的;
  • 组件化:是从UI界面的角度进行划分的。

组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树,如下图所示:

分分快三计划 6

示例:

6.2 具名插槽

若有多个插槽(占位符),通过name属性加以区分,这种插槽就是具名插槽(可更灵活的管理组件的内容)

  • 先定义插槽(占位符),即将内容不确定的地方使用插槽占个位置
  • 再使用插槽,即使用真实内容替换占位符

      

        <son>
            <h3 slot="title">这是标题</h3>
            <p slot="content">这是段落</p>
        </son>
    </div>
    <template id="son">
        <div>
            <slot name="title"></slot>
            <slot name="content"></slot>
        </div>
    </template>
    

组件切换动画:

html代码:

  <div id="app">
    <a href="" @click.prevent="comName='login'">登录</a>
    <a href="" @click.prevent="comName='register'">注册</a>

    <!-- 通过 mode 属性,设置组件切换时候的模式为先出后进-->
    <transition mode="out-in">
      <component :is="comName"></component>
    </transition>

  </div>

  <script>
    // 组件名称是 字符串
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })

    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' // 当前 component 中的 :is 绑定的组件的名称
      },
    });
  </script>

css代码:

  <style>
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(150px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: all 0.5s ease;
    }
  </style>
methods: {  increment() {  this.count   } }

7.1 Vue实例属性

  • $el,获取挂着 Vue 实例的元素
  • $data,获取 Vue 实例的数据项

分分快三计划 7

  • $refs,获取对DOM元素的引用

Vue 侧重于数据驱动,而jQuery侧重于dom,Vue提供了 $refs 属性对dom元素进行灵活的操作,具体使用:

    • 在元素上添加一个属性ref:<标签 ref=“keyword”
    • 在Vue实例中,通过this.$refs获取所有的dom引用

        <a href="" ref="oa">超链接</a>
        <button @click="setStyle">点击切换</button>
    </div>
    <script type="text/javascript">
        let app = new Vue({
            el:"#app",
            methods:{
                setStyle(){
                    //找到DOM节点
                    console.log(this.$refs)
                    console.log(this.$refs.oa)
                    this.$refs.oa.style.textDecoration='none'
                    this.$refs.oa.style.color='red'
                }
            }
        })        
    </script>
    

分分快三计划 8

注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素

this.$emit('func', this.sonmsg)

3.3 注册组件

注册组件,组件在哪里使用,就注册到哪里

在被控制的#app外面,使用template元素,定义组件的HTML模板结构:

  <template id="tmpl">
    <div>
      <h1>这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的智能提示和语法高亮</h1>
    </div>
  </template>

   Vue.component('mycom3', {
      template: '#tmpl' //引用template的id属性
    })

①父组件,可以在引用子组件的时候, 通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用

5.1 父传子

  • 先在父组件中定义数据

  • 在父组件的模板中,通过属性绑定把数据绑定在子组件上,语法:子组件 :变量名=”数据项”

  • 在子组件中定义props属性,用来接收父组件传递的数据

  • 在子组件模板中使用数据

  • 在子组件的函数中使用数据

    {{number}}
    <!-- 2. 把数据绑定在子组件上 -->
    <my-collapse :num="number"></my-collapse>
    

分分快三计划 9

  • props细节:每个数据项,都可有3个属性进行约束
    • type:类型约束,约束父组件给子组件传递的数据类型。类型包括:Object、Array、Number、String、Boolean
    • default:指定默认值,若父组件未传递数据,可指定默认值
    • required:指定该数据项是否必须传递

执行结果:

分分快三计划 10

我的博客即将搬运同步至腾讯云 社区,邀请大家一同入驻:

①组件可以有自己的 data 数据

8. Vue 实例的生命周期

实例化的Vue对象(根组件)以及自定义的组件对象都有生命周期,Vue 设计者为方便调试程序,提供了8个钩子函数:

    <div id="app">
      {{name}}    
    </div>
    <script type="text/javascript">
        let app = new Vue({
            data:{
                name:'David'
            },
            beforeCreate(){
                alert('beforeCreate')
            },
            created(){
                alert('created')
            },
            beforeMount(){
                alert('beforeMount')
            },
            mounted(){
                alert('mounted')
            },
            beforeUpdate(){
                alert('beforeUpdate')
            },
            updated(){
                alert('updated')
            },
            beforeDestory(){
                alert('beforeDestory')
            },
            destroyed(){
                alert('destroyed')
            }
        })    
        app.$mount('#app')
        app.$destroy('name')    
    </script>

生命周期函数作用:在不同的阶段,做相应的工作

  • created阶段,初始化数据,创建数据对象
  • mounted阶段,使用数据项替换模板,即将数据挂载到DOM元素节点上
  • updated阶段,当DOM节点中的数据发生改变,在此阶段进行更新

组件的调用: 

  <div id="app">
    <!-- 如果要使用组件,直接把组件的名称以HTML标签的形式,引入到页面中即可 -->
    <my-com1></my-com1>
  </div>
Vue.component('mycom2', {  template: '<div><h3>这是直接使用 Vue.component 创建出来的组件</h3123</div>'})

1. 组件介绍

组件(component),vue.js最强大的功能之一

  • 作用:封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能调用该功能体
  • 根组件:我们实例化的Vue对象就是一个组件,且是所有组件的根组件
  • 分类:全局组件,局部组件
  • 不足:跳转时,无法传递参数,则无法实现同一个页面根据不同的参数显示不同内容

注:每个组件都是Vue的实例对象

使用Vue.extend来创建全局vue组件:

var com1 = Vue.extend({
template: '<h3>这是使用 Vue.extend 创建的组件</h3>' // 通过template属性,指定了组件要展示的HTML结构
})
components: { login: { template: '<h1>这是私有组件</h1>'}}
<login></login>

3.4 使用组件

定义组件时用的驼峰法,使用时将驼峰法转换为帕斯卡命名

<div id="app">
    <!-- 4.使用组件 -->
    <my-header></my-header>
</div>
<!-- 2.定义组件模板 -->
<template id="my-header">
    <div>
        <h3>我是头部局部组件</h3>
        <p>{{name}}</p>
    </div>
</template>
<script type="text/javascript">
    //1.定义局部组件
    let MyHeader = {
        template:'#my-header',//组件的模板,#my-header指id为my-header的模板
        data(){
            return {
                name:"局部组件"//数据项
            }
        }
    }
    let app = new Vue({
        el:"#app",
        //3.注册组件
        components:{
            MyHeader//将MyHeader 这个组件注册到app根组件中
        }
  })
</script>

分分快三计划 11

组件中的data和methods:

  1. 组件可以有自己的data数据;
  2. 组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法;
  3. 组件中的data除了必须为一个方法之外,这个方法内部还必须返回一个对象;
  4. 组件中的data数据,使用方式和实例中的data使用方式完全一样

    Vue.component('mycom1', {
      template: '<h1>这是全局组件 --- {{msg}}</h1>',
      data: function () {
        return {
          msg: '这是组件的中data定义的数据'
        }
      }
    })
    

五、获取DOM节点和组件的引用

6. 插槽 slot

插槽,即一个占位符,能在不同环境下,传递不同的参数,并得到不同的效果,在Vue中通过slot标签实现

思路:先在子组件中定义一个占位符(插槽),再使用真实的内容替换这个插槽

其它两种创建组件的方式:

    Vue.component('myCom1', Vue.extend({
      template: '<h3>这是使用Vue.extend创建的组件</h3>'
    }))

    Vue.component('mycom2', {
      template: '<div><h3>这是直接使用Vue.component创建出来的组件</h3>123</div>'
    })

父向子传递值(data):

3. 局部组件

在父组件的 components 属性中定义。

子组件调用父组件的方法:

请详细看下面代码中的注释

 1  <div id="app">
 2      
 3     <com2 @func="show"></com2>
 4     </div>
 5     <template id="tmpl">
 6         <div>
 7             <h1>这是子组件</h1>
 8             <input type="button" value="这是子组件中的点击按钮" @click="myclick">
 9         </div>
10     </template>
11     <script>
12         //定义了一个字面量类型的组件模板对象
13         var com2 = {
14             template: '#tmpl',
15             data() {
16                 return {
17                     sonmsg: { name: 'wjl', age: 16 }
18                 }
19             },
20             methods: {
21                 myclick() {
22                     //当点击子组件的按钮时,通过$emit拿到父组件传递过来的func
23                     //emit的英文愿意为触发、调用、发射的意思
24                     this.$emit('func', this.sonmsg, 123, 456)
25                 }
26             }
27         }
28         var vm = new Vue({
29             el: '#app',
30             data: {
31                 datamsg: null
32             },
33             methods: {
34                 show(data, data1, data2) {
35                     console.log('调用了父组件的show方法:'   data.name   data1   data2);
36                 }
37             },
38             components: {
39                 com2
40             }
41         })
42     </script>
data: function () { return {  msg: '这是组件的中data定义的数据' } }

9. 动态组件

可定义多个组件,再使用 :is 属性动态地在多个组件之间切换

语法:<component v-bind:is=”组件名”></component>

Component 相当于一个占位符,具体显示哪个组件,通过:is指定

    <div id="app">
        第一个
        第二个
        <component :is="currentCom"></component>
    </div>
    <template id="com1">
        <div>第一个组件</div>
    </template>
    <template id="com2">
        <div>第二个组件</div>
    </template>
    <script type="text/javascript">
        let FirstCom={
            template:'#com1',
            mounted(){
                console.log("第一个被渲染")
            }
        }
        let SecondCom={
            template:'#com2',
             mounted(){
                console.log("第二个被渲染")
            }
        }
        let app = new Vue({
            el:"#app",
            data:{
                currentCom:''
            },
            components:{
                FirstCom,
                SecondCom
            }
        })
    </script>

分分快三计划 12

  • keep-alive 组件

无 keep-alive 组件时,每次切换组件都重新创建一次组件,使用 keep-alive后,会将创建过的组件保存在内存中,以后使用时直接使用,而不会每次重新创建

    <div id="app">
        第一个
        第二个
        <keep-alive>
            <component :is="currentCom"></component>
        </keep-alive> 
    </div>
    <template id="com1">
        <div>第一个组件</div>
    </template>
    <template id="com2">
        <div>第二个组件</div>
    </template>
    <script type="text/javascript">
        let FirstCom={
            template:'#com1',
            mounted(){
                console.log("第一个被渲染")
            }
        }
        let SecondCom={
            template:'#com2',
             mounted(){
                console.log("第二个被渲染")
            }
        }
        let app = new Vue({
            el:"#app",
            data:{
                currentCom:''
            },
            components:{
                FirstCom,
                SecondCom
            }
        })
    </script>

分分快三计划 13

②直接使用 Vue.component 创建出来的组件

3.1 定义组件对象

  • 组件对象名,采用驼峰法命名
  • 组件对象的配置项与Vue实例的配置项相似,data 数据项除外(组件对象中,data是一个方法)
template: '<h1>这是子组件---{{parentmsg}}</h1>';

5. 组件间的相互通信

组件实例是孤立的,不可在子组件中直接用父组件中的数据(组件特性:高内聚、低耦合)

父组件通过 props 向下传递数据,子组件通过 emit 向上发射事件传递数据分分快三计划 14

②调用:通过this.$refs.myh3调用,可调用组件的data和methods,this.$refs.mylogin.msg

②再把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据

③组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行

四、父子组件的单向通信

三、组件的切换

④组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样

注意:不论是哪种方式创建出来的组件,组件的 template ,属性指向的模板内容,必须有且只能有唯一的一个根元素

②私有组件的话,不用注册,外部组件需要在用到父组件注册一下

<com1 v-bind:parentmsg="msg"></com1>
<com2 @func="show"></com2>

①父组件向子组件 传递 方法,使用的是 事件绑定机制v-on, 当我们自定义了 一个 事件属性之后,那么,子组件就能够,通过某些方式,来调用 传递进去的 这个 方法了

var com1 = Vue.extend({ template: '<h3>这是使用 Vue.extend 创建的组件</h3>' })
Vue.component('myCom1', com1);

Vue提供了 component ,来展示对应名称的组件

<template id="tmpl"></template>
Vue.component('mycom3', {template: '#tmpl'})
<mycom3></mycom3><!--这种方式写组件,有提示,而且内容比较多时分配写到外面,观感更佳-->

③当点击子组件的按钮的时候,如何 拿到 父组件传递过来的 func 方法,并调用这个方法?

注意:默认子无法获得父的data数据和methods方法

①使用 Vue.extend 来创建全局的Vue组件

常见

③使用

组件里的data:

组件里的methods:

②组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法

一、组件的创建方式

二、组件中的data和methods

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划