Vue基础小结

88 阅读9分钟

vue

  • 渐进式JavaScript框架拥有自己规则的语法
  • 官网地址(作者:尤雨溪)

渐进式

  • 逐步增加需求功能,逐步集成

库和框架

  • 库:封装的属性或方法(axios)
  • 框架:拥有自己的规则和元素,比库强大得多(bootstrap, vue)

开发方式

  • 传统开发方式:基于html文件开发vue
  • 工程化开发方式:在webpack环境中开发Vue(常用)

@vue/cli和脚手架介绍

  • 脚手架:保证施工过程顺利进行的工作平台,开箱即用(搭建项目)
  • @vue/cli:Vue官方提供的一个全局模块包(得到vue命令),用于创建脚手架项目

安装@vue/cli

  • 全局安装

    npm install -g @vue/cli
    
  • 查看版本

    vue -V
    

创建项目

  1. 创建项目((项目名不能有大写字母,中文和特殊符号))

    vue create xxx
    
  2. 选择模板和包管理器,等待脚手架项目创建完毕(上下键回车选择版本)

启动开发服务

  1. cd进入自定义项目下,启动内置的webpack本地热更新开发服务器 - 浏览项目页面

    cd xxx
    
    npm run serve
    
  2. 可以手动打开端口,查看浏览器页面

清理脚手架欢迎界面

  1. assets 和 components文件夹下的内容全部删除
  2. src/App.vue默认有很多内容,全部删除留下template, script 和 style的框

项目主要文件

  1. node_modules——项目npm依赖包
  2. index.html——浏览器运行的网页
  3. main.js——项目入口
  4. App.vue——页面根组件,渲染入口
  5. package.json——记录项目依赖包声明

配置端口号

  1. 在vue.config.js文件里面添加配置

    devServer:{ // 自定义服务配置
    	port:3000,
    	open:true //某些平台会出错
    }
    
  2. 重新在项目下运行命令

    npm run serve
    

eslint检查代码

  • 代码检查工具,替代jslint
  • 如果写代码违反eslint规则-报错(详细)

处理代码检查

  • 手动解决错误/自动解决

  • 暂时关闭eslint检查

    lintOnSave: false //关闭检查
    

vue单文件

  • Vue推荐采用.vue文件来开发项目
  • template里面只能有一个根标签
  • vue文件——独立模块——作用域互不影响
  • style配合scoped属性,保证样式只在当前tamplate内标签生效,否则默认全局样式
  • vue文件配合webpack,打包插入到index.html

基础-插值表达式

作用:在dom标签中,直接插入vue数据变量(动态显示)

  • 别名:声明式渲染/文本插值

    • 语法:{{ 表达式 }}

      <template>
        <div>
          <h2>{{ msg }}</h2>
        </div>
      </template>
      
      
  • 表达式和语句的区别

    • 语句:if语句,for语句
    • 表达式:
      • 变量
      • 属性
      • 三元运算符
      • 方法调用
      • 数字、字符串
  • vue数据变量

    • 需要在js的data函数里声明

    • data里面必须返回一个对象

      export default {
        data() {
          return {
            msg: "hello鸭,你好哇",
          };
        },
      };
      
      

MVVM设计模式

  • 转变思维,用数据驱动视图改变,操作dom的事情,vue源码做了

Vue指令

v-bind

基本使用

给标签属性设置vue变量的值

  • 语法

    • 写法:v-bind:属性名="vue变量"

    • 简写::属性名="vue变量"(常用)

      <img v-bind:src="imgSrc" alt="" />
      <a :href="baidu">baidu</a>
      
      
动态设置样式(v-bind)
css
  • 语法::class="{类名: 布尔值}"

    <button :class="{ 'change-color': flag, fs: !flag }" @click="fn">按钮</button>
    
    export default {
      data() {
        return {
          flag: false,
        };
      },
      methods: {
        fn() {
          this.flag = !this.flag;
        },
      },
    };
    
  • **注意:**类名如果包含横杠,用单引号包裹

style
  • 语法::style="{css属性名: 值}"

    <button :style="{ 'background-color': 'red', fontSize: '12px' }" @click="fn">按钮111</button>
    
  • **注意:**样式名如果包含横杠,用单引号包裹,或者写成小驼峰

