Vue框架插槽(第八课)

简介: Vue框架插槽(第八课)

案例 组件信息的通信

自己思考一下 答案在本文章的后面

插槽 v-slot

这个时候我们就可以来定义插槽slot: 插槽的使用过程其实是抽取共性、预留不同;

我们会将共同的元素、内容依然在组件内进行封装;

同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;

如何使用slot呢?

Vue中将  元素作为承载分发内容的出口;

在封装组件中,使用特殊的元素就可以为封装组件开启一个插槽;

该插槽插入什么内容取决于父组件如何使用;


插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。简单理解就是子组件中留下个“坑”,父组件可以使用指定内容来补“坑”.


页面控制平台

案例一

这个案例带你去理解啥是插槽

主页面

   <template #bbb>
        name=BBB请输入密码:<input type="password" name="" id="" />
      </template>
<template>
  <div class="App">
    <headerTab>
      <!-- v-solt 插槽 名称 -->
      <template v-slot:aaa>
        <a href="name=AAA返回按钮<">name=AAA返回按钮</a>
      </template>
      <template #bbb>
        name=BBB请输入密码:<input type="password" name="" id="" />
      </template>
      <template #ccc>
        name=CCC:<input type="Number">
      </template>
      <template #ddd>name=DDD <input type="checkbox" name="" id="" />男 </template>
      <template #eee> name=EEE<input type="checkbox" name="" id="" />女</template>
      <template #[msg]><button>name=fff你好呀</button> </template>
    </headerTab>
    <headerTab>
      <template #[msg]>
        <button>返回按钮</button>
      </template>
      <template v-slot:aaa>
        <a href="#">返回按钮</a>
      </template>
      <template #bbb>
        请输入密码:<input type="password" name="" id="" />
      </template>
      <template #ccc>
        点击按钮:<button>{{ msg }}</button>
      </template>
      <template #ddd> <input type="checkbox" name="" id="" />男 </template>
      <template #eee> <input type="checkbox" name="" id="" />女</template>
    </headerTab>
    <button @click="msg = 'left'">left</button>
    <button @click="msg = 'center'">center</button>
    <button @click="msg = 'right'">right</button>
    <button @click="msg = 'left'">left</button>
    <button @click="msg = 'aaa'">aaa</button>
    <button @click="msg = 'bbb'">bbb</button>
    <button @click="msg = 'ccc'">ccc</button>
    <button @click="msg = 'ddd'">ddd</button>
    <p>返回</p>
    <hr />
    <headerTab :propList="propList">
      <template v-slot="slotProps">
        <div>{{ slotProps.item + "&nbsp;&nbsp;&nbsp;" + slotProps.index }}</div>
      </template>
    </headerTab>
    <hr />
    <!-- <headerTab :propList="propList" v-slot="slotProps"> -->
    <!-- <div>{{slotProps.item+'-'+slotProps.index}}</div> -->
    <!-- </headerTab> -->
  </div>
</template>
<script>
import headerTab from "./components/header-tab.vue";
export default {
  name: "App",
  components: {
    headerTab,
  },
  data() {
    return {
      msg: "我是登录按钮",
      propList: ["王者荣耀", "JavaScript", "Jquery", "Web", "EEEE"],
    };
  },
  methods: {},
};
</script>
<style scoped>
div{
  border-top: 2px solid red;
  background-color: rgb(124, 188, 225);
}
</style>

子组件

 <div class="content">
  <div class="item left">
    <slot name="aaa"> 请输入姓名:<input type="text" /> </slot>
  </div>
  <div class="item"><slot name="bbb">请输入邮箱地址:<input type="emil" /></slot></div>
  <div class="item"><slot name="ccc">我是a链接:<a href="#">我是a标签</a></slot></div>
  <div class="item center">
    <!-- 命令 -->
    <slot name="ddd">标题</slot>
  </div>
  <div class="item right">
    <slot name="eee">登录</slot>
  </div>


