(VueJs)组件化

全局和局部组件


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div id="app">

    <my-cpn>my-cpn>
    <my-cpn>my-cpn>
    <my-cpn>my-cpn>

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

    //1、创建组件构造器对象
    //``定义的字符可以换行
    const cpnC=Vue.extend({
        template:`
        

我是标题

内容

`
}) //2、注册组件 注意:组件不能定义在Vue后面 Vue.component('my-cpn',cpnC); const app=new Vue({ el:'#app', data:{ message:'你好', sex:'123', agree:false, balls:[], vegetable:'请选择', fruits:[] } })
script> body> html>

组件化的基本运用:

  1. 创建组件构造器对象,关键词extend()
    Vue.extend()通常是在创建组件构造器时,传入template代表我们自定义组件的模板,该模板就是在使用到组件的地方显示的html代码
const cpnC=Vue.extend({
        template:`
        

我是标题

内容

`
})
  1. 注册组件
    注意:组件不能定义在Vue后面,关键词:component()
    Vue.component()是将刚才的左键构造器注册为一个组件,并起一个标签名;参数:标签名+组件构造器;这种组件注册方式默认是全局组件

注册方式一:

 Vue.component('my-cpn',cpnC);//默认全局

注册方式二:

//局部组件
        components:{
        //cpn是使用标签时的标签名
            cpn:cpnC
        }
  1. 组件运用
    直接用注册时用的标签在html中声明
    (VueJs)组件化_第1张图片

父组件和子组件


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div id="app">
    
    <cpn>cpn>
	<cpnC11>cpnC11>
div>
<script src="../../js/vue.js">script>
<script>

    //1、创建组件构造器对象1和2
    const cpnC1=Vue.extend({
        template:`
        

我是标题1

内容1

`
}) const cpnC11=Vue.extend({ template:`

我是标题11

内容11

`
}) const cpnC2=Vue.extend({ template:`

我是标题2

内容2

`
, components:{ cpnC1:cpnC1, cpnC11:cpnC11 } }) // //2、注册组件 注意:组件不能定义在Vue后面 // Vue.component('my-cpn',cpnC); const app=new Vue({ el:'#app', data:{ message:'你好', sex:'123', agree:false, balls:[], vegetable:'请选择', fruits:[] }, components:{ cpn:cpnC2 } })
script> body> html>

运行结果:
(VueJs)组件化_第2张图片
在div外的cpnC11没有被包含
整理:
就是子组件注册时在 父组件定义的代码段注册
子组件不能再html代码中直接用
父组件中的会优先从父组件的compontent中找,若没有再去全局定义中找,找到替换编译

语法糖注册方式:

省去了extend

全局组件:
js:

Vue.component('cpnC1',{
        template:`
        

我是标题

内容

`
})

html:

<conC1>conC1>

(VueJs)组件化_第3张图片

局部组件语法糖:

js:

        components:{
            'cnp2':{
                template:`
                    

我是标题2

内容2

`
} }

html:

<cnp2>cnp2>

(VueJs)组件化_第4张图片

将template的html代码分离出去

第一种:script标签:text/x-template

html代码:

<script type="text/x-template" id="fenli">
<div>
    <h2>我是分离标题</h2>
    <p>分离内容</p>
</div>
</script>

js代码:

//定义的局部组件,在Vue对象中的components中
  components:{
            'cnp3':{
                template:'#fenli'
            }
        }

(VueJs)组件化_第5张图片

第二种:template


html代码:

<template id="fenli">
<div>
    <h2>我是分离标题</h2>
    <p>分离内容</p>
</div>
</template>

Vue组件数据的存放

重要:组件内部不能访问实例(Vue)的data中的数据
组件中数据定义在components中的data中,注意这里的data返回的是一个方法(目的:闭包,当多次调用同一个组件的时候,不会数据错乱),区别于Vue实例的data

js:

//定义一个局部组件
components:{
            'cnp3':{
                template:'#fenli3',
                data(){
                    return {
                        title:'我是data标题'
                    }
                }
            }
        }

html:

<template id="fenli3">
    <div>
        <h2>{{title}}h2>
        <p>数据data内容p>
    div>
template>


<cnp3>cnp3>

(VueJs)组件化_第6张图片

