超级无敌大结合(vue3+scss+axios(ajax+promise))

vue2:选项式开发模式                          vue3:组合式开发模式和选项式开发模式

利用vite创建vue3项目

npm create vite@latest

这是我的选项:

2a4129850b5d47ba9b974fe9e8cbcc40.png

1.响应式数据

ref:定义基本类型响应式数据  

   ref和reactive均可定义对象类型的响应式数据

 ref:

2a3244498dbf4e8fb5ba38e4c160f447.png

reactive:

44b9b3271a924323a080b538838b78ec.png

vue2使用的是object.defineproperty实现响应式,vue3则是proxy实现响应式

2.computed

3.watch(需要明确指出监视的数据)

作用:监视数据的变化

只能监听以下四种数据:

09a6ac79e7f44f058e1ca5f27bfc5e94.png

①ref定义的数据

ref定义的基本类型的数据

ref定义的对象类型的数据:监视的是对象的地址值,若想监听对象内部属性的变化,需要手动开启深度监视(deep:true)

②reactive定义的对象类型数据:默认开启深度监视,无法关闭

③函数返回一个值(getter函数)

④一个包含上述内容的数组

4.watchEffect(不用明确指出监视的数据,响应式地追踪其依赖)

5.标签的ref属性

对于html标签:取dom元素

对于组件:取组件实例对象

6.props的使用(传值)

defineProps

7.生命周期(组件一生)[生命周期,生命周期函数,生命周期钩子]

组件的生命周期:特定的时刻调用特定的函数

vue2:4个阶段,8个钩子:

创建(创建前beforeCreate(),创建完毕created())

挂载(挂载前beforeMount(),挂在完毕mounted())

更新(更新前beforeUpdate(),更新完毕updated())

销毁(销毁前beforeDestroy(),销毁完毕Destroyed())

vue3:4个阶段,7个钩子:

创建(setup)

挂载(挂载前onBeforeMount(()=>{}),挂在完毕onMounted(()=>{}))

更新(更新前onBeforeUpdate(()=>{}),更新完毕onUpdated(()=>{}))