<template>
  <div class="content">
    <div class="item left">
      <slot name=" item lefts"> 请输入姓名:<input type="text" /> </slot>
    </div>
    <div class="item">请输入邮箱地址:<input type="emil" /></div>
    <div class="item">我是a链接:<a href="#">我是a标签</a></div>
    <div class="item center">
      <slot name="center">标题</slot>
    </div>
    <div class="item right">
      <slot name="right">登录</slot>
    </div>
  </div>
  <div class="content">
  <div class="item left">
    <slot name="aaa"> 请输入姓名:<input type="text" /> </slot>
  </div>
  <div class="item"><slot name="bbb">请输入邮箱地址:<input type="emil" /></slot></div>
  <div class="item"><slot name="ccc">我是a链接:<a href="#">我是a标签</a></slot></div>
  <div class="item center">
    <!-- 命令 -->
    <slot name="ddd">标题</slot>
  </div>
  <div class="item right">
    <slot name="eee">登录</slot>
  </div>
</div>
  <div>
  <div class="item" v-for="item,index in propList" :key="item">
  <slot :item="item" :index="index">登录信息</slot>
  <slot name="two">我是数据信息</slot>
  </div>
  </div>
</template>
<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "left",
  props: ["propList"],
  data() {
    return {
      msg: "子组件的msg",
    };
  },
  methods: {},
};
</script>
<style scoped>
.content {
  display: flex;
  height: 50px;
  line-height: 50px;
  text-align: center;
  display: flex;
}
.item {
  margin-top: 3px;
  border-left: 2px solid red;
  flex: 1;
  background-color: rgb(166, 236, 167);
  color: rgb(0, 0, 0);
}
.left {
  background: rgb(171, 220, 223);
}
.center {
  background: rgb(50, 174, 28);
}
.right {
  background: rgb(10, 155, 213);
}
</style>

案例二  兄弟的组件直接转送值

定义对象的属性值

 

取出值展示在页面上

主页面

<template>
  <div class="app">
    <h3 style="color:red">Provide和Inject基本使用</h3>
    <home></home>
    <hr>
    <content></content>
  </div>
</template>
<script>
import content from "./components/content.vue";
import home from "./components/home.vue";
export default {
  name: "app",
  data() {
    return {
      message: "Hello world vue cli",
    };
  },
  components: {
    // eslint-disable-next-line vue/no-unused-components
    content,
    // eslint-disable-next-line vue/no-unused-components
    home,
  },
  methods: {
    btnclick() {
      console.log("为难忘");
    },
  },
};
</script>
<style scoped>
</style>

子组件1

<template>
  <div class="content">
    <home></home>
  </div>
</template>
<script>
import home from "../components/home.vue";
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "content",
  data() {
    return {
      message: "Hello world vue cli",
    };
  },
  // 定义对象
  provide: {
    name: "李四",
    age: 20,
    height: 123,
    weight: 78,
    email: "2678903458@qq.com",
    qq: "2386754567",
    weixing: "12389999933",
  },
  // 函数的写法
  methods: {
    btnclick() {
      console.log("为难忘");
    },
  },
  components: {
    // eslint-disable-next-line vue/no-unused-components
    home,
  },
};
</script>
<style scoped>
</style>


 // 定义对象
  provide: {
    name: "李四",
    age: 20,
    height: 123,
    weight: 78,
    email: "2678903458@qq.com",
    qq: "2386754567",
    weixing: "12389999933",
  }

子组件2

  //   取值
  inject: ["name", "age", "height", "weight", "email", "qq", "weixing"],
<template>
  <h6>
    在home.vue组件中和content组件中利用 provide定义对象 利用 inject取出对象
  </h6>
  <div class="home">
    <content></content>
    <table>
      <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>身高</th>
        <th>体重</th>
        <th>邮箱</th>
        <th>qq</th>
        <th>微信</th>
      </tr>
      <tr>
        <td>
          <span>{{ name }}</span>
        </td>
        <td>
          <span>{{ age }}</span>
        </td>
        <td>
          <span>{{ height }}</span>
        </td>
        <td>
          <span>{{ weight }}</span>
        </td>
        <td>
          <span>{{ email }}</span>
        </td>
        <td>
          <span>{{ qq }}</span>
        </td>
        <td>
          <span>{{ weixing }}</span>
        </td>
      </tr>
    </table>
  </div>
