• Vue2+Vue3基础入门到实战项目全套教程的学习笔记


    内容的视频链接点击此处可进入

    这套笔记是按照视频和视频笔记总结的笔记,主要是方便vue的学习或温习,基本抛弃css样式的添加,专注于vue的使用。

    第一天

    Vue 快速上手

    Vue的概念

    Vue 是一个用于 构建用户界面 的 渐进式 框架
    在这里插入图片描述

    创建实例

    在这里插入图片描述
    el 指定挂载点,选择器指定控制的是哪个盒子

    插值表达式{{ }}

    利用表达式进行插值,渲染到页面中
    表达式:是可以被求值的代码,JS引擎会将其计算出一个结果)
    在这里插入图片描述

    响应式特性

    响应式:数据变化,视图自动更新
    在这里插入图片描述

    开发者工具

    在这里插入图片描述

    Vue 指令

    v-html

    作用:设置元素的 innerHTML
    语法:v-html = "表达式 "
    在这里插入图片描述

    v-show

    1. 作用: 控制元素显示隐藏
    2. 语法: v-show = “表达式” 表达式值 true 显示, false 隐藏
    3. 原理: 切换 display:none 控制显示隐藏
    4. 场景: 频繁切换显示隐藏的场景

    v-if

    1. 作用: 控制元素显示隐藏(条件渲染)
    2. 语法: v-if = “表达式” 表达式值 true 显示, false 隐藏
    3. 原理: 基于条件判断,是否 创建 或 移除 元素节点
    4. 场景: 要么显示,要么隐藏,不频繁切换的场景

    v-else

    1. 作用: 辅助 v-if 进行判断渲染
    2. 语法: v-else v-else-if = “表达式”
    3. 注意: 需要紧挨着 v-if 一起使用

    v-on

    1. 作用: 注册事件= 添加监听 + 提供处理逻辑
    2. 语法:
      ① v-on:事件名 = “内联语句”
      ② v-on:事件名 = “methods中的函数名”
    3. 简写:@事件名
    4. 注意:methods函数内的 this 指向 Vue 实例

    v-bind

    1. 作用: 动态的设置html的标签属性→ src url title …
    2. 语法: v-bind:属性名=“表达式”
    3. 注意: 简写形式 :属性名=“表达式”

    v-for

    1. 作用: 基于数据循环, 多次渲染整个元素→ 数组、对象、数字…
    2. 遍历数组语法:
      v-for = “(item, index) in 数组”
      Ø item 每一项, index 下标
      Ø 省略 index: v-for = “item in 数组”
    v-for 中的 key

    key作用:
    给元素添加的唯一标识,便于Vue进行列表项的正确排序复用。
    注意点:

    1. key 的值只能是 字符串 或 数字类型
    2. key 的值必须具有 唯一性
    3. 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)

    v-model

    1. 作用:给表单元素使用,双向数据绑定→ 可以快速 获取 或 设置 表单元素内容
      ① 数据变化 → 视图自动更新
      ② 视图变化 → 数据自动更新
    2. 语法: v-model = '变量

    总结案例

    <template>
      <div>
        
        <div v-html="htmlContent">div>
    
        
        <div v-show="showElement">这是一个可显示的元素div>
    
        
        <div v-if="condition">条件为真时显示这个div>
        <div v-else>条件为假时显示这个div>
    
        
        <button @click="handleClick">点击我button>
    
        
        <a :href="link">点击跳转a>
    
        
        <ul>
          <li v-for="(item, index) in items" :key="index">{{ item }}li>
        ul>
    
        
        <input v-model="message" placeholder="输入消息">
        <p>您输入的消息是: {{ message }}p>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          htmlContent: '这是一段HTML内容',
          showElement: true,
          condition: true,
          link: 'https://www.example.com',
          items: ['项1', '项2', '项3'],
          message: ''
        };
      },
      methods: {
        handleClick() {
          alert('按钮被点击了!');
        }
      }
    };
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    综合案例-小黑记事本

    列表渲染 / 删除功能 / 添加功能 / 底部统计 / 清空
    在这里插入图片描述
    功能总结:
    ① 列表渲染:
    v-for key 的设置 {{ }} 插值表达式
    ② 删除功能
    v-on 调用传参 filter 过滤 覆盖修改原数组
    ③ 添加功能
    v-model 绑定 unshift 修改原数组添加
    ④ 底部统计 和 清空
    数组.length累计长度
    覆盖数组清空列表
    v-show 控制隐藏

    第二天

    指令补充

    指令修饰符

    通过 . 指明一些指令 后缀,不同 后缀 封装了不同的处理操作 → 简化代码
    ① 按键修饰符
    @keyup.enter → 键盘回车监听
    ② v-model修饰符
    v-model.trim → 去除首尾空格
    v-model.number → 转数字
    ③ 事件修饰符
    @事件名.stop → 阻止冒泡
    @事件名.prevent → 阻止默认行为

    v-bind对于样式操作的增强

    为了方便开发者进行样式控制, Vue 扩展了 v-bind 的语法,可以针对 class 类名style 行内样式 进行控制 。

    v-bind 对于样式控制的增强 - 操作class

    语法 :class = “对象/数组”
    ① 对象 → 键就是类名,值是布尔值。如果值为 true,有这个类,否则没有这个类

    <div class="box" :class="{ 类名1: 布尔值, 类名2: 布尔值 }">div>
    
    • 1

    适用场景:一个类名,来回切换
    ② 数组 → 数组中所有的类,都会添加到盒子上,本质就是一个 class 列表
    v-bind 对于样式控制的增强 - 操作class

    <div class="box" :class="[ 类名1, 类名2, 类名3 ]">div>
    
    • 1

    适用场景:批量添加或删除类 e.g.

    :class="['pink', 'big']"
    
    • 1
    v-bind 对于样式控制的增强 - 操作style

    语法 :style = “样式对象”

    <div class="box" :style="{ CSS属性名1: CSS属性值, CSS属性名2: CSS属性值 }">div>
    
    • 1

    适用场景:某个具体属性的动态设置

    v-model应用于其他表单元素

    常见的表单元素都可以用 v-model 绑定关联 → 快速 获取 或 设置 表单元素的值

    它会根据 控件类型 自动选取 正确的方法 来更新元素
    输入框 input:text→ value
    文本域 textarea→ value
    复选框 input:checkbox→ checked
    单选框 input:radio→ checked
    下拉菜单 select→ value

    总结案例

    <template>
      <div>
        
        <h2>部分 1: 指令修饰符h2>
        <button @click.once="handleClick">点击一次button>
        <p v-show="showElement">这个元素通过 v-show 显示p>
        <input v-model.trim="inputText" placeholder="去除输入内容两边的空格" />
    
        
        <h2>部分 2: v-bind 对于样式控制的增强 - 操作classh2>
        <div :class="{ active: isActive, error: hasError }">样式由v-bind:class动态绑定div>
    
        
        <h2>部分 3: v-bind 对于样式控制的增强 - 操作styleh2>
        <div :style="dynamicStyles">样式由v-bind:style动态绑定div>
    
        
        <h2>部分 4: v-model应用于其他表单元素h2>
        <input type="checkbox" v-model="isChecked" /> 是否选中: {{ isChecked }}
    
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          // 部分 1: 指令修饰符
          inputText: '',
          showElement: true,
    
          // 部分 2: v-bind 对于样式控制的增强 - 操作class
          isActive: true,
          hasError: false,
    
          // 部分 3: v-bind 对于样式控制的增强 - 操作style
          dynamicStyles: {
            color: 'blue',
            fontSize: '20px'
          },
    
          // 部分 4: v-model应用于其他表单元素
          isChecked: false
        };
      },
      methods: {
        // 部分 1: 指令修饰符
        handleClick() {
          alert('按钮被点击了!');
        }
      }
    };
    script>
    
    <style>
      /* 部分 2: v-bind 对于样式控制的增强 - 操作class */
      .active {
        background-color: lightgreen;
      }
      .error {
        color: red;
        font-weight: bold;
      }
    style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    computed计算属性

    基础语法

    概念:基于现有的数据,计算出来的新属性。 依赖的数据变化,自动重新计算。
    语法:
    ① 声明在 computed配置项中,一个计算属性对应一个函数
    ② 使用起来和普通属性一样使用 {{ 计算属性名 }}
    计算属性 → 可以将一段 求值的代码 进行封装
    在这里插入图片描述

    computed 计算属性 vs methods 方法

    computed 计算属性:
    作用:封装了一段对于数据的处理,求得一个结果。
    语法:
    ① 写在 computed 配置项中
    ② 作为属性,直接使用 → this.计算属性 {{ 计算属性 }}

    缓存特性(提升性能):
    计算属性会对计算出来的结果缓存,再次使用直接读取缓存,
    依赖项变化了,会自动重新计算 → 并再次缓存

    methods 方法:
    作用:给实例提供一个方法,调用以处理业务逻辑。
    语法:
    ① 写在 methods 配置项中
    ② 作为方法,需要调用 → this.方法名( ) {{ 方法名() }} @事件名="方法名"

    完整写法

    计算属性默认的简写,只能读取访问,不能 “修改”。
    如果要 “修改” → 需要写计算属性的完整写法。
    在这里插入图片描述

    成绩案例

    在这里插入图片描述
    业务技术点总结:

    1. 渲染功能(不及格高亮)
      v-if v-else v-for v-bind:class
    2. 删除功能
      点击传参 filter过滤覆盖原数组
      .prevent 阻止默认行为
    3. 添加功能
      v-model v-model修饰符(.trim .number)
      unshift 修改数组更新视图
    4. 统计总分,求平均分
      计算属性 reduce求和

    watch侦听器

    基础语法

    作用:监视数据变化,执行一些 业务逻辑 或 异步操作。
    语法:
    ① 简单写法 → 简单类型数据,直接监视
    ② 完整写法 → 添加额外配置项
    在这里插入图片描述

    <template>
      <div>
        <input v-model="inputText" placeholder="输入内容" />
        <p>翻译结果: {{ translatedText }}p>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          inputText: '',
          translatedText: ''
        };
      },
      watch: {
        inputText(newText) {
          // 在输入内容变化时触发翻译操作
          this.translatedText = this.translate(newText);
        }
      },
      methods: {
        translate(text) {
          // 实现翻译逻辑的函数
          // 这里可以调用翻译服务或实现自定义翻译逻辑
          // 返回翻译后的文本
          return text.toUpperCase(); // 示例:将输入的文本转为大写
        }
      }
    };
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    完整写法

    ② 完整写法 → 添加额外配置项
    (1) deep: true 对复杂类型深度监视
    (2) immediate: true 初始化立刻执行一次handler方法
    在这里插入图片描述

    <template>
      <div>
        <input v-model="inputText" placeholder="输入内容" />
        <select v-model="selectedLanguage">
          <option value="en">英语option>
          <option value="fr">法语option>
          <option value="es">西班牙语option>
        select>
        <p>翻译结果: {{ translatedText }}p>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          inputText: '',
          selectedLanguage: 'en', // 默认语言为英语
          translatedText: ''
        };
      },
      watch: {
        inputText(newText) {
          // 在输入内容或语言选择变化时触发翻译操作
          this.translatedText = this.translate(newText, this.selectedLanguage);
        },
        selectedLanguage(newLanguage) {
          // 在语言选择变化时触发翻译操作
          this.translatedText = this.translate(this.inputText, newLanguage);
        }
      },
      methods: {
        translate(text, language) {
          // 实现翻译逻辑的函数
          // 根据选择的语言调用翻译服务或实现自定义翻译逻辑
          // 返回翻译后的文本
          // 这里需要根据language参数选择不同的翻译方式
          return text.toUpperCase() + ' (' + language + ')'; // 示例:将输入的文本转为大写,并附加语言标识
        }
      }
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述

    <template>
      <div>
        <input v-model="inputText" placeholder="输入内容" />
        <select v-model="selectedLanguage">
          <option value="en">英语option>
          <option value="fr">法语option>
          <option value="es">西班牙语option>
        select>
        <p>默认文本: {{ defaultText }}p>
        <p>翻译结果: {{ translatedText }}p>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          inputText: '',
          selectedLanguage: 'en', // 默认语言为英语
          defaultText: 'Hello, World!', // 默认文本
          translatedText: ''
        };
      },
      watch: {
        inputText(newText) {
          // 在输入内容或语言选择变化时触发翻译操作
          this.translatedText = this.translate(newText, this.selectedLanguage);
        },
        selectedLanguage(newLanguage) {
          // 在语言选择变化时触发翻译操作
          this.translatedText = this.translate(this.inputText, newLanguage);
        }
      },
      mounted() {
        // 在页面加载后立即触发翻译操作
        this.translatedText = this.translate(this.defaultText, this.selectedLanguage);
      },
      methods: {
        translate(text, language) {
          // 实现翻译逻辑的函数
          // 根据选择的语言调用翻译服务或实现自定义翻译逻辑
          // 返回翻译后的文本
          // 这里需要根据language参数选择不同的翻译方式
          return text.toUpperCase() + ' (' + language + ')'; // 示例:将输入的文本转为大写,并附加语言标识
        }
      }
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    综合案例:水果购物车

    渲染 / 删除 / 修改数量 / 全选反选 / 统计总价 / 持久化

    在这里插入图片描述
    业务技术点总结:

    1. 渲染功能: v-if/v-else v-for :class
    2. 删除功能: 点击传参 filter过滤覆盖原数组
    3. 修改个数:点击传参 find找对象
    4. 全选反选:计算属性computed 完整写法 get/set
    5. 统计选中的总价和总数量: 计算属性computed reduce条件求和
    6. 持久化到本地: watch监视,localStorage,JSON.stringify, JSON.parse
    <template>
      <div class="app-container">
        
        <div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" />div>
        
        <div class="breadcrumb">
          <span>🏠span> /
          <span>购物车span>
        div>
        
        <div class="main" v-if="fruitList.length > 0">
          <div class="table">
            
            <div class="thead">
              <div class="tr">
                <div class="th">选中div>
                <div class="th th-pic">图片div>
                <div class="th">单价div>
                <div class="th num-th">个数div>
                <div class="th">小计div>
                <div class="th">操作div>
              div>
            div>
            
            <div class="tbody">
              <div v-for="(item, index) in fruitList" :key="item.id" class="tr" :class="{ active: item.isChecked }">
                <div class="td"><input type="checkbox" v-model="item.isChecked" />div>
                <div class="td"><img :src="item.icon" alt="" />div>
                <div class="td">{{ item.price }}div>
                <div class="td">
                  <div class="my-input-number">
                    <button :disabled="item.num <= 1" class="decrease" @click="sub(item.id)"> - button>
                    <span class="my-input__inner">{{ item.num }}span>
                    <button class="increase" @click="add(item.id)"> + button>
                  div>
                div>
                <div class="td">{{ item.num * item.price }}div>
                <div class="td"><button @click="del(item.id)">删除button>div>
              div>
            div>
          div>
          
          <div class="bottom">
            
            <label class="check-all">
              <input type="checkbox" v-model="isAll" />
              全选
            label>
            <div class="right-box">
              
              <span class="price-box">总价  :  ¥ <span class="price">{{ totalPrice }}span>span>
              
              <button class="pay">结算( {{ totalCount }} )button>
            div>
          div>
        div>
        
        <div class="empty" v-else>🛒空空如也div>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          fruitList: [
            {
              id: 1,
              icon: 'http://autumnfish.cn/static/火龙果.png',
              isChecked: true,
              num: 2,
              price: 6,
            },
            {
              id: 2,
              icon: 'http://autumnfish.cn/static/荔枝.png',
              isChecked: false,
              num: 7,
              price: 20,
            },
            {
              id: 3,
              icon: 'http://autumnfish.cn/static/榴莲.png',
              isChecked: false,
              num: 3,
              price: 40,
            },
            {
              id: 4,
              icon: 'http://autumnfish.cn/static/鸭梨.png',
              isChecked: true,
              num: 10,
              price: 3,
            },
            {
              id: 5,
              icon: 'http://autumnfish.cn/static/樱桃.png',
              isChecked: false,
              num: 20,
              price: 34,
            },
          ],
        };
      },
      computed: {
        isAll: {
          get() {
            return this.fruitList.every(item => item.isChecked);
          },
          set(value) {
            this.fruitList.forEach(item => (item.isChecked = value));
          },
        },
        totalCount() {
          return this.fruitList.reduce((sum, item) => (item.isChecked ? sum + item.num : sum), 0);
        },
        totalPrice() {
          return this.fruitList.reduce((sum, item) => (item.isChecked ? sum + item.num * item.price : sum), 0);
        },
      },
      methods: {
        del(id) {
          this.fruitList = this.fruitList.filter(item => item.id !== id);
        },
        add(id) {
          const fruit = this.fruitList.find(item => item.id === id);
          fruit.num++;
        },
        sub(id) {
          const fruit = this.fruitList.find(item => item.id === id);
          if (fruit.num > 1) {
            fruit.num--;
          }
        },
      },
    };
    script>
    
    <style scoped>
    /* 样式放在这里 */
    @import "../css/inputnumber.css";
    @import "../css/index.css";
    style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    第三天

    生命周期

    生命周期&生命周期的四个阶段

    Vue生命周期:一个Vue实例从 创建 到 销毁 的整个过程。
    生命周期四个阶段:① 创建 ② 挂载 ③ 更新 ④ 销毁
    在这里插入图片描述

    生命周期钩子

    Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】→ 让开发者可以在【特定阶段】运行自己的代码。
    在这里插入图片描述

    生命周期案例

    综合案例:小黑记账清单

    列表渲染(请求) / 添加 / 删除 / 饼图渲染
    在这里插入图片描述
    在这里插入图片描述

    工程化开发入门

    工程化开发和脚手架

    基本介绍:
    Vue CLI 是 Vue 官方提供的一个全局命令工具。
    可以帮助我们快速创建一个开发 Vue 项目的标准化基础架子。【集成了 webpack 配置】
    在这里插入图片描述
    使用步骤:

    1. 全局安装 (一次) :yarn global add @vue/cli 或 npm i @vue/cli -g
    2. 查看 Vue 版本:vue --version
    3. 创建项目架子:vue create project-name(项目名-不能用中文)
    4. 启动项目: yarn serve 或 npm run serve(找package.json)

    在这里插入图片描述

    项目运行流程

    在这里插入图片描述

    组件化

    ① 组件化:一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。
    好处:便于维护,利于复用 → 提升开发效率。
    组件分类:普通组件、根组件。

    ② 根组件:整个应用最上层的组件,包裹所有普通小组件。
    一个根组件App.vue,包含的三个部分:
    1.template 结构 (只能有一个根节点)
    2.style 样式 (style标签,lang="less" 开启less功能,需要装包 less 和 less-loader )yarn add less less-loader
    3.script 行为

    在这里插入图片描述

    组件注册

    组件注册的两种方式:

    1. 局部注册:只能在注册的组件内使用
    2. 全局注册:所有组件内都能使用
      在这里插入图片描述
    局部注册

    步骤:
    ① 创建 .vue 文件 (三个组成部分)
    ② 在使用的组件内导入并注册
    使用:
    ◆ 当成 html 标签使用 <组件名>
    注意:
    ◆ 组件名规范 → 大驼峰命名法,如:HmHeader
    在这里插入图片描述

    全局注册

    步骤:
    ① 创建 .vue 文件 (三个组成部分)
    ② main.js 中进行全局注册
    使用:
    ◆ 当成 html 标签使用 <组件名>
    注意:
    ◆ 组件名规范 → 大驼峰命名法,如:HmHeader
    技巧:
    ◆ 一般都用局部注册,如果发现确实是通用组件,再定义到全局。
    在这里插入图片描述

    综合案例:小兔鲜首页

    拆分模块-局部注册 / 结构样式完善 / 拆分组件 – 全局注册

    第四天

    组件的三大组成部分(结构/样式/逻辑)

    在这里插入图片描述

    scoped样式冲突

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

    1. 全局样式: 默认组件中的样式会作用到全局
    2. 局部样式: 可以给组件加上 scoped 属性, 可以让样式只作用于当前组件

    scoped原理?

    1. 当前组件内标签都被添加 data-v-hash值 的属性
    2. css选择器都被添加 [data-v-hash值] 的属性选择器
      最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到

    在这里插入图片描述

    data是一个函数

    一个组件的 data 选项必须是一个函数。→ 保证每个组件实例,维护独立的一份数据对象。
    每次创建新的组件实例,都会新执行一次 data 函数,得到一个新对象。
    在这里插入图片描述

    组件通信

    组件通信, 就是指 组件与组件 之间的数据传递。
    ⚫ 组件的数据是独立的,无法直接访问其他组件的数据。
    ⚫ 想用其他组件的数据 → 组件通信

    组件通信语法

    不同的组件关系

    组件关系分类:

    1. 父子关系
    2. 非父子关系

    在这里插入图片描述

    组件通信解决方案

    在这里插入图片描述
    父子通信流程图:

    1. 父组件通过 props 将数据传递给子组件
    2. 子组件利用 $emit 通知父组件修改更新
      在这里插入图片描述

    父传子

    在这里插入图片描述

    子传父

    在这里插入图片描述

    关于props

    什么是 prop

    Prop 定义:组件上 注册的一些 自定义属性
    Prop 作用:向子组件传递数据

    特点:
    ⚫ 可以 传递 任意数量 的prop
    ⚫ 可以 传递 任意类型 的prop
    在这里插入图片描述

    props 校验

    作用:为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误
    语法:
    ① 类型校验
    ② 非空校验
    ③ 默认值
    ④ 自定义校验
    在这里插入图片描述

    prop & data、单向数据流

    共同点:都可以给组件提供数据。
    区别:
    ⚫ data 的数据是自己的 → 随便改
    ⚫ prop 的数据是外部的 → 不能直接改,要遵循 单向数据流
    单向数据流:父级 prop 的数据更新,会向下流动,影响子组件。这个数据流动是单向的。
    在这里插入图片描述

    综合案例:小黑记事本(组件版)

    拆分组件 / 渲染 / 添加 / 删除 / 统计 / 清空 / 持久化

    进阶语法

    v-model原理

    原理:v-model本质上是一个语法糖。例如应用在输入框上,就是 value属性 和 input事件 的合写。
    作用:提供数据的双向绑定
    ① 数据变,视图跟着变 :value
    ② 视图变,数据跟着变 @input
    注意:$event 用于在模板中,获取事件的形参
    在这里插入图片描述

    v-model应用于组件

    1. 表单类组件 封装→ 实现 子组件 和 父组件数据 的双向绑定
      ① 父传子:数据 应该是父组件 props 传递 过来的,拆解 v-model 绑定数据
      ② 子传父:监听输入,子传父传值给父组件修改
      在这里插入图片描述
    2. 父组件 v-model 简化代码,实现 子组件 和 父组件数据 双向绑定
      ① 子组件中:props 通过 value 接收,事件触发 input
      ② 父组件中:v-model 给组件直接绑数据( :value + @input )
      在这里插入图片描述
      注意,这种方法的value和input的命名是必须和图中一样固定的,而不是上上一张图可以随意指定

    sync修饰符

    作用:可以实现 子组件 与 父组件数据 的 双向绑定,简化代码
    特点:prop属性名,可以自定义,非固定为 value
    场景:封装弹框类的基础组件, visible属性 true显示 false隐藏
    本质:就是 :属性名 和 @update:属性名 合写
    在这里插入图片描述

    ref和$refs

    $nextTick

    第五天

    自定义指令

    基本语法(全局&局部注册)

    指令的值

    v-loading指令封装

    插槽

    默认插槽

    作用:让组件内部的一些 结构 支持 自定义
    需求: 将需要多次显示的对话框, 封装成一个组件
    问题:组件的内容部分,不希望写死,希望能使用的时候自定义。怎么办?
    在这里插入图片描述
    插槽基本语法:

    1. 组件内需要定制的结构部分,改用占位
    2. 使用组件时, 标签内部, 传入结构替换slot
      在这里插入图片描述

    后备内容(默认值)

    通过插槽完成了内容的定制,传什么显示什么, 但是如果不传,则是空白
    能否给插槽设置 默认显示内容 呢?
    在这里插入图片描述
    插槽后备内容:封装组件时,可以为预留的 插槽提供后备内容(默认内容)。
    l 语法: 在 标签内,放置内容, 作为默认显示内容
    l 效果:
    在这里插入图片描述

    具名插槽

    需求:一个组件内有多处结构,需要外部传入标签,进行定制
    (默认插槽:一个的定制位置)
    在这里插入图片描述
    具名插槽语法:
    在这里插入图片描述具名插槽简化语法:
    在这里插入图片描述

    作用域插槽

    作用域插槽: 定义 slot 插槽的同时, 是可以传值的。给 插槽 上可以 绑定数据,将来 使用组件时可以用。
    场景:封装表格组件

    1. 父传子,动态渲染表格内容
    2. 利用默认插槽,定制操作列
    3. 删除或查看都需要用到 当前项的 id,属于 组件内部的数据
      通过 作用域插槽 传值绑定,进而使用
      在这里插入图片描述
      基本使用步骤:

    1.给 slot 标签, 以 添加属性的方式传值
    在这里插入图片描述

    2.所有添加的属性, 都会被收集到一个对象中
    在这里插入图片描述

    3.在template中, 通过 #插槽名= "obj" 接收,默认插槽名为 default
    在这里插入图片描述

    综合案例:商品列表

    路由入门

    单页应用程序SPA - Single Page Application

    单页面应用(SPA): 所有功能在 一个html页面 上实现
    在这里插入图片描述

    路由概念

    Vue中路由:路径 和 组件 的 映射 关系
    根据路由就能知道不同路径的,应该匹配渲染哪个组件
    在这里插入图片描述

    VueRouter的基本使用(5+2)

    5个基础步骤 (固定)
    在这里插入图片描述
    2 个核心步骤
    在这里插入图片描述

    组件目录存放问题(组件分类)

    组件分类: .vue文件分2类; 页面组件 & 复用组件
    注意:都是 .vue文件 (本质无区别)
    分类开来 更易维护

    1. src/views文件夹
      页面组件 - 页面展示 - 配合路由用
    2. src/components文件夹
      复用组件 - 展示数据 - 常用于复用

    页面组件 - views文件夹 => 配合路由,页面展示
    复用组件 - components文件夹 => 封装复用
    在这里插入图片描述

    第六天

    路由进阶

    ① 路由模块封装

    问题:所有的路由配置都堆在main.js中合适么?
    目标:将路由模块抽离出来。 好处:拆分模块,利于维护
    在这里插入图片描述

    ② 声明式导航 & 导航高亮 / 精确匹配&模糊匹配 / 自定义高亮类名/声明式导航传参 ( 查询参数传参 & 动态路由传参 )

    声明式导航 & 导航高亮

    需求:实现导航高亮效果
    vue-router 提供了一个全局组件 router-link (取代 a 标签)
    ① 能跳转,配置 to 属性指定路径(必须) 。本质还是 a 标签 ,to 无需 #
    ② 能高亮,默认就会提供高亮类名,可以直接设置高亮样式
    在这里插入图片描述

    精确匹配&模糊匹配

    在这里插入图片描述

    ① router-link-active 模糊匹配 (用的多)
    to=“/my” 可以匹配 /my /my/a /my/b …
    ② router-link-exact-active 精确匹配
    to=“/my” 仅可以匹配 /my

    自定义高亮类名

    在这里插入图片描述
    linkActiveClass 模糊匹配 类名自定义
    linkExactActiveClass 精确匹配 类名自定义

    声明式导航传参 ( 查询参数传参 & 动态路由传参 )

    目标:在跳转路由时, 进行传值
    在这里插入图片描述
    方法:

    1. 查询参数传参
      ① 语法格式如下
      to="/path?参数名=值"
      ② 对应页面组件接收传递过来的值
      $route.query.参数名
      在这里插入图片描述

    2. 动态路由传参

    ① 配置动态路由
    在这里插入图片描述
    ② 配置导航链接
    to="/path/参数值"
    ③ 对应页面组件接收传递过来的值
    $route.params.参数名
    在这里插入图片描述
    两种传参方式的区别

    1. 查询参数传参 (比较适合传多个参数)
      ① 跳转:to="/path?参数名=值&参数名2=值"
      ② 获取:$route.query.参数名
    2. 动态路由传参 (优雅简洁,传单个参数比较方便)
      ① 配置动态路由:path: "/path/参数名"
      ② 跳转:to="/path/参数值"
      ③ 获取:$route.params.参数名

    在这里插入图片描述

    ③ 路由重定向 / 路由404 / 路由模式

    路由重定向

    问题:网页打开, url 默认是 / 路径,未匹配到组件时,会出现空白
    说明:重定向 → 匹配path后, 强制跳转path路径
    语法: { path: 匹配路径, redirect: 重定向到的路径 },
    在这里插入图片描述

    路由404

    作用:当路径找不到匹配时,给个提示页面
    位置:配在路由最后
    语法:path: "*", (任意路径) – 前面不匹配就命中最后这个
    在这里插入图片描述

    路由模式

    问题: 路由的路径看起来不自然, 有#,能否切成真正路径形式?
    hash路由(默认) 例如: http://localhost:8080/#/home
    history路由(常用) 例如: http://localhost:8080/home (以后上线需要服务器端支持)
    在这里插入图片描述

    ④ 编程式导航 / 编程式导航传参 ( 查询参数传参 & 动态路由传参 )

    编程式导航

    问题:点击按钮跳转如何实现?
    编程式导航:用JS代码来进行跳转
    在这里插入图片描述

    两种语法:
    ① path 路径跳转 (简易方便)
    在这里插入图片描述

    ② name 命名路由跳转(适合 path 路径长的场景)

    在这里插入图片描述

    编程式导航传参 ( 查询参数传参 & 动态路由传参)

    问题:点击搜索按钮,跳转需要传参如何实现?
    两种传参方式:查询参数 + 动态路由传参
    两种跳转方式,对于两种传参方式都支持:
    ① path 路径跳转传参(query传参)
    在这里插入图片描述

    ① path 路径跳转传参 (动态路由传参)
    在这里插入图片描述

    ② name 命名路由跳转传参 (query传参)
    在这里插入图片描述

    ② name 命名路由跳转传参 (动态路由传参)
    在这里插入图片描述

    面经基础版

  • 相关阅读:
    力扣打卡之两数之和【有序数组和无序数组】
    初步了解android如何锁键
    Shell第四章《正则表达式》
    03 【流程控制语句】
    如果使用Vue要做根据已有的图形填入到指定的单元格中,你会怎么做?
    AD敷铜报polygon not repour after edit[已解决]
    2.9.C++项目:网络版五子棋对战之业务处理模块的设计
    反射详细说明
    【每日一题Day38】LC809情感丰富的文字 | 双指针 模拟
    MYSQL使用binlog日志恢复数据
  • 原文地址:https://blog.csdn.net/qq_44154915/article/details/132968498