v-on

给标签绑定事件

语法

  • v-on:事件名="少量代码"

  • v-on:事件名="method中的函数名"

  • v-on:事件名="method中的函数名(实参)"

    <button v-on:click="count++">加1</button>
    <button v-on:click="calc">+ 5</button>
    <button v-on:click="calcNew(20)">+ 20</button>
    
    
  • 简写:@事件名="methods中的函数"

    <button @click="calcNew(50)">+ 50</button>
    
    
  • 函数在methods选项里定义

    export default {
      methods: {
        calc() {
          this.count += 5;
        },
        calcNew(num) {
          this.count += num;
        },
      },
    };
    
    
v-on事件对象
  • 语法

    • 没有传参,通过形参接收

      <a :href="baidu" @click="fn">点我</a>
      
      
      fn(e) {
            e.preventDefault();
          },
      
      
    • 传参,通过$event指代事件对象传给事件处理函数

      • $event固定写法,不可更改
      <a :href="baidu" @click="fn1(12,$event)">点我</a>
      
      
      fn1(num,e) {
            e.preventDefault();
          },
      
      
v-on修饰符

事件.修饰符——带来更强大的功能

  • 语法

    • @事件名.修饰符="methods对象里面的函数"
  • 修饰符

    • .stop——阻止事件冒泡

      <div @click="say('father')">
        father
        <div @click.stop="say('son')">son</div>
      </div>
      
      
      say(dom) {
            console.log(`i am ${dom}`);
          },
      
      
    • .prevent——阻止默认行为

      <a href="javascript:;" @click.prevent="fn">url</a>
      
      
      fn() {
            console.log("阻止默认行为");
          },
      
      
    • .once——程序运行期间,只触发一次事件处理函数

      <button @click.once="fn1">我只会触发一次</button>
      
      
      fn1() {
            console.log("触发一次解除绑定");
          },
      
      
v-on按键修饰符

给键盘事件,添加修饰符,增强能力

  • 语法

    • @keydown.enter

      <div>密码:<input type="password" @keydown.enter="login" /></div>
      
      
      login(){
            console.log("触发了");
          }
      
      

v-model

value属性和vue数据变量,双向绑定

  • 语法:v-model="Vue数据变量"

  • 双向数据绑定

    • 变量变化 ---> 视图自动同步

    • 视图变化 ---> 变量自动同步

    • 表单标签常用

      • 复选框
        • v-model默认绑定checked属性
        • 可以将vue变量初始化为空数组,绑定的是选中项value
      • 单选按钮
        • 不需要设置为相同name属性
        • 绑定选中项value
      • 下拉列表
        • v-model写在select标签中
        • 绑定的是option的value
      <div>
        <h5>{{ username }}</h5>
        <div>
          用户名:
          <input type="text" v-model="username" />
        </div>
        <div>
          密码:
          <input type="password" v-model="password" />
        </div>
        <button @click="login">login</button>
      </div>
      
      
      <template>
        <div>
          <!-- 下拉列表 -->
          <div>
            城市:
            <select v-model="city">
              <option value="湛江">湛江</option>
              <option value="茂名">茂名</option>
              <option value="广州">广州</option>
            </select>
          </div>
          <!-- 复选框 -->
          <div>
            爱好:
            <input type="checkbox" value="音乐" v-model="hobby" />音乐
            <input type="checkbox" value="跳舞" v-model="hobby" />跳舞
            <input type="checkbox" value="唱歌" v-model="hobby" />唱歌
          </div>
          <!-- 单选按钮 -->
          <div>
            性别:
            <input type="radio" value="男" v-model="gender" />男
            <input type="radio" value="女" v-model="gender" />女
          </div>
          <!-- 文本框 -->
          <div>
            自我介绍:
            <textarea v-model="txt"></textarea>
          </div>
          <div>
            <button @click="getData">获取数据</button>
          </div>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            city: "",
            hobby: [],
            gender: "",
            txt: "",
          };
        },
        methods: {
          getData() {
            console.log(this.city, this.hobby, this.gender, this.txt);
          },
        },
      };
      </script>
      
      <style>
      </style>
      
      
      
v-model修饰符

