Vue - 标准开发方式、组件(全局、局部、props、事件传递)、插槽的使用

目录

一、Vue

1.1、标准开发方式

1.2、组件的使用

1.2.1、全局组件

1.2.2、局部组件

1.2.3、props 传递静态数据

1.2.4、props 传递动态数据

1.2.5、事件传递

1.2.6、插槽slot


一、Vue


1.1、标准开发方式

Vue 的标准开发方式是 SPA(Single Page Application):单页面web 应用,也就是收,日后的项目中只有一张页面(index.html).

为什么要使用 SPA 开发方式?

  1. Vue 官方推荐:一个应用中只能存在一个 Vue 实例.
  2. 复用:Vue 提供了 Component 组件,不仅减少了 Vue 实例的代码量,还可以实现复用.
  3. 解耦合:一个组负责完成项目中的一个功能或者一组功能,实现业务隔离.

1.2、组件的使用

1.2.1、全局组件

全局组件:直接注册到 Vue 根实例组件中.

定义方式:Vue.component(' ', {})  ,第一个参数是组件名,第二个参数是配置对象.

Ps:无论是使用全局组件还是局部组件,都必须在组件 template 中添加唯一根元素.

如下代码:

    <div id="app">
        <!-- 使用组件 -->
        <register></register>
    </div>

    <script src="../js/vue.js"></script>
    <script>
        //定义全局组件(生效的前提是要有 Vue 实例, 并在实例的作用域中使用)
        Vue.component('register', {
            template: `<div><h1>注册</h1><span>{{msg}}</span><span>{{counterSqrt}}</span><comp></comp></div>`,
            data() { //组件中定义数据,必须函数的形式(和 Vue 实例定义唯一的区别)
                return { //返回值是一个对象,对象内部就是数据
                    msg: "我是注册全局组件中的数据",
                    count: 2
                }
            },
            methods: { //给组件定义一些方法
                test() {
                    console.log("我是组件中的方法");
                }
            },
            computed: { //给组件定义一些计算属性
                counterSqrt() {
                    return this.count * this.count;
                }
            },
            components: { //给组件中定义一些组件
                comp: {
                    template: `<div>我是全局组件的子组件</div>`
                }
            },
            beforeCreate() { //组件也有自己的生命周期
                console.log("beforeCreate:", this.msg);//此时 msg 因该是 undefine
            }
            //......
        });

        const app = new Vue({ //没有这里,组件就不会生效
            el: "#app"
        });

效果如下:

 

1.2.2、局部组件

局部组件:只能在注册组件中使用组件.

代码如下:


    <div id="app">
        <login></login>
        <reg></reg>
    </div>

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

        //定义局部组件(这是另一种方式,现在外部定义好,再到局部注册组件中引入)
        //Ps:在子组件中不可使用父组件的数据! 比如 parent 数据
        const login = {
            template: `<div><h1>登录</h1><div>{{ child }}{{ counterSqrt }}</div><comp></comp></div>`,
            data() {
                return {
                    child: "我是注册组件的子组件 login 中的数据",
                    count: 3
                }
            },
            methods: { //给组件定义一些方法
                test() {
                    console.log("我是组件中的方法");
                }
            },
            computed: { //给组件定义一些计算属性
                counterSqrt() {
                    return this.count * this.count;
                }
            },
            components: { //给组件中定义一些组件
                comp: {
                    template: `<div>我是子组件的子组件</div>`
                }
            },
            beforeCreate() { //组件也有自己的生命周期
                console.log("beforeCreate:", this.child);//此时 child 因该是 undefine
            }
            //......
        }

        let app = new Vue({
            el: "#app",
            data: {
                parent: "我是父组件中的数据"
            },
            components: { //注册组件
                login, //也可以单独在外面定义好组件,然后引入
                reg: {
                    template: `<div><div>{{ child }}</div></div>`,
                    data() { //注意组件中数据的写法
                        return {
                            child: "我是子组件 reg 中的数据"
                        }
                    }
                }
            }
        });
    </script>

效果如下:

1.2.3、props 传递静态数据

父组件向子组件传递静态数据:在使用的组件标签上,声明静态数据 key=value (key 是自定义的),最后在子组件的 props 中声明对应的  key 即可

代码如下:

    <div id="app">
        <!-- 父组件向子组件传递静态数据:在使用的组件标签上,声明静态数据 key=value (key 是自定义的),最后在子组件的 props 中声明对应的  key 即可 -->
        <login name="hello?" count="1"></login>

    </div>

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

        const login = {
            template: `<div><h1>登录</h1><div>{{ name }} --- {{ count }}</div></div>`,
            data() {
                return {
                    //这里相当于添加了 name: "hello?", count="1"
                }
            },
            props: ['name', 'count'] //用来接收父组件传来的数据, 这就相当于在子组件的 data 中添加了这个静态数据
        }

        const app = new Vue({
            el: "#app",
            components: {
                login //注册组件
            }
        });

    </script>

