Vue教程-2-快速入门

目录

1.父子组件通信-双向绑定

2.父组件访问子组件:children/refs

3.子组件访问父组件:parent/root

4.slot插槽

5.编译作用域

6.模块化开发

7.ES6的export/import基本使用


1.父子组件通信-双向绑定

官方推荐:修改父组件的data,来达到修改子组件props的效果,而不是直接通过v-model来修改子组件的props中的继承数据;

解决方法如下:

在子组件的data选项中,新定义数据,然后把props中数据赋值给data中新定义的变量,然后再在子组件的template中通过v-model来绑定data中新定义的变量,而不是props中的变量;

data:{

           return {新变量=this.props中的变量}

}

event.target.value

2.父组件访问子组件:children/refs

父组件访问子组件的实例对象:$children或者$refs;

this.$children返回的是一个VueComponent数组,然后通过索引去获取你想获取的哪个子组件实例对象,然后就可以访问子组件实例对象的属性、方法;

$children缺点在于:由于返回的是一个VueComponent数组,当开发者在HTML模板中添加/删除一个自定义组件的时候,就会导致开发者同时修改$children数组的索引下标,这就容易导致各种问题产生;

为了解决这个问题,可以使用$refs来取代$children;在自定义组件中添加ref=”key”的属性,然后就可以在父组件中通过this.$refs.key的形式来直接访问具体的某个VueComponent子组件,再也不用担心VueComponent数组下标的问题;

<body>

<div id="app">

    <cpn_father v-bind:cpn_movies="movies" @fatherclick="fatherclick2" ref="cpn0"></cpn_father>

    <button @click="getChildren">父组件访问子组件的实例对象</button>

</div>

<template id="cpn_template">

    <div>

        {{title}}

        <ul>

            <li v-for="item in cpn_movies" @click="itemclick(item)">{{item}}</li>

        </ul>

        <cpn_child></cpn_child>

    </div>

</template>

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

<script>

    const cpn_father =Vue.component('test_cpn',{

        template: '#cpn_template',

        data(){

            return {title: '这是自定义的子组件'}

        },

        props:{

            cpn_movies:{

                type:Array,

                required:true,

                default(){

                    return ['自定义组件的movies默认值'];

                }

            }

        },

        methods: {

            itemclick(item){

                console.log('这是自定义组件的单击事件',item);

                this.$emit('fatherclick',item);

            }

        }

    });

    const root = new Vue({

        el: '#app',

        data: {

            movies:['进击的巨人','海贼王','火影忍者','数码宝贝']

        },

        components: {

            cpn_father

        },

        methods: {

            fatherclick2(item){

                console.log('这是自定义组件发给父组件的事件',item);

            },

            getChildren(){

                console.log(this.$children);

                console.log(this.$refs.cpn0)

            }

        }

    });

</script>

</body>

3.子组件访问父组件:parent/root

子组件访问父组件的实例对象:$parent、$root;

$parent访问自己的直属上级组件,而$root则访问自己的根Vue实例;

<body>

<div id="app">

    <h1>这是Vue实例</h1>

    <cpn_father ref="cpn0"></cpn_father>

</div>

<template id="cpn_template">

    <div>

        <h2>这是Vue实例的第1层子组件</h2>

        <cpn_child></cpn_child>

    </div>

</template>

<template id="cpn_template2">

    <div>

        <h3>这是Vue实例的第1层子组件的第1层子组件,即Vue实例是该子组件的-爷爷级别</h3>

        <button @click="test">访问父组件,即Vue的第1层子组件</button>

        <button @click="test1">访问Vue组件</button>

    </div>

</template>

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

<script>

    const root = new Vue({

        el: '#app',

        data: {

            movies:['进击的巨人','海贼王','火影忍者','数码宝贝']

        },

        components: {

            cpn_father:{

                template: '#cpn_template',

                data(){

                  return {message:'Vue实例的第1层子组件'}

                },

                components:{

                    cpn_child:{

                        template: '#cpn_template2',

                        methods: {

                            test(){

                                console.log(this.$parent);// 这里返回的是VueComponent实例

                                console.log(this.$parent.message);// 这里返回的是VueComponent实例

                            },

                            test1(){

                                console.log(this.$root);// 这里返回的是Vue实例

                            }

                        }

                    }

                }

            }

        }

    });

</script>

</body>

注意:

我们开发自定义组件,是为了在不同场景下进行复用,既然是复用,你就不能去严苛规定父组件必须有哪些属性、方法,这就决定了从子组件来访问父组件实例对方的使用场景很少;

4.slot插槽

组件的插槽是为了让封装的组件更加具有扩展性,让使用者来决定组件内部来展示哪些内容;

通俗来讲,就是使用者在使用某个组件时,需要对组件进行个性化修改,但开发者又不能去修改组件源代码,此时,则可以通过slot来进行这种个性化扩展;

<slot/>定义在子组件的template中,且<slot/>中可以定义默认值;

具名插槽:当template中存在多个<slot/>时,需要对多个<slot/>起唯一性的名字,这样当在Vue实例中,可以针对某一个<slot/>进行替换;

使用规则如下:

①<slot name=”xxxx”/>

②使用的时候slot=”xxxxx”

<body>

<div id="app">

    <h1>这是Vue实例</h1>

    <cpn_father ref="cpn0">

        <p slot="middle">测试slot</p>

    </cpn_father>

</div>

<template id="cpn_template">

    <div>

        <h3>自定义组件</h3>

        <slot name="left"><button>返回</button></slot>

        <slot name="middle"><button>查询</button></slot>

        <slot name="right"><button>删除</button></slot>

    </div>

</template>

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

<script>

    const root = new Vue({

        el: '#app',

        components: {

            cpn_father:{

                template: '#cpn_template'

            }

        }

    });

</script>

</body>

5.编译作用域

如果在template中使用变量,那么变量就会去该template所绑定的实例中查找同名变量,可以总结为:父组件template的所有东西都会在父级作用域内编译、子组件template的所有东西都会在子级作用域内编译;

作用域插槽:父组件替换子组件template中的<slot/>标签,但是内容还是由子组件提供,通俗来讲就是:由父组件提供展示样式,子组件提供展示内容;

使用步骤如下:

①在子组件template中,通过变量XXX指向data中的数据;

②在父组件template中来访问XXX来间接达到访问子组件data中的数据;

③然后可以按照想要的样式来输出子组件data中的数据;

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>作用域插槽</title>

</head>

<body>

<div id="app">

    <h1>这是Vue实例</h1>

    <cpn_father ref="cpn0">

        <!-- 2.5以下必须用template -->

        <!-- slot-scope='slottest',这里的slottest是随便起的名字,而slottest.test则是代表slottest去访问在子组件template中定义的变量test,而test又指向了子组件data中的message -->

        <template slot-scope="slottest">

            <span v-for="item in slottest.test">{{item}} #-# </span>

        </template>

    </cpn_father>

    <cpn_father ref="cpn1"></cpn_father>

</div>

<template id="cpn_template">

    <div>

        <!-- :test='message',这里的test是随便起的名字,而message则是子组件中data中的message,表明test指向了template对应实例对象data中的message -->

        <slot  :test="message">

            <ul>

                <li v-for="item in message">{{item}}</li>

            </ul>

        </slot>

    </div>

</template>

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

<script>

    const app = new Vue({

        el: '#app',

        data:{

        },

        components: {

            cpn_father:{

                template: '#cpn_template',

                data(){

                    return {message: ['a','b','c','d','e','f']};

                }

            }

        }

    });

</script>

</body>

</html>

6.模块化开发

在ES6之前, JS通过闭包 + 匿名函数的方式来封装不同的模块,来实现模块化开发,此刻常见的模块化规范有:CommonJS/AMD/CMD;

CommonJS规范主要有2部分组成:导出、导入;具体流程如下:在一个名叫org.js文件中,该js文件中所有代码编写方式,与HTML中<script/>标签中的一致,CommonJS会把每个js文件当做一个独立的作用域,一个独立的模块,对于要导出的内容则通过如下代码方式来导出:module.exports = {导出内容1:导出内容1,导出内容2:导出内容2}

然后在想要使用该模块的js文件中,通过如下内容来导入:let {导出内容1,导出内容2} = require(‘org.js’);这样就可以在其他js文件中使用org.js已经定义好的变量与方法;

针对模块化开发,到了ES6才定义相关的语法:export导出、import导入;

7.ES6的export/import基本使用

<script src="xxx.js" type="module"/>,其中的type="module"代表的意思是被引入的xxx.js是一个独立的空间,与其他js文件是彼此独立的存在,如果其他js文件想要访问xxx.js中的内容,则需要在xxx.js中使用export导出,然后在使用的js文件import from导入;

export default:在某些情况下,一个模块中包含某个功能,但该功能的命名交给导入这来自己命名;

注意:一个js文件中,export default只能有一个;

import命令来加载对应的模块,注意<script src type=”module”/>,如果想一次性全部导入,则可以通过 import * as 变量名 from XXXX来实现;

HTML

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

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

<script src="js/export1.js" type="module"></script>

<script src="js/export3.js" type="module"></script>

</body>

</html>

export1.js

let name = 'export1.js';

let age = 1;

let flag = true;

 

function sum(num1,num2){

    return num1 + num2;

}

 

class T{

    run(){

        console.log('----------------------run');

    }

}

 

// 导出变量、函数、类

export {

    name,age,flag,sum,T

}

 

// export default

export default function(argument){

    console.log(argument);

}

// 导出变量

// export let name = 'export1.js';

// export let age = 1;

// export let flag = true;

 

// 导出函数

// export function sum(num1,num2){

//     return num1 + num2;

// }

 

// 导出类

// export class T{

//     run(){

//         console.log('----------------------run');

//     }

// }

export3.js

import {name,age,flag,sum,T} from './export1.js';

 

// 通过*来一次性全部导入

import * as OBJ from './export1.js';

 

console.log(OBJ.flag);

 

// export default

import testdefault from './export1.js';

 

 

if(flag){

    console.log(name,age,flag,sum(3,3));

    const t = new T();

    t.run();

    testdefault('test export default');

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值