让v-model拥有强大功能

  • 语法:v-model.修饰符="Vue数据变量"

    • .number——以parseFloat转成数字类型

    • .trim——去除首尾空白字符

    • .lazy——在change时触发而非input时(失去焦点,随后更新变量)

      <template>
        <div>
          <div>
            自动转换数字
            <input type="text" v-model.number="say" />
          </div>
          <div>
            去除空格
            <input type="text" v-model.trim="username" />
          </div>
          <div>
            节流
            <input type="text" v-model.lazy="pwd" />
          </div>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            say: "",
            username: "",
            pwd: "",
          };
        },
        methods: {},
      };
      </script>
      
      <style>
      </style>
      
      
      

v-for

作用:列表渲染,所在标签结构,按照数据数量,循环生成

  • 语法

    • v-for="值变量 in 目标结构"

      <ul>
        <li v-for="item in students">{{ item }}</li>
      </ul>
      
      
      students: ["杰豪", "老王", "万少"],
      
      
    • v-for="(值变量, 索引变量) in 目标结构"

      <ul>
        <li v-for="(item, idx) in food">{{ idx + 1 }}{{ item }}</li>
      </ul>
      
      
      food: ["姜葱鸡", "番茄炒蛋", "青椒包肉"],
      
      
  • 目标结构:

    • 可以遍历数组/对象/数字/字符串(可遍历结构)

    • 数字:从1开始遍历到当前数字结束

    • 对象:可以遍历(value,key)

    • 字符串:逐步把每一个字符遍历

      <!-- 遍历数字 -->
      <ul>
        <li v-for="(item, idx) in num">{{ item }}</li>
      </ul>
      <!-- 遍历对象 -->
      <ul>
        <li v-for="(item, key) in obj">{{ key }}:{{ item }}</li>
      </ul>
      <!-- 遍历字符串 -->
      <ul>
        <li v-for="(item, idx) in str">{{ item }}</li>
      </ul>
      
      
      num: 10,
      obj: {
          name: "楼下小黑",
          age: 24,
          phone: "1300000000",
        },
      str: "前端与移动开发75期班级",
      
      
  • 注意

    • v-for的临时变量名不能用到v-for范围外

v-show和v-if

控制标签显示隐藏

  • 语法

    • v-show="Vue变量"

      <p v-show="age > 18">我18了</p>
      <p v-show="age < 18">我未成年</p>
      
    • v-if="Vue变量"

      <!-- 不满足条件,直接删除整个元素 -->
      <p v-if="age > 18">我18了</p>
      <p v-if="age < 18">我未成年</p>
      
  • 原理

    • v-show——通过display:none隐藏标签(需要频繁切换渲染的时候使用)
    • v-if——不满足条件直接从DOM树上移除标签
  • 高级

    • v-if、v-else、v-else-if

    • 三者搭配使用,标签之间不可以在使用其他语法

      <template>
        <div>
          <div>
            <input type="text" v-model.number="age" />
          </div>
          <p v-if="age < 18">我未成年</p>
          <p v-else-if="age = 18">我成年</p>
          <p v-else-if="age < 50">我小于五十</p>
          <p v-else-if="age < 100">我快一百岁了</p>
          <p v-else>我长寿村长大</p>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            age: "",
          };
        },
      };
      </script>
      
      <style>
      </style>
      
      

v-text/v-html

更新DOM对象的innerText/innerHTML

  • 语法

    • v-text="Vue变量"

      <p v-text="text"></p>
      
    • v-html="Vue变量"

      <p v-html="liHtml"></p>
      
      data() {
          return {
            liHtml: "<button>我是按钮</button>",
            text: "我是纯文本",
          };
      
  • **注意:**会覆盖插值表达式

案例

翻转句子案例

  • 思路

    • 将文本内容通过split()方法分割为数组

    • 再用数组方法reverse()将数组元素自动翻转

    • 赋值回去给文本容器

      <div>
        <p>{{ msg }}</p>
        <button @click="fn">我要翻天</button>
      </div>
      
      
      methods: {
          fn() {
            const arr = this.msg.split("");
            this.msg = arr.reverse().join("");
          },
        },
      
      

折叠面板案例

<template>
  <div>
    <h1>
      折叠面板
      <button @click="show">{{ flag ? "收起面板" : "展开面板" }}</button>
    </h1>
    <div>
      <h3>静夜思</h3>
      <div v-show="flag">
        <p>床前明月光</p>
        <p>床前明月光</p>
        <p>床前明月光</p>
        <p>床前明月光</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      flag: true,
    };
  },
  methods: {
    show() {
      this.flag = !this.flag;
    },
  },
};
</script>