卸载(卸载前onBeforeUnmount(()=>{}),销毁完毕onUnmount(()=>{})

8.axios(涉及promise和ajax知识补充)

API:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。——百度百科

补充:XML(可扩展标记语言,存储和传输数据,现被json取代)而 HTML是呈现数据.

Ajax全称:Asynchronous JavaScript and XML(异步的JavaScript和XML)

Ajax特点:在网页不刷新的情况下,向服务端发起http请求,然后得到http响应.(登陆页面不刷新显示账号情况,百度搜索某内容会出现对应相关内容,商品二级目录交互显示一级目录等)

http:超文本传输协议(英文:Hyper Text Transfer Protocol)

6232dc73ace949a6a10791ee9c47c2bf.png

请求报文:从客户端发往服务器的报文。
响应报文:服务器收到请求报文后,作为响应发往客户端的报文文。

dad94d8bc270474fb15937cd654a9b90.png

注:CR:回车   LF:换行

912739bcbf674ae7bf7a685918fa0517.jpeg

请求报文举;例格式:

http://www/xyz.edu.cn/dir/index.htm

GET /dir/index.htm HTTP/1.1

HOST:www/xyz.edu.cn   //给出主机域名

Connection:close   //告诉服务器发送完请求文档就可以释放连接

User=Agent:Mozilla/5.0 //表示用户代理使用的是火狐浏览器firefox

Accept-Language:cn //表示用户希望优先得到的是中文版本的文档

 

响应报文中: 

cb941af584ca40dfa8cc26c25ed1bcf0.jpeg

#头部举例

HTTP/1.1 202 Accpted

HTTP/1.1 400 Bad Request

HTTP/1.1 404 Not Found 

#常见头部(headers)

HTTP报文之"请求报文"和"响应报文"详解_请求报文是什么意思-CSDN博客

4f44c62762a7443dadd607f3eaae5517.png

(空行)

#体(响应体)

<html>                                  
<body>
<h1>Hello, World</h1>             
</body>
</html>

网页中查看报文:

ec1025da186645f8b1130b6e77d0636a.png

0040e299f3fa4b2095a8790bc89b25a2.png

express框架:(学习Ajax)

8a39a0d9b58e4a4dbae008567622fc86.png

#安装工具包  npm install -g nodemon

8f569fe52fcb41268aca260216918eda.png

引入xmlhttprequest: XMLHttpRequest 详解_xmlrequest-CSDN博客

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px blue;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result" ></div>
</body>
<script>
    const btn=document.getElementsByTagName('button')[0];
    const result=document.getElementById('result')
    btn.onclick=function (){
        const xhr=new XMLHttpRequest();
        xhr.open('GET','http://127.0.0.1:8000/server');
        xhr.send(),
        //xhr.setRequestHeader()请求头内容
        xhr.onreadystatechange=function(){
            //0未初始化 1open方法调用完毕 2send方法调用完毕
            //3服务端返回部分接口 4服务端返回所有接口
            if(xhr.readyState===4){
                if(xhr.status>=200&&xhr.status<300){
                    // console.log(xhr.status);//状态码
                    // console.log(xhr.statusText);//状态码文本
                    // console.log(xhr.getAllResponseHeaders)//响应头
                    // console.log(xhr.response)//响应体
                    result.innerHTML=xhr.response
                }
            }
        }
    }
</script>
</html>
const express = require('express')
const app = express();
app.all('/server',(request,response)=>{
    response.setHeader('Access-Control-Allow-Origin','*')
    response.send('this body')
});//all->get,post,option
app.listen(8000,()=>{
    console.log("suceess8000,watching")
})

在ajax中传递参数:

996453d421aa451e82988fb4a8ab5047.png

利用post传递参数:

7dd27206a9ab475a9786ac62420cc183.png

至此也说明了为什么get method没有请求体而post可能有.

服务端响应json数据:

9b3286d29e394f1fa8abfec3325c48ba.png

虽然在服务器端通过 response.send(data) 发送了一个对象,但如果不设置 xhr.responseType = 'json' ,xhr.response 的值将会是一个字符串形式的响应体。

例如,如果不设置 xhr.responseType = 'json' ,得到的 xhr.response 可能类似于 '{"username":"henry"}' 这样的字符串,而不是已经解析为 JavaScript 对象的形式。这样直接使用 xhr.response.username 就会导致错误,因为此时 xhr.response 不是一个对象,没有 username 这个属性。

设置 xhr.responseType = 'json' 后,浏览器会自动将接收到的字符串形式的 JSON 数据解析为 JavaScript 对象,从而可以方便地通过 xhr.response.username 来获取属性值。

604ceb47a4ab46639b7e9bdf581a7e05.png

延时与网络异常处理:

154b47253a6545c2a0f592b94d601d25.png

 081b17e9370d4eb9b279bd5a7a174ac9.png

b4e7085104f24d779dcd6f1fe5c16512.png

取消请求:

87d974ed366b4444846d28efd8fa6cfb.png

77ddb54ee4e345c4a6a27ac2b6bb54cf.png

拒绝重复请求:

71d753683ce24c239bde647646cf30a0.png

Promise:

JavaScript是单线程语言,在执行任务的时候,会先执行第一个任务再执行第二个任务,假如第一个任务是个耗时的任务那么第二个任务就一直阻塞不能执行,那么这个时候就需要异步来处理这个操作;

同步:主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务;
异步:不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程;

①promise是一门新的技术(ES6规范),是JS中进行异步编程(fs文件操作,数据库操作,ajax,定时器)的新解决方案.

异步编程是一种编程模型,它将程序中的计算任务分成独立的阶段,并在每个阶段完成后立即返回结果。异步编程模型通常用于处理长时间运行的任务

②从语法上来说:promise是一个构造函数,从功能上来说:promise对象用来封装一个异步操作并可以获取其成功/失败的结果值.

promise支持链式调回,可以解决回调地狱问题

回调地狱:外部回调函数异步执行的结果是嵌套的回调执行的条件,那么随着异步层级的增长,代码会变得极其深陷且难以理解和维护。

回调地狱产生的 根本原因是异步操作的嵌套和回调函数的链式调用.缺点:不便于阅读,不方便异常处理.

promise之setTimeout:

<body>
    <button class="btn">点击抽奖</button>
</body>
<script>
    function getRnd(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min - 1
    }
    const btn = document.querySelector('.btn')
    btn.addEventListener('click', function () {
        let test = getRnd(1, 100);//0-100不包括100
    //     setTimeout(()=>{//回调函数的方法
    //     let test = getRnd(1, 100);//0-100不包括100
    //     if (test <= 30) {
    //         console.log(test)
    //         alert("中奖了")
    //     }else{
    //         console.log(test)
    //         alert("抱歉")
    //     }
    // },1000)
       // promise方法
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                if (test <= 30) {
                    resolve(test);//将promise对象的状态设置为成功
                } else {
                    reject(test);
                }
            }, 1000);
        });
        //调用then函数
        p.then((test) => {
            console.log(test);
            alert("中奖了");
        }, (test) => {
            console.log(test)
            alert("抱歉")
        })
    })