父子组件的信息传递

父传子 关键词:props

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件数据传递title>
head>
<body>
<div id="app">
    <cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>

<template id="fenli3">
    <div>
        <h2>{{cmovies}}h2>
        <p>{{cmessage}}p>
    div>
template>
<script src="../../js/vue.js">script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
            message:'你好',
            sex:'123',
            movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
        },
        components:{
            'cnp3':{
                template:'#fenli3',
                data(){
                    return {
                        title:'我是data标题'
                    }
                },
                //父传子  props
                props:['cmessage','cmovies']
            }
        }
    })
script>
body>
html>

(VueJs)组件化_第7张图片
分析:
实现组件cnp3从Vue实例中获取movies、message数据
注册组件时添加props属性:

const app=new Vue({
        el:'#app',
        data:{
            message:'你好',
            sex:'123',
            movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
        },
        components:{
            'cnp3':{
                template:'#fenli3',
                data(){
                    return {
                        title:'我是data标题'
                    }
                },
                //父传子  props
                props:['cmessage','cmovies']
            }
        }
    })

这是定义的局部组件,在Vue实例中注册的
然后在cnp3标签应用的时候动态绑定

<div id="app">
    <cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>

在组件cnp3中应用,这里用的是cmessage而非message

<template id="fenli3">
    <div>
        <h2>{{cmovies}}h2>
        <p>{{cmessage}}p>
    div>
template>
子传父 关键词: 发射:$emit(标识名) 接收:v-on@标识名

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件子传父title>
head>
<body>

<div id="app">
    <cnp3 @itemclick="cpnClick">cnp3>
div>

<template id="fenli3">
    <div>
        <h2>子组件h2>
        <button v-for="item in categories" @click="btnclick(item)">{{item.name}}button>
    div>
template>
<script src="../../js/vue.js">script>
<script>
    const app=new Vue({
        el:'#app',
        methods:{
            cpnClick(item){
                console.log('------'+item.name)
            }
        },
        data:{
            message:'你好',
            sex:'123',
            movies:['海蜇王','海贼王','灌篮高手','火影忍者'],

        },
        components:{
            'cnp3':{
                template:'#fenli3',
                data(){
                    return {
                        title:'我是data标题',
                        categories:[
                            {id:1,name:'热门推荐'},
                            {id:2,name:'电视剧'},
                            {id:3,name:'电影'},
                            {id:4,name:'综艺节目'},
                        ]
                    }
                },
                //父传子  props
                props:['cmessage','cmovies'],
                methods:{
                    btnclick(item){
                        console.log(item);
                        //$emit方法是子传父的关键词,参数:标识符,参数
                        this.$emit('itemclick',item)
                    }
                }
            }
        }
    })
script>
body>
html>

执行结果:
(VueJs)组件化_第8张图片
热门推荐、电视剧、电影、综艺都是在子组件cnp3中的数据中,父组件中没有;当点击按钮热门推荐时——>触发

//$emit方法是子传父的关键词(发射),参数:标识符,参数
this.$emit('itemclick',item)

在父组件中进行接收


<div id="app">
    <cnp3 @itemclick="cpnClick">cnp3>
div>

触发cpnClick方法——>

cpnClick(item){
  	console.log('------'+item.name)
}

打印item的name属性

父访问子 关键词:$children和 $refs
子访问父 关键词:$parent

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件子传父title>
head>
<body>
<div id="app">
    <cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>

<template id="fenli3">
    <div>
        <h2>子组件h2>
        <button @click="btnclick">按钮button>
    div>
template>
<script src="../../js/vue.js">script>
<script>
    const app=new Vue({
        el:'#app',
        data:{
            message:'你好',
            sex:'123',
            movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
        },
        components:{
            'cnp3':{
                template:'#fenli3',
                data(){
                    return {
                        title:'我是data标题'
                    }
                },
                //父传子  props
                props:['cmessage','cmovies'],
                methods:{
                    btnclick(){
                        //访问父组件   关键词$parent
                        console.log(this.$parent);
                        //访问跟组件
                        console.log(this.$root)
                    }
                }
            }
        }
    })
script>
body>
html>

执行:
(VueJs)组件化_第9张图片
打印了一个Vue实例对象

你可能感兴趣的:(前端)