<style>
</style>

更新检测

数组更新

  • 数组方法修改原始数组,触发页面刷新
    • reverse()——就地更新机制,需要添加key优化
  • 数组方法不修改原始数组,不会触发页面刷新
  • 通过索引修改原始数组,不会触发页面刷新
    • 可以通过Vue给this注入的**$set方法**修改数组
      • 语法:$set(数组, index, 修改后的值)

就地更新机制

  • 数据对比更新,消耗性能
  • 优化
    • 给列表内容加上key(唯一标识)
    • 更新DOM时,会根据key比较内容,不会触发就地更新

虚拟DOM

本质是保存节点关键信息的JS对象

过滤器

转换格式,是一个函数,传入值返回处理后的值

  • 过滤器只能在插值表达式v-bind动态属性里使用

  • Vue过滤器场景

    • 字符串翻转
    • 字母转大写
  • 语法

    • Vue.filter("过滤器", value => {return "处理后的值"}(全局写法,且要在main.js文件写,因为需要一个个声明过滤器,所以不加s)

      <p>转换大写:{{ msg | toUpper }}</p>
      
      // 全局过滤器
      Vue.filter("toUpper", (str) => {
        return str.toUpperCase();
      });
      
    • filters:{过滤器名字(value) => {return "处理后的值"}}

      <p>价格:{{ price | initPrice }}</p>
      <p>转换大写:{{ msg | toUpper }}</p>
      
      export default {
        data() {
          return {
            price: 239,
            msg: "hello",
          };
        },
        methods: {},
        filters: {
          initPrice(num) {
            return `${num}¥`;
          },
        },
      };
      

过滤器传参、多过滤器

可同时使用多个过滤器,或者传参

  • 语法

    • 传参:vue变量 | 过滤器(实参)

      <p>价格:{{ price | initPrice("$","wait to buy") }}</p>
      
      filters: {
          initPrice(num,format,str) {
            return `${num} ${format} <--- ${str}`;
          },
        },
      
    • 多过滤器:vue变量 | 过滤器1 | 过滤器2

      <p>转换大写:{{ msg | toUpper | reverseFn }}</p>
      
      // 过滤器
      Vue.filter("toUpper", (str) => {
        return str.toUpperCase();
      });
      // 过滤器
      Vue.filter("reverseFn", (str) => {
        console.log(str);
        return str.split("").slice(0).reverse().join("");
      });
      

时间格式化(moment包)

创建时间以YYYY-MM-DD格式显示

  • 在哪个文件使用,就在哪个文件导入moment包

计算属性computed

根据一些数据计算而来的结果

  • 语法

    • <p>总价:{{ sum }}={{ a }}+{{ b }}</p>
      <input type="text" v-model.number="a" />
      
      export default {
        data() {
          return {
            a: 10,
            b: 20,
          };
        },
        computed: {
          sum() {
            return this.a + this.b;
          },
        },
      };
      
  • 作用:计算属性依赖的数据变化是,计算属性会重新运算

  • **注意:**计算属性也是vue数据变量,所以不要和data里的数据重名,不要使用括号语法

  • 默认情况下,计算属性,只知道怎么取值

  • 改变计算属性,它还不知道怎么办

  • 所以需要加上set函数

    • 主动改变计算属性的时候,需要设置set让计算属性知道该怎么处理改动的值

完整写法——计算属性

  • 语法

    computed:{
    	"属性名":{
    		get(){
    			
    			return 值
    		},
    		set(){
    			
    		}
    	}
    }
    

缓存

  • 计算属性,基于依赖项的值进行缓存,依赖的变量不变,都直接从缓存取结果

侦听器watch

侦听data/computed属性值的改变

  • 作用:侦听数据改变前后(获得新旧数据)

  • 语法

    watch:{
    	"被侦听的属性名"(newVal,oldVal){
    		
    	}
    }
    

深度侦听和立即执行

侦听复杂类型,立即执行侦听函数

  • 语法

    user: {
    		  // 立即执行函数
          // 深度侦听复杂类型,必须设置
          deep: true,
          handler(newVal, oldVal) {
            
          },
        },
    

组件

可复用的Vue实例,封装标签,样式和JS代码

  • 组件化——封装思想
    • 把页面上可用的部分或者拆分部分封装为组件,从而方便项目的开发和维护
    • 各自独立,互不影响

基础使用

组件都是独立个体,代码里体现为一个独立的.vue文件

  • 步骤

    1. 创建组件,封装要复用的标签,样式,JS代码

    2. 注册组件

      • 全局注册——main.js文件内

        import 组件对象 from 'vue文件路径'
        
        Vue.component("组件名", 组件对象)
        
      • 局部注册——.vue文件内

        import 组件对象 from 'vue文件路径'
        
        export default {
        	component:{
        		"组件名": 组件对象
        	}
        }
        
    3. 使用组件

      <template>
        <div id="app">
          <h3>折叠面板</h3>
          <组件名></组件名> 
          <组件名></组件名>
        </div>
      </template>
      

独立样式

  • scoped
    • 避免组件样式互相污染
  • 注意
    • 继承不受影响
    • 根元素不受影响
    • 权重问题

组件通信-父传子

父组件 ==> 子组件 传值

  • 首先明确父与子是谁,在父文件引入子文件(引入子)
    • 父亲:App.vue
    • 儿子:MyProduct.vue
  • 创建MyProduct.vue
  • 步骤
    1. 子组件内,定义变量,准备接收,然后使用变量
    2. 父组件内,引入组件,注册组件,使用组件,传值进去
组件通信-父向子-配合循环

父组件 => 子组件 循环使用-传值

单向数据流

子组件修改父组件传递过来的数据,会报错

  • 原因
    • 子组件修改,不通知父组件,造成数据不一致性
    • Vue规定props里的变量,本身是只读
  • 结论
    • 从父组件到子组件的数据流向,称为单向数据流
子传父-自定义事件

子组件中自定义事件方法

  1. 子组件内,当用户点击按钮,自定义一个事件,并将数据通过该事件传递出去。
  2. 父组件内,绑定子组件中的自定义事件和事件处理函数
    1. 语法:@自定义事件名="父methods里函数名"

生命周期-钩子函数

Vue框架内置函数,随着组件的生命周期阶段自动执行

  • 作用:特定时间,特定操作
  • 分类:4个阶段8个方法(前后)
    • 初始化
      • beforeCreate
      • created(数据data获取完毕,还没能获取真是DOM)
    • 挂载
      • beforeMount
      • mounted(页面渲染完毕,与window.onload相似)
    • 更新
      • beforeUpdate
      • updated(数据更新完毕,可获取更新后的DOM)
    • 销毁
      • beforeDestroy
      • destroyed(手动消除计时器,定时器,全局事件)
      • 应用:限时活动

axios

  • 特点
    • 专门支持客户端发送Ajax请求()
      • 一种前端一部请求后端的技术
      • 原理:浏览器window接口的XMLHttpRequest
    • 支持服务端Node.js发送请求
    • 支持Promise相关用法(.then
      • 任何官方文档提到会返回promise,直接用.then方法
    • 支持请求和相应的拦截器功能
    • 自动转换JSON数据
  • axios底层还是原生js实现,内部通过Promise封装的

uncaught错误

  • 请求的时候出现uncaught错误时,说明没有

请求参数

  • params
    • 会在请求地址后面带上参数
  • data(post专用)
    • 直接将参数加入请求体

基地址

  • 设置在src/utils/request.js文件中
<script>
import axios from "axios";
axios.defaults.baseURL = "http://123.57.109.30:3006";

封装全局axios

  • api/books.js
import axios from "@/utils/request";
// 获取图书
export function getBooks(params) {
  return axios.get("/getbooks", { params });
}
// 添加图书
export function addBook(data) {
  return axios.post("/addbook", {
    appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a",
    ...data,
  });
}

  • App.vue文件中引用books.js中的函数

  • methods: {
      getBooks() {
        getBooks()
          .then((res) => {
            console.log(res);
          })
          .catch((err) => {
            console.log(err);
          });
      },
      addBook() {
        addBook(this.bookData)
          .then((res) => {
            console.log(res);
          })
          .catch((err) => {
            console.log(err);
          });
      },
    },
    

获取DOM

通过id或者ref属性获取原生DOM

  • 在mounted生命周期 – 2种方式获取原生DOM标签
  1. 目标标签添加id或者ref

    <MyBox id="myBox" ref="MyBoxRef" />
    
  2. 通过id / ref属性获取标签

    console.log(document.querySelector("#myBox"));
    console.log(this.$refs.MyBoxRef);
    

获取组件对象

ref属性获取组件对象

  1. 组件添加ref

    <MyBox id="myBox" ref="MyBoxRef" />
    
  2. 通过ref属性获取组件对象

    console.log(this.$refs.MyBoxRef);
    

vue-异步更新DOM

点击改data, 获取原生DOM内容

<template>
  <div>
    <button @click="toggle">显示输入框</button>
    <div class="box" v-if="isShow" ref="BoxRef"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: true,
    };
  },
  methods: {
    toggle() {
      this.isShow = !this.isShow;
       console.log(this.$refs.BoxRef);
    },
  },
};
</script>

