03-vue基础入门③(侦听器、计算属性、组件)

1. 侦听器

1.1 watch侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作

<body>
    <div id="app">
        <span>{{flag ? '选中' : '未选中'}}</span><br>
        <input type="checkbox" v-model="flag"><br>

        <input type="text" placeholder="请输入姓名" v-model="info.name">
        <input type="text" placeholder="请输入年龄" v-model="info.age">
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                flag: true,
                info: {
                    name: '',
                    age: null,
                },
            },
            watch: {
                flag: {
                    // handler 是固定写法,表示当侦听数据的值变化时,自动调用 handler 处理函数
                    handler(newVal) {
                        if (newVal == true) {
                            console.log('我选中了');
                        }
                    },
                    immediate: true,
                },
                info: {
                    handler(newVal) {
                        console.log('姓名' + newVal.name + ',年龄:' + newVal.age);
                    },
                    deep: true
                },
                'info.age': {
                    handler(newVal) {
                        console.log(newVal);
                    },
                }
            },
            filters: {},
            methods: {},
        });
    </script>
</body>

在这里插入图片描述

  • 默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项。
  • 如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选 项。
  • 可以监听对象里单个属性的变化

2. 计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值。
这个动态计算出来的属性值可以被模板结构或 methods 方法使用。

  • 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
  • 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算
<style>
    .box {
        width: 200px;
        height: 200px;
        margin-top: 20px;
    }
</style>

<body>
    <div id="app">
        <div>
            <span>R:</span>
            <input type="text" v-model.number="r">
        </div>
        <div>
            <span>G:</span>
            <input type="text" v-model.number="g">
        </div>
        <div>
            <span>B:</span>
            <input type="text" v-model.number="b">
            <button @click="show">{{`rgb(${r}, ${g}, ${b})`}}</button>
        </div>
        <div class="box" :style="{ backgroundColor: rgb }"></div>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                r: 0,
                b: 0,
                g: 0
            },
            computed: {
                rgb() {
                    return `rgb(${this.r}, ${this.g}, ${this.b})`
                }
            },
            methods: {
                show() {
                    console.log(this.rgb);
                }
            },
            watch: {},
            filters: {},
        });
    </script>
</body>

在这里插入图片描述

3. vue-cli

3.1 什么是单页面应用

单页面应用程序(英文名:Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成

3.2 什么是 vue-cli

vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程。(脚手架)
中文官网:https://cli.vuejs.org/zh/

3.3 安装和使用

安装:npm install -g @vue/cli
使用:vue create projectNamevue ui

3.4 vue 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。

  • App.vue 用来编写待渲染的模板结构
  • index.html 中需要预留一个 el 区域
  • main.js 把 App.vue 渲染到了 index.html 所预留的区域中

4. 组件

4.1 什么是组件化开发

组件化开发指的是:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。

4.2 vue 中的组件化开发

vue 是一个支持组件化开发的前端框架。
vue 中规定:组件的后缀名是.vue

4.3 组件的三个组成部分

每个 .vue 组件都由 3 部分构成,分别是:

  • template 组件的模板结构
  • script 组件的 JavaScript 行为
  • style 组件的样式

其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。

template

vue 规定:每个组件对应的模板结构(DOM),需要定义到<template> 节点中。

  • template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
  • template 中只能包含唯一的根节点
<template>
  <!-- 当前组件的DOM结构,需要定义到template标签的内部 -->
</template>

script

vue 规定:开发者可以在 <script> 节点中封装组件的 JavaScript 业务逻辑

<script>
//组件相关的data数据、methods方法等,都要定义到export default所导出的对象中
export default {}
</script>
  • .vue 组件中的 data 必须是函数,否则多个组件实例会共用同一份数据
export default {
  ...,
  data(){
    return{
    }
  },
  ...,
}

style

vue 规定:组件内的<style>节点是可选的,开发者可以在 <style>节点中编写样式美化当前组件的 UI 结构。(之前css)

  • 能支持less语法
<style lang="less">
...
</style>

4.4 组件之间的关系

组件在被封装之后,彼此相互独立,不存在父子关系
在这里插入图片描述

在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系
在这里插入图片描述

使用组件的三个步骤

在App.vue组件内:
①使用import语法导入需要的组件

import HelloWorld from './components/HelloWorld.vue'

②使用components节点注册组件

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}

③以标签形式使用刚才注册的组件

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

通过components注册的是私有子组件

在组件 A 的 components 节点下,注册了组件 F。
则组件 F 只能用在组件 A 中;不能被用在组件 B 中。

注册全局组件

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

//导入需要全局注册的组件
import HelloWorld from './components/HelloWorld.vue'

//参数一:字符串格式,组件的注册名称
//参数而:需要被注册的那个组件
Vue.component('HelloWorld',HelloWorld)

4.5 组件的props

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

props: ['自定义属性1', '自定义属性2', '自定义属性3', ...]

props: {
  //自定义属性名:类型
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

props 是只读的

vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。要想修改 props 的值,可以把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的!

props 的 default 默认值

在声明自定义属性时,可以通过 default 来定义属性的默认值。

export default {
  props: {
    init:{
      default:0
    }
  }
}

props 的 type 值类型

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

export default {
  props: {
    init:{
      default:0,
      type:Number
    }
  }
}

props 的 required 必填项

在声明自定义属性时,可以通过 required 选项,将属性设置为必填项,强制用户必须传递属性的值。

export default {
  props: {
    init:{
      default:0,
      type:Number,
      required:true
    }
  }
}

4.6 组件之间的样式冲突问题

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

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

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

解决组件样式冲突的问题

为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域

style 节点的 scoped 属性

为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped属性,从而防止组件之间的样式冲突问题

它会自动为每一个组件分配唯一的“自定义属性”,并自动为当前组件的DOM标签和style样式应用这个属性,以防止组件的样式冲突问题

<style scoped>
...
</style>

/deep/ 样式穿透

如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样
式对子组件生效,可以使用 /deep/深度选择器

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值