</template>
<script>
import content from '../components/content.vue'
// home 与content组件为兄弟元素
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: "home",
  data() {
    return {
      message: "Hello world vue cli",
    };
  },
  components: {
    // eslint-disable-next-line vue/no-unused-components
    content
  },
  //   取值
  inject: ["name", "age", "height", "weight", "email", "qq", "weixing"],
  methods: {
    btnclick() {
      console.log("为难忘");
    },
  },
};
</script>
<style scoped>
.home {
  background-color: rgb(214, 248, 177);
  display: flex;
}
.home span {
  font-size: 20px;
  background-color: rgb(236, 253, 239);
  color: red;
  flex: 1;
}
table {
  width: 100%;
  background-color: rgb(176, 230, 232);
  color: rgb(255, 0, 0);
  font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
}
td {
  width: 18%;
  border-radius: 10px;
}
td {
  text-align: center;
  line-height: 60px;
  height: 60px;
  border: 3px solid green;
}
</style>

组件通信答案

<!-- eslint-disable vue/require-v-for-key -->
<template>
  <div class="app">
    <div class="big_father">
      <span
        v-for="(item, index) in arrays"
        :key="index.id + ''"
        class=".big_father"
        :class="{ active: isshow === index }"
        @click="btnclick(index)"
        >{{ item }} {{ index }}</span
      >
    </div>
    <div>
    <span
   v-for="(item, index) in infor"
   :key="index.id + ''"
   class=".big_father"
   :class="{ active: isshow === index }"
   @click="btnclick1(ko)">{{ item }} {{ index }}</span
 >
    </div>
    <yf v-show="isshow === 0"></yf>
    <kz v-show="isshow === 1"></kz>
    <xz v-show="isshow === 2"></xz>
    <sy v-show="isshow === 3"></sy>
    <wt v-show="isshow === 4"></wt>
  </div>
</template>
<script>
// 导入文件信息
import yf from "./components/yf.vue";
import xz from "./components/xz.vue";
import kz from "./components/kz.vue";
import sy from "./components/sy.vue";
import wt from './components/wt.vue';
export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    yf,
    // eslint-disable-next-line vue/no-unused-components
    xz,
    // eslint-disable-next-line vue/no-unused-components
    kz,
    // eslint-disable-next-line vue/no-unused-components
    sy,
    wt
  },
  name: "app",
  data() {
    return {
      message: "Hello world vue cli",
      isshow: 0,
      arrays: ["衣服", "鞋子", "裤子", "上衣", "外套"],
      infor: ["衣服页面", "鞋子页面", "裤子页面", "上衣页面", "外套页面"],
      index:0,
      ko:true
    };
  },
  methods: {
    btnclick(flag) {
      this.isshow = flag;
    },
    btnclick1(ko){
      this.ko= !ko
    }
  },
};
</script>
<style scoped>
.active {
  color: red;
  background-color: azure;
  border: 2px solid lightseagreen;
  border-bottom: 8px solid red;
  border-radius: 12px;
}
.big_father {
  display: flex;
}
.big_father div {
  text-align: center;
  height: 60px;
  line-height: 60px;
  flex: 1;
  color: white;
  background-color: rgb(28, 125, 147);
}
.big_father div span {
  text-align: center;
  height: 60px;
  line-height: 60px;
  width: 100px;
  flex: 1;
  color: white;
  background-color: rgb(116, 214, 236);
}
button {
  height: 60px;
  width: 100px;
  line-height: 60px;
  margin-left: 100px;
}
span {
  text-align: center;
  line-height: 60px;
  margin-left: 10px;
  display: inline-block;
  width: 17%;
  height: 60px;
  font-size: 20px;
  border-radius: 20px;
  background: rgb(121, 224, 235);
  border-right: 2px solid red;
}
</style>