<style>
.box {
  width: 400px;
  height: 400px;
  background-color: pink;
}
</style>
  • Vue更新DOM是异步的

$nextTick使用

等DOM更新后, 触发此方法里函数体执行

  • 可以解决dom元素异步更新问题
<template>
  <div>
    <button @click="toggle" v-if="!isShow">显示输入框</button>
    <input class="box" v-if="isShow" ref="search" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: false,
    };
  },
  methods: {
    toggle() {
      this.isShow = !this.isShow;
      this.$nextTick(() => {
        this.$refs.search.focus();
      });
    },
  },
};
</script>

<style>
</style>

props

  • props:[]
    • 不规定传入格式
    • 自己封装常用
  • props:{}
    • 规定传过来的规则格式
    • 团队合作常用

组件进阶

动态组件

多个组件使用同一个挂载点,并动态切换

  1. 准备需要切换的2个组件
  2. 引入到App.vue注册
  3. 准备变量来承载要显示的“组件名”
  4. 设置挂载点, 使用is属性来设置要显示哪个组件
<template>
  <div>
    <button @click="componentsName='UserInfo'">个性签名</button>
    <button @click="componentsName='UserName'">用户账号</button>
    <component :is="componentsName"/>
  </div>
</template>

<script>
import UserName from "@/components/UserName.vue";
import UserInfo from "@/components/UserInfo.vue";
export default {
  components: {
    UserName,
    UserInfo,
  },
  data() {
    return {
      componentsName: "UserName",
    };
  },
};
</script>