</script>

promise的属性: 

接上面的例子我们了解一下promise的属性:

1c8afbfb66c8471c9032b4736e8da21c.png

promise实例对象的一个属性promisestate(状态):三种状态即为中奖(成功)的fulfilled/resolved(成功),rejected(失败),以及pending(没有决定的),无论成功或者失败都只有一种结果数据,成功数据一般为value,失败数据一般为reason.

除了resolve和reject还有throw也可以更改状态:

53fe226e48e646c4b38a8c7a67c5659f.png

promise实例对象的一个属性promiseresult(结果):保存实例对象成功和失败的值,可以使用resolve和reject进行修改

 promise之fs:

const fs = require('fs')
// fs.readFile('11.txt',(err,data)=>{
//   if(err) throw err;
//   console.log(data.toString())
// })
let p = new Promise((resolve, reject) => {
    fs.readFile('11.tx', (err, data) => {
        if (err) reject(err);
        resolve(data);
    });
});
//构造函数then
p.then(data=>{
    console.log(data.toString())
},err=>{
   console.log(err)
})

封装 

function testFile(path){
    return new Promise((resolve, reject) => {
        require('fs').readFile(path,(err,data)=>{
            if(err) reject(err);
            resolve(data);
        })
    })
}
testFile('11.txt').then(data=>{
    console.log(data.toString())
},err=>{
    console.log(err)
})

a2e1ce0a07734d1cab12da40c6eaa029.png

 promise之ajax:

<script>
  function testajax(url){

    return new Promise((resolve, reject) => {
        const xhr= new XMLHttpRequest()
        xhr.open('GET',url);
        xhr.send();
        xhr.onreadystatechange=function(){
          if(xhr.readyState===4){
            if(xhr.status>=200&&xhr.status<300){
              resolve(xhr.response)
            }else{
              reject(xhr.status)
            }
          }
        }
    })
}
testajax('http://127.0.0.1:8000/json-srver')//之前express中的ajax
.then(value=>{
  console.log(value)
},reason=>{
  console.warn(reason)
})
</script>

0d09704c8fbf41978ae777deb1ca6dbb.png

promise函数的方法

promise.resolve

8a695549fda4488ea73bf84d4322de1f.png

promise.reject

6701b674f48b491395d067250adbaefb.png

promise.all ->包含n个promise对象的数组

a9d268d549d44796a45b78209069b668.png

promise对象有一个失败贼为失败:

063d783f5b2b489ba6b6de6e66abcd40.png

promise.race

第一个promise状态结果就为最终的结果:

59fb6f2510f54afc9707bb51635fa2a6.png

promise串联多个任务:

07b36a8846b448f5850df38d8f97577b.png

promise异常穿透:

只需要一次抛出错误即可

e6875eaf45d94610aa061c2103e9746e.png

1d90f37a35ce460ea98cf025daeae279.png

 中断穿透链的方法:

96e9827a536a49c38a74ac37cac099b7.png

async和await:

async:

b95797e9338c44aeab59c0ff9f8986ae.png

9dace4ccef12454facadcdb00c7b3e76.png

1ba1dbe46a1f44a08644b2d6fc64f62d.png

 await:

await必须写在async函数中,但是async函数中可以没有await

0675b2a3006348f1aa9120c166b96b7d.png

结合async,await

回到之前提到的回调地狱 

//回调地狱
// const fs = require('fs');
// fs.readFile('1.txt', (err, data1) => {
//     if (err) throw err
//     fs.readFile('2.txt', (err, data2) => {
//         if (err) throw err
//         fs.readFile('3.txt', (err, data3) => {
//             if (err) throw err
//             console.log(data1+data2+data3)
//         })
//     })
// })
//使用async和await
const fs = require('fs');
const util=require('util')
const mineReadFile=util.promisify(fs.readFile)
async function main() {
    try{
        let data1=await mineReadFile('1.txt')
        let data2=await mineReadFile('2.txt')
        let data3=await mineReadFile('3.txt')
        console.log(data1+data2+data3)
    }catch(e){
    console.log(e);
    }
}
main()

 e3da32c6cf3d4fe5be014216e808f014.png