效果如下:

1.2.4、props 传递动态数据

向子组件传递动态数据:

  1. 在组件标签上声明 key=value (key 是自定义的,value 就是 Vue 实例中的 data),子组件内部使用 props 数组声明 key 
  2. 声明的自定义 key 可以通过 v-bind 进行属性的动态绑定

Ps:Vue 官方明确提出只允许单向数据流,也就是只能从父传递到子,否则会报警告

代码如下:

    <div id="app">
        <!-- 向子组件中传递动态数据:
            1.在组件标签上声明 key=value (key 是自定义的,value 就是 Vue 实例中的 data),子组件内部使用 props 数组声明 key 
            2.声明的自定义 key 可以通过 v-bind 进行属性的动态绑定

            最后的效果:
            1.修改 input 中的值 
            2.由于 v-model 动态绑定到 Vue实例中的 data 的 count 数据也随之变化
            3.由于 login 组件中声明的属性 aa 动态绑定了 count,导致 属性aa 也随之变化

            注意:Vue 官方明确提出只允许单向数据流,也就是只能从父传递到子,否则会报警告
        -->
        <login :aa="count"></login>
        <input type="text" v-model="count">
    </div>

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

        const login = {
            template: `<h1><div>登录</div><h2>{{ aa }}</h2><button @click="add()">点我增加数字<button></h1>`,
            data() {
                return {

                }
            },
            props: ['aa'],
            methods: {
                add() {
                    this.aa++;//props 声明的数据,就相当于直接 data 中添加了该数据
                }
            }

        }

        const app = new Vue({
            el: "#app",
            data: {
                count: "1"
            },
            components: {
                login
            }
        });

    </script>

最后的效果:

  1. 修改 input 中的值 
  2. 由于 v-model 动态绑定到 Vue实例中的 data 的 count 数据也随之变化
  3. 由于 login 组件中声明的属性 aa 动态绑定了 count,导致 属性aa 也随之变化

如下图

1.2.5、事件传递

父向子传递事件:在组件标签上定义 @key=value (@自定义事件名=父组件中的事件名) 即可

代码如下:

    <div id="app">
        <!-- 父向子传递事件:在组件标签上定义 @key=value (@自定义事件名=父组件中的事件名) 即可 -->
        <login @aa="testParent()" @bb="testParent2" @cc="testParent3"></login>
    </div>

    <script src="../js/vue.js"></script>
    <script>
        const login = {
            template: `<div><h2>登录</h2><button @click="testChild()">点给我调用父组件中的事件</button></div>`,
            data() {
                return {
                    count: 10
                }
            },
            methods: {
                testChild() {
                    alert("我是子组件中的事件!");
                    //通过 this.$emit 来调用父组件中的事件 
                    //参数1:组件标签上定义的事件名
                    //后续参数: 参数1 后面还可以继续传递参数,作为父组件事件中的参数
                    this.$emit("aa");
                    this.$emit("bb", this.count); //Vue 官方说只能单向传递(父传子),但是这种方式可以实现
                    this.$emit("cc", { count: this.count, name: "cyk", isGood: true });
                }
            }
        }

        const app = new Vue({
            el: "#app",
            methods: {
                testParent() {
                    alert("1.我是父组件中的事件!");
                },
                testParent2(count) {
                    alert("2.我是父组件中的事件!");
                    console.log("获取到子组件的值:" + count);
                },
                testParent3(obj) {
                    alert("3.我是父组件中的事件!");
                    console.log("获取到子组件的值: count=" + obj.count + ", name=" + obj.name + ", isGood=" + obj.isGood);

                }
            },
            components: {
                login
            }
        });
    </script>

效果如下:

1.2.6、插槽slot

插槽就是用来扩展现有组件的.

代码如下:

    <div id="app">

        <!-- 插槽: 用来扩展现有组件 -->
        <login></login>
        <!-- 默认: 会将信息填入所有插槽 -->
        <hr>
        <login><span>hello</span></login>
        <!-- 具名插槽: 给 slot 标签添加 name 属性作为身份标识  -->
        <hr>
        <login><button slot="aa" @click="parent()">点我</button></login>
    </div>

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

        const login = {
            template: `<div><slot name="aa"></slot><h1>登录</h1><slot name="bb"></slot></div>`,
        }

        const app = new Vue({
            el: "#app",
            methods: {
                parent() {
                    alert("我是父组件的事件");
                }
            },
            components: {
                login
            }
        });

    </script>

效果如下:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈亦康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值