Vue 组件使用

目录

@ 路径自动提示

使用组件的步骤

全局注册组件

注册私有组件

注册全局组件

自动闭合标签插件

自定义属性 props

props

Count.vue

Left.vue

Right.vue

集合 v-bind 使用自定义属性

props 是只读的

default 默认值

type 值类型

required 必填项

样式冲突-了解 scoped 的使用和底层实现原理

组件之间的样式冲突问题

解决样式冲突

/deep/ 样式穿透

vue 组件的实例对象


@ 路径自动提示

在 vscode 中导入下面的插件:

在设置 settings.json 插入如下配置:

    // 导入文件时是否携带文件的拓展名
    "path-autocomplete.extensionOnImport": true,
    // 配置 @ 的路径提示
    "path-autocomplete.pathMappings": {
        "@": "${folder}/src"
    },

使用组件的步骤

步骤1:使用 import 语法导入需要的组件

<script>
    import Left from "@/components/Left.vue"
    import Right from "@/components/Right.vue"
    export default {}
</script>

步骤2:使用 components 节点注册组件

<script>
    import Left from "@/components/Left.vue"
    import Right from "@/components/Right.vue"
    export default {
        components: {
            Left,
            Right
        }
    }
</script

步骤3:以标签形式使用刚才注册的组件

    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <Left></Left>
      <Right></Right>
    </div>

以上修改内容都是在 App.vue 中修改

全局注册组件

注册私有组件

在组件 A 的 components 节点下注册的组件,不能在其他与组件 A 平级的组件中使用

注册全局组件

在 vue 项目中的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件

// 导入需要全局注册的组件
import Count from "@/components/Count.vue"
// 参数1:字符串格式,表示组件的 "注册名称"
// 参数2:需要被全局注册的组件
Vue.component('MyCount', Count);

然后在需要此组件的组件中以标签形式使用接口

组件自身中不能使用自己

自动闭合标签插件

自定义属性 props

props

为 count 组件声明 props 自定义属性

props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大地提高组件的复用性

自定义属性 props 传递的是字符串,不是数值

props 中的数据,可以直接在模板结构中被使用

props 是只读的

Count.vue

<script>
    export default {
        // props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
        // props: ['自定义属性1', '自定义属性2', '自定义属性3', ...]
        props: ['init'],
    }
</script>
    <div>
        <p>count 的值是: {{ init }}</p>
        <button @click="init++">+1</button>
    </div>

Left.vue

  <div class="left-container">
    <MyCount init = "9"></MyCount>
  </div>

Right.vue

  <div class="right-container">
    <MyCount init="6"></MyCount>
  </div>

集合 v-bind 使用自定义属性

组件的封装者:Count.vue

组件的使用者:Left.vue、Right.vue

在 v-bind 中写入的内容都是 JavaScript

  <div class="left-container">
    <!-- v-bind:init="9" 传递的值就是数值 -->
    <!-- v-bind:inti="'9'" 传递的值是字符串 -->
    <MyCount :init = "9"></MyCount>
  </div>

props 是只读的

不建议直接修改 props 自定义的属性,因为将来该属性可能会被覆盖

vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props。否则会报错

要想修改 props 的值,可以把 props 的值转存到 data 中,data 中的数据是可读可写的

<template>
    <div>
        <h5>Count 组件</h5>
        <p>count 的值是: {{ count }}</p>
        <!-- 不建议直接修改 props 自定义的属性 init,因为将来 init 可能会被覆盖 -->
        <button @click="count++">+1</button>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                count: this.init,
            }
        },
        methods: {},
        // props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
        props: ['init'],
    }
</script>

上述代码中,init 只负责初始化,其他的功能实现都通过 count 

当页面中的数值发生改变时,count 值将发生改变,但 init 值并不会被改变

default 默认值

数组格式的 props 不能设置默认值

对象格式的 props 才可以设置默认值

<script>
    export default {
        // props: ['init',] 数组格式的 props 不能设置默认值
        // props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
        props: {
            init: {
                // 用 default 属性定义属性的默认值
                default: 8,
            }
        },
    }
</script>

type 值类型

在声明自定义属性时,可以通过 type 来定义属性的值类型

<script>
    export default {
        props: {
            init: {
                default: 8,
                // 用 type 属性定义属性的值类型
                // 如果传递过来的值不符合此类型,则会在终端报错
                type: Number,
            }
        },
    }
</script>

required 必填项

<script>
    export default {
        props: {
            init: {
                default: 8,
                type: Number,
                // 规定只要使用此组件的组件都必须传 init 属性,否则将会报错
                required: true,
            }
        },
    }
</script>

样式冲突-了解 scoped 的使用和底层实现原理

组件之间的样式冲突问题

默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题

导致组件之间样式冲突的根本原因是:

  • 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
  • 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素

解决样式冲突

原理:保证每一个组件中都有一个 data-v-00x,以区分每一个组件,从而解决样式冲突的问题

<template>
  <div class="left-container" data-v-001>
    <h3 data-v-001>Left 组件</h3>
    <MyCount :init = "9" data-v-001></MyCount>
  </div>
</template>
<style lang="less">
    h3[data-v-001] {
        color: darkcyan;
    }
</style>

实际开发中,只需要在 style 标签后面写上 scoped 属性,vue 就会自动为该组件的 template 中的每一个标签添加 data-v-00x,从而解决样式冲突的问题

<style lang="less" scoped>
    h3 {
        color: darkcyan;
    }
</style>

/deep/ 样式穿透

使用 deep 修改子组件中的样式

当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/ 

scoped 也是有缺陷的

父组件 Left.vue 无法直接对子组件 Count.vue 中的标签进行样式修改

<style lang="less" scoped>
    h3 {
        color: darkcyan;
    }
    
    h5 {
        color: beige;
    }
</style>

以上对子组件中 h5 标签的样式修改并不会起作用。

因为 scoped 属性只会为当前组件 Left.vue 中 template 中的标签添加 data-v-xxx。并不会为子组件标签添加 data-v-xxx

此时就需要用到 /deep/,/deep/ 将为子组件中的标签添加 data-v-xxx

<style lang="less" scoped>
    /* 原先的解决办法是 h5 [data-v-xxx] */
    /* 加上 /deep/ 之后,[data-v-xxx] h5 */
    /deep/ h5 {
        color: beige;
    }
</style>

  

vue 组件的实例对象

.vue 文件是一个模板,此模板真正被渲染到页面上,需要 vue-template-compiler 进行编译

Count.vue 可以被看作是一个构造函数

使用标签引入 Count.vue 的过程,可以看作是一个 new Vue 实例对象的过程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值