<style>
</style>

组件缓存

让切换显示的组件不用来回创建销毁,提升性能和用户体验

  • vue内置的keep-alive组件包起来要频繁切换的组件

    <keep-alive>
    	<component :is="componentsName" />
    </keep-alive>
    
  • 被包裹的组件没有createdestroy钩子函数

组件激活和非激活

扩展2个新的生命周期方法

  • 在子组件
    • export default(){}里面写上activated(){}deactivated(){}
    • 被缓存包裹的组件才会生效

组件插槽

通过slot标签,让组件内可以接受不同的标签结构显示

  • 给组件插入什么标签,组件就显示什么标签

  • 语法

    • 组件内用占位

    • 使用组件时<组件><组件/>包夹的位置,传入标签替换

      <!-- PersonBox组件 -->
      <template>
        <div class="single">
            <div class="left"></div>
            <div class="right">
                <slot/>
            </div>
        </div>
      </template>
      
      // App.vue文件
      <template>
        <div>
          <PersonBox>
            <button>设置</button>
            <button>报表</button>
          </PersonBox>
          <PersonBox>
            <button>详情</button>
          </PersonBox>
        </div>
      </template>
      
      <script>
      import PersonBox from "@/components/PersonBox.vue";
      export default {
        components: {
          PersonBox,
        },
      };
      </script>
      
插槽默认内容

如果外面不传,可以写默认显示内容

  • 用法:内放置内容,作为默认显示内容
具名插槽

一个组件内有2处以上需要外部传入标签的地方

  • 语法

    1. 使用name属性区分名字