相关文章
|
3天前
|
JavaScript
Vue中如何设置在执行删除等危险操作时给用户提示(二次确认后执行对应的操作)
这篇文章介绍了在Vue项目中如何实现执行删除等危险操作时的二次确认机制,使用Element UI的`el-popconfirm`组件来弹出确认框,确保用户在二次确认后才会执行删除操作。
Vue中如何设置在执行删除等危险操作时给用户提示(二次确认后执行对应的操作)
|
3天前
|
JavaScript
如何创建一个Vue项目(手把手教你)
这篇文章是一篇手把手教读者如何创建Vue项目的教程,包括使用管理员身份打开命令行窗口、找到存放项目的位置、通过vue-cli初始化项目、填写项目信息、进入项目目录、启动项目等步骤,并提供了一些常见第三方库的引入方法。
如何创建一个Vue项目(手把手教你)
|
3天前
|
前端开发
StringBoot+Vue实现游客或用户未登录系统前、可以浏览商品等信息、但是不能购买商品或者加入购物车等操作。登录系统显示用户的登录名(源码+讲解)
这篇文章介绍了使用StringBoot+Vue实现用户登录状态判断的方法,包括前端加载用户信息和后端设置session的源码示例。
|
3天前
|
JavaScript
如何在Vue页面中引入img下的图片作为背景图。../的使用
这篇文章介绍了在Vue页面中如何引入`img`目录下的图片作为背景图,提供了两种使用相对路径的方法。第一种是使用`../assets/img/`作为路径引入图片,第二种是使用`../../assets/img/`作为路径。文章还展示了使用这些方法的代码实现和效果展示,并鼓励读者学无止境。
如何在Vue页面中引入img下的图片作为背景图。../的使用
|
3天前
|
JavaScript
如何通过点击商品的信息(图片或者文字)跳转到更加详细的商品信息介绍(前后端分离之Vue实现)
该博客文章介绍了如何在Vue 2框架下实现前后端分离的商品信息展示和详情页跳转,包括排序筛选、详情展示、加入购物车和分享功能。
如何通过点击商品的信息(图片或者文字)跳转到更加详细的商品信息介绍(前后端分离之Vue实现)
|
3天前
|
JavaScript
如何查看Vue使用的版本
这篇文章介绍了如何在项目中查看Vue及其相关库的版本信息,比如element-ui和element-china-area-data。要查看Vue的版本,需要查看项目中的`package.json`文件,在`dependencies`部分可以找到Vue的版本号。如果需要查询不同版本的兼容性,可以访问相应的官方文档或资源网站。
|
3天前
|
存储 JavaScript 前端开发
Vue中如何通过三元运算符来展示不同的操作
这篇文章讲述了在Vue中如何使用三元运算符结合v-if指令来根据订单的不同状态展示不同的操作按钮,例如在待发货状态显示退款按钮,在待付款或完成状态显示删除按钮。
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1029 0
|
3天前
|
JavaScript 编译器
成功解决:Module build failed: Error: Vue packages version mismatch
这篇文章记录了解决Vue项目中遇到的"Module build failed: Error: Vue packages version mismatch"错误的步骤,原因是项目中Vue依赖的版本不一致,解决方法是删除`node_modules`后重新安装指定版本的Vue和`vue-template-compiler`,确保版本匹配,最终成功运行项目。
成功解决:Module build failed: Error: Vue packages version mismatch
|
3天前
|
JavaScript
在Vue中使用Avue、配置过程以及实际应用
这篇文章介绍了作者在Vue项目中集成Avue组件库的完整过程,包括安装、配置和实际应用,展示了如何利用Avue实现动态表单和数据展示的功能。
在Vue中使用Avue、配置过程以及实际应用