79006f6762894a5eb5385cce823ef893.png

Axios:

axios有很多特性,方便了很多.

7205f4889b8a46c3b5f413858e47925d.png

搭建json-server

GitHub - typicode/json-server: Get a full fake REST API with zero coding in less than 30 seconds (seriously)https://github.com/typicode/json-server

axios配置

GitHub - axios/axios: Promise based HTTP client for the browser and node.jsPromise based HTTP client for the browser and node.js - axios/axioshttps://github.com/axios/axios

axios:get:

03fa8ce3d69d48a1974fa22bdbd161e6.png

axios:post:

d16e75cccf2c453e87704155a039642f.png

 axios:put:

54585fd4427f4e6ead54fa56bfca34e9.png

 axios:delete:

8c204ed058314d97a17537eff9ac71b0.png

<template>
  <button @click="clickGet" >发送 get</button>
  <button @click="clickPost" >发送 Post</button>
  <button @click="clickPut" >发送 put</button>
  <button @click="clickDelete" >发送 delete</button>
</template>
<script setup  lang="ts">
import axios from 'axios';
axios.defaults.baseURL='http://localhost:3000'
const clickGet = () => {
  axios.request({
    method: 'GET',
    url: '/posts/2'
  }).then(response => {
    console.log(response);
  });
};
const clickPost = () => {
  axios({
    method: 'POST',
    url: '/posts',
    //设置请求体
    data:{
      "id":2,
      "title": "add",
       "views": 300 
    }
  }).then(response => {
    console.log(response);
  });
};
const clickPut = () => {
  axios({
    method: 'PUt',
    url: '/posts/2',
    //设置请求体
    data:{
      "id":2,
      "title": "add",
       "views": 300 
    }
  }).then(response => {
    console.log(response);
  });
};
const clickDelete = () => {
  axios({
    method: 'delete',
    url: '/posts/2',
  }).then(response => {
    console.log(response);
  });
};
</script>

  axios.methods

e19dcdb2cc4f4a9d90c9c262b89bda48.png

axios.request()

const clickGet = () => {

  axios.request({

    method: 'GET',

    url: 'http://localhost:3000/posts/1'

  }).then(response => {

    console.log(response);

  });

};

 axios.post()

 

const clickPost = () => {

  axios.post(

    'http://localhost:3000/comments',

    //设置请求体

    {

      "text": "more comments about post 1",

      "postId": "1"

    }).then(response => {

      console.log(response);

    });

};

创建axios实例对象(重点) 

 

import axios from 'axios';

const clickGet = () => {

  let request=axios.create({

    baseURL:'http://localhost:3000',

    timeout:3000

  })

  request.get('/posts').then(response=>{

    console.log(response)

  })

}

拦截器 :

请求拦截器(Request Interceptor)的作用

请求拦截器允许在发送请求之前对请求进行处理和修改。

  • 可以添加统一的请求头,例如添加身份验证信息、设置 Content-Type 等。例如,如果您的应用需要在每个请求中都携带一个特定的 token 用于身份验证,就可以在请求拦截器中添加。
  • 可以对请求参数进行预处理,比如格式化、加密等操作。
  • 可以在发送请求前进行日志记录,方便后续的调试和跟踪。

响应拦截器(Response Interceptor)的作用

响应拦截器让在接收到服务器的响应后能够对其进行处理。

  • 可以统一处理错误状态。例如,当服务器返回特定的错误码时,进行统一的错误提示或跳转处理。
  • 对响应数据进行解析和转换。例如,如果服务器返回的数据格式不统一,在响应拦截器中进行格式转换,以方便后续使用。
  • 进行缓存处理,根据响应结果决定是否将数据缓存起来,以提高后续相同请求的响应速度。

a7a16b56eb2b41698ee84e40c57df075.png

 b5e6784ff3df497a9359636a51ec4067.png

<script setup  lang="ts">
import axios from 'axios';
  let test=axios.create({
    baseURL:'http://localhost:3000',
    timeout:3000
  })
  test.interceptors.request.use(function(config){
    console.log('reques interceptors')
    // return config;
    throw 'wrong'  
  }
  ),
  test.interceptors.response.use(function(response){
    console.log('response interceptors')
    return response;
  },function(error){
    console.log('response interceptors err')
    return Promise.reject(error)
  })
  test({
    method:'GET',
    url:'http://localhost:3000/posts'
  }).then(response=>{
    console.log(response)
  },reason=>{
    console.log('失败')
  })
</script>

a31f8990b7af4cbe87148dd6fc7428f9.png

 取消axios请求:

f2485a40d8564695a7d0dda4b42a160a.png

9.hooks(封装)

10.路由

(安装路由器->npm i vue-router)

路径->组件

4368029cd74f413b97fe58835ad8160b.png

路由组件:靠路由的规则渲染出来的(pages/views)

一般组件:需要亲手写标签(components)

路由的三种to跳转写法:

2b4319b72da1405b81487eb7be37fb92.png

路由嵌套:

const router=createRouter({

  history:createWebHistory (),

  routes:[

    {

      path:'/menu2',

      name:'menu2',

      component:Menu2,

      children:[{

        path:'/menu2-1',

        component:Menu21

      }]

    }

路由query参数(通过地址传参)

    <RouterLink

    :to="{

      path:' ',

      query:{

       

      }

    }"

    >

  </RouterLink>

 路由params参数(传递params参数时,需要提前在规则中占位。 )

    <RouterLink

    :to="{

      name:' ',

      params:{

       

      }

    }"

    >

  </RouterLink>

 

11.组件通信方式

①Props:只读的(组件中间传递只读的数据)

vue3中对应父子组件传递数据,需要使用defineProps方法去接受父组件传递过来的数据,不需要引入直接使用.

 defineProps();

②自定义事件

  • 原生事件:

    • 事件名是特定的(clickmosueenter等等)

    • 事件对象$event: 是包含事件相关信息的对象(pageXpageYtargetkeyCode

  • 自定义事件:

    • 事件名是任意名称

    • 事件对象$event: 是调用emit时所提供的数据,可以是任意类型!!!

vue3中利用defineEmits方法返回函数触发自定义事件,不需要引入直接使用.

③全局事件总线(mitt)

  // 绑定事件

<template>

    <div class="box1">

        <h3>{{gnum}}</h3>

    </div>

</template>

 

<script setup lang='ts'>

import tnum from '@/bus';

import { ref } from 'vue';

let gnum =ref('');

tnum.on('tnum',(value:any)=>{

    gnum.value=value;

})

</script>

 

<style scpoed lang='scss'>

    .box1{

        @extend %box;

        background-color: rgb(168, 36, 177);

    }

</style>

  // 触发事件

<template>

    <div class="box2">

        <button @click="tnum.emit('tnum',n)">传输数字</button>

        <h3>{{ n }}</h3>

    </div>

</template>

<script setup lang='ts'>

import tnum from '@/bus';

import { ref } from 'vue';

let n=ref(234);

</script>

 

<style scpoed lang='scss'>

    .box2{

        @extend %box;

        background-color: aquamarine;

    }

</style>

 

ef7b6d7e658b46cbbfc38532928827d5.png

④v-model

原理:

1.v-bind绑定value属性的值。
2.v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中。 

        <!-- v-model用在<html>标签上 -->

        <input type="text" v-model="username">

        <!-- 对v-model进行更冗长的等价展开 -->

        <!-- <input type="text" :value=”username” @input="username=( <HTMLInputElement>$event.target).value”-->

        <!-- v-model用在组件标签上 -->

         <Home v-model="username"/>

          <!-- 对v-model进行更冗长的等价展开 -->

        <!-- <input type="text" :modelvalue=”username” @update="modelvalue="username=$event"-->

在Home组件中:

<template>
  <div class="box">
    <!--将接收的value值赋给input元素的value属性,目的是:为了呈现数据 -->
        <!--给input元素绑定原生input事件,触发input事件时,进而触发update:model-value事件-->
    <input 
       type="text" 
       :value="modelValue" 
       @input="emit('update:model-value',$event.target.value)"
    >
  </div>
</template>

<script setup lang="ts" name="AtguiguInput">
  // 接收props
  defineProps(['modelValue'])
  // 声明事件
  const emit = defineEmits(['update:model-value'])
</script>

 

对于原生事件,$event就是事件对象(能.target)

对于自定义事件,$event就是触发事件时,所传递的数据(不能.target)

⑤useAtrrts方法(获取组件的属性与事件)

useAtrrts方法可以获取组件的属性与事件.

3c582150ebee4f10a71bb7c5ea57145b.png

fcf3ce54c0e34d05977f9fe160957882.png

⑥ref和$parent(父子间实现互相传递应用)

  • $refs用于 :父→子。

  • $parent用于:子→父。

$refs值为对象,包含所有被ref属性标识的DOM元素或组件实例。
$parent值为对象,当前组件的父组件实例对象。

组件内部数据对外关闭的,别人不能访问

如果想要外部访问需要通过deFineExpose方法对外暴露

⑦provide和inject(隔辈传递数据)

12.pinia(任意组件通信)->项目存储数据

Pinia是vue生态里Vuex的替代者,一个全新的vue状态管理库。在Vue3成为正式版以后,尤雨溪强势推荐的项目就是Pinia。

核心概念:state.actions.getters

pinia组合式写法:选择器API.组合式API

持久存储: 快速开始 | pinia-plugin-persistedstate (prazdevs.github.io)

选择器API

大仓库配置(./store/index.ts)

//创建大仓库

通过createPinia( )方法,得到pinia的实例,然后将Pinia挂载到Vue根实例上。

import { createPinia } from "pinia";

const store = createPinia();

export default store;

小仓库配置:(./modouls/info) 

//定义小仓库

import { defineStore } from "pinia";

//defineStore方法会执行返回第一个函数,函数作用就是可以让组件可以获取到仓库数据

//第一个参数:小仓库名字 第二个参数:小仓库配置对象

const useinfostore=defineStore("info",{

   //数据

    state:() =>{

        return{

 

        }

    },

//方法

    actions:{

 

    },

//计算

    getters:{

 

    }

})

export default useinfostore;

 

获取小仓库数据:

<template>

<h3>box2:{{ infoStore.num }}</h3>

</template>

<script setup lang='ts'>

import useinfostore from '@/store/modules/info';

let infoStore=useinfostore();

</script>

<style scpoed lang='scss'>

</style>

 

组合式API 

import { defineStore } from "pinia";

import { ref } from "vue";

const usetodoStore=defineStore('todo',()=>{

    //要返回一个对象:属性与方法可以提供给组件使用

    const num=ref(999);

   

    return{

        num,

        updateto(){

            this.num.value+=1;

        },

    }

});

export default usetodoStore;

 

<template>

<h3>box1:{{ todoStore.num }}</h3>

<button @click="updatetodo">小仓库数据+1</button>

</template>

 

<script setup lang='ts'>

import usetodostore from '@/store/modules/todo';

let todoStore=usetodostore();

const updatetodo=()=>{

   todoStore.updateto();

}

</script>

<style scpoed lang='scss'>

</style>

 

13.插槽 

①默认插槽

子组件:

<template>

<h1>插槽前内容</h1>

<!-- 默认插槽 -->

<slot></slot>

<h1>插槽后内容</h1>

</template>

<script setup lang='ts'>

</script>

<style scpoed lang='scss'>

</style>

父组件:

<template>

   <sBox>

      <pre>这是插槽内容</pre>

   </sBox>

</template>

<script setup lang='ts'>

import sBox from './sBox.vue';

</script>

<style scpoed lang='scss'>

</style>

a61bf7cb8a9d4d5987ead4bf64972b89.png

 ②具名插槽

子组件:

<template>

<h1>插槽(a)前内容</h1>

<!-- 具名插槽 -->

<slot name="a"></slot>

<h1>插槽(a)后内容</h1>

</template>

父组件:

<template>

   <sBox>

      <template v-slot:a>

         <pre>这是插槽a内容</pre>

      </template>

   </sBox>

</template>

493179310c9843bb86ac9da6c224d225.png

③作用域插槽

作用域插槽:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。

父组件:

<template>

   <sBox v-slot="params">

      <ul>

          <li v-for="c in params.content" :key="c.id">{{ c.name }}</li>

        </ul>

   </sBox>

</template>

子组件:

<template>

<h1>插槽前内容</h1>

<!-- 作用域插槽 -->

<slot :content="content"></slot>

<h1>插槽后内容</h1>

</template>

<script setup lang='ts'>

 import {reactive} from 'vue'

        let content = reactive([

          {id:'01',name:'内容1'},

          {id:'02',name:'内容2'},

          {id:'03',name:'内容3'},

          {id:'04',name:'内容4'}

        ])

</script>

 

4306b93921a945dab1a141f6275b99b9.png

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值