清朝云资源网

作者: 清朝云

  • 宝塔转1penel你想不到的小问题

    前言

    今天主题群里有个群友在群里询问,为何主题的验证码一直获取不到。

    过程

    出于好奇,我使用了todesk连接了他的电脑。发现使用了1panel,因为习惯了使用宝塔,所以主用服务器没有安装过1panel。

    但是香港的服务器曾经安装过1panel并且搭建过网站,但是也只搭建了typecho。

    然后我就F12大发查看报错了什么,发现提示WordPress站点遇到了致命错误,并不是像之前遇到的一样提示waf拦截之类的。

    于是我就询问他迁移后有没有修改什么东西,他说并没有。那就更奇怪了,并没有修改任何东西为何会出现这样的情况。

    我就继续测试,因为获取验证码是通过post提交给admin-ajax.php,所以我就想到了写文章也是通过admin-ajax.php提交。

    但是当我测试时发现并没有问题。然后我就怀疑是nginx的问题,群友也说可能是php拓展的问题,于是我就查看了php版本发现是8.3。

    当我以为将它降为7.4就可以解决问题的时候,发现问题并没有得到解决。当我正想添加拓展的时候,他那边因为网络问题断开了连接。

    不过最后他也告诉我是因为缺少了gd的php拓展导致获取不到验证码。

    结语

    1.1panel不像宝塔一样在安装完成时会提示你需要安装运行环境。

    2.1panel也不会像宝塔一样在安装运行环境的时候就将所需的扩展安装好,需要你自己去安装。

    3.对于新手来说还是使用宝塔比较好,毕竟能够轻松建站。

    4.在面板没有遇到重大且无法解决的问题时,还是不要轻易更换面板的选择,因为会大大增加你网站出现bug的可能性。

  • 08月20日,星期二, 每天60秒读懂全世界!

    百度热搜新闻

    新闻来源:百度热搜榜

    1. 2岁女童失踪多日 家属悬赏20万寻人 8月12日,山西马夭村一2岁女童董苡柔在家中失踪,引发关注。19日晚,女童一家再次发布公告:愿意支付20万元作为酬谢。

    2. 女子迪士尼上厕所超时崩溃大哭 近日,一女子在迪士尼排队中途想上厕所,工作人员发放厕所卡限时20分钟,女子归队超时需重新排队,与工作人员起争执后崩溃大哭。

    3. 中越跨境旅游持续火热 近来,云南入境游持续火热,迎来了大批越南游客。与此同时,越南也成为许多中国人出境游的热门目的地。中越跨境旅游双向奔赴,呈现出蓬勃发展的良好势头。

    4. 河南2男子捉44只壁虎被刑拘

    5. 女生高考前撞死人 获谅解未被起诉

    6. 是什么引起了蔬菜价格上涨

    7. 女子怀孕6个月在飞机厕所突然分娩

    8. 辛追夫人素纱单衣被盗?谣言 近日,有网友对湖南博物院展出的“辛追夫人素纱单衣”提出疑问,认为其早已被盗被毁。对此,博物院回应:从未被盗,一直精心保存。

    9. 省委巡视组反馈后 魏新刚任上被查

    10. 黑神话证明男性购买力

    —- 百度热搜新闻 End —-

    知乎新闻

    新闻来源:知乎日榜

    标题: 李白一辈子没怎么工作过,整日游山玩水,他的钱从哪儿来?
    链接: https://daily.zhihu.com/story/9774730
    ———————-
    标题: 有哪些几乎是中国人特有的生理疾病?
    链接: https://daily.zhihu.com/story/9774716
    ———————-
    标题: 霸王龙也解放了双手,也能直立行走,脑袋也足够大,为什么没发展出人类这样的文明?
    链接: https://daily.zhihu.com/story/9774721
    ———————-
    标题: 为什么中国古典园林没有供人晒太阳的大草坪?
    链接: https://daily.zhihu.com/story/9774735
    ———————-
    标题: 瞎扯 · 如何正确地吐槽
    链接: https://daily.zhihu.com/story/9774745
    ———————-

    —- 知乎新闻 End —-

    IT之家新闻

    新闻来源:ITHome之家科技新闻

    标题: (更新:已恢复)网易云音乐“崩了”:网页端报错 502 Bad Gateway,App 无法使用
    发布时间: 2024-08-19T15:14:41.663
    新闻简介: 据多位IT之家小伙伴投稿反馈,网易云音乐疑似出现服务器故障,网页端出现 502 Bad Gateway 报错,App 无法使用。#网易云音乐#
    ———————-
    标题: 网易云音乐“崩了”,知情人士称机房刚刚完成迁移
    发布时间: 2024-08-19T15:58:42.26
    新闻简介: 知情人士对凤凰网科技表示,网易在贵州建立了机房,旗下业务分阶段搬迁,2024年Q2网易云音乐刚刚完成了贵州机房的迁移。“新机房确实问题会多,据说也节省了成本。”
    ———————-
    标题: 网易云音乐恢复使用:没有删库跑路,将补偿 7 天会员权益
    发布时间: 2024-08-19T17:46:47.97
    新闻简介: 目前,网易云音乐已恢复正常使用,官方发文称“没有删库,没有跑路,故障已陆续修复”,官方将提供 7 天会员权益作为补偿。
    ———————-
    标题: 苹果 iPhone 16 Pro 系列镜头环曝光,新配色“钛金”亮相
    发布时间: 2024-08-19T08:09:51.62
    新闻简介: 爆料人 Majin Bu 最新分享的一张图片显示,iPhone 16 Pro 和 iPhone 16 Pro Max 的相机镜头环颜色似乎得到了确认,并进一步揭露了新配色“钛金(Desert Titanium)”的细节。
    ———————-
    标题: (更新:已恢复使用)网易云音乐开发者删库跑路?官方回应称“目前故障与机房无关”
    发布时间: 2024-08-19T16:54:33.31
    新闻简介: 据贝壳财经报道,针对“网易云音乐开发者删库跑路”、“网易云音乐无法搜索歌曲”等传闻,网易云音乐官方回复称:“目前故障与机房无关,内容有失实”。
    ———————-
    标题: M1 芯片:苹果 2020 款 MacBook Air 京东自营 8+256G 版 4999 元清仓
    发布时间: 2024-08-19T13:13:55.53
    新闻简介: M1 芯片:苹果 2020 款 MacBook Air 京东自营 8+256G 版 4999 元清仓
    ———————-
    标题: 消息称因极氪 2025 款新车上市客户分流,小米上周新增订单破 4 千
    发布时间: 2024-08-19T14:00:57.287
    新闻简介: 极氪于 8 月 13 日发布了 2025 款极氪 001 和 2025 款极氪 007 汽车。
    ———————-
    标题: 网易云游戏明日上线《黑神话:悟空》“4070Ti 极致版”:支持苹果 iOS、安卓、PC 等设备游玩
    发布时间: 2024-08-19T19:40:35.983
    新闻简介: 据介绍,网易云游戏“4070Ti 极致版”《黑神话:悟空》将支持 iOS 端、安卓端、网页端 (支持 MAC)、PC 端和 TV 端进行游玩。
    ———————-
    标题: 反诈电影《孤注一掷》宣布 8 月 24 日重映,位列中国影史票房第 11
    发布时间: 2024-08-19T12:58:36.237
    新闻简介: 《孤注一掷》由宁浩监制,申奥编剧执导,张艺兴、金晨、咏梅、王传君领衔主演。《孤注一掷》最初于 2023 年 8 月 8 日上映,引发关于电信诈骗的讨论热潮,最终收获了 38.48 亿元高额票房,位列中国影史第 11。
    ———————-
    标题: 致态 TiPlus 7100 固态硬盘《黑神话:悟空》联名版发售,2TB 定价 1099 元
    发布时间: 2024-08-19T08:38:26.093
    新闻简介: 本次联名新品外包装以黑色为主,整体采用中国传统的重墨技法,用毛笔勾勒出两条线条,辅以由水墨笔触所描绘的云海底纹。此外,硬盘本体上写有联名相关字样,还有限量“天命人专属身份卡”。
    ———————-
    标题: 业内首颗!国产 1.8 亿像素相机全画幅 CMOS 图像传感器成功试产,打破索尼垄断地位
    发布时间: 2024-08-19T08:21:35.097
    新闻简介: 晶合集成今日官宣,该公司与思特威联合推出业内首颗 1.8 亿像素全画幅(2.77 英寸)CIS(CMOS 图像传感器),为高端单反相机应用图像传感器提供更多选择。
    ———————-
    标题: 极氪:近期出现大量针对公司的谣言,已固定证据并报警
    发布时间: 2024-08-19T10:35:44.63
    新闻简介: 今日 @极氪法务部 发文称,近期网络出现大量针对极氪的网络暴力行为,大量谣言、谩骂和捏造的不实信息,被反复恶意扩散传播,不仅对公众产生误导,更直接损害了企业形象和商誉,严重影响企业的正常生产经营活动。以上谣言及不实信息,公司已经全部固定证据并报警,将通过法律手段维护自身合法权益。
    ———————-

    —- IT之家新闻 End —-

  • Docker 搭建 webhook – 调用接口即可运行本地脚本


    共计 1557 个字符,预计需要花费 4 分钟才能阅读完成。

    为什么突然想到用这个,因为有时候需要快速批量修改域名的 cname 解析,但是登录云平台去一个个修改非常麻烦。但如果将常见的操作写成脚本,并使用网络请求进行调用,这个就变得非常容易了。

    简而言之,就是将复杂的操作做成脚本,然后通过接口调用运行脚本。(为什么不直接登录机器,因为有时候不方面,而浏览器是哪里都有的)当然,能做的还有很多,全看自己的需求。

    简介

    这里直接引用开源项目 Webhook 自己的介绍。

    WebHook 是一个用 Go 语言编写的轻量可配置的实用工具,它允许你轻松、快速的创建 HTTP 服务(钩子)。你可以使用它来执行配置好的命令。并且还能够将 HTTP 请求中的数据(如请求头内容、请求体以及请求参数)灵活的传递给你配置好的命令、程序。当然,它也允许根据具体的条件规则来便触发钩子。

    举个例子,如果你使用的是 GitHub 或 Gitea,可以使用 WebHook 设置一个钩子,在每次你推送更改到项目的某个分支时,这个钩子会在你运行服务的设备上运行一个“更新程序部署内容”的脚本。

    如果你使用飞书、钉钉、企业微信或者 Slack,你也可以设置一个“传出 Webhook 集成”或“斜杠命令”,来在你的服务器上运行各种命令。我们可以通过聊天工具的“传入 Webhook 集成”功能处理接口的响应内容,直接向你或你的 IM 会话或频道报告执行结果。

    Webhook 的目标只是它应该做的,那就是:

    • 收到请求,
    • 解析标头、有效负载和查询变量,
    • 检查是否满足钩子的指定规则,
    • 最后,通过以下方式将指定的参数传递给指定的命令 命令行参数或通过环境变量。

    其他一切都是命令作者的责任。

    配置文件中文解释:https://github.com/soulteary/webhook/tree/main/docs/zh-CN

    使用

    这里的配置文件可以使用 yaml 或者 json 格式。

    首先创建配置文件:

    mkdir -p /home/docker/webhook/config && \
    cat > /home/docker/webhook/config/hooks.yaml << EOF
    - id: test
      execute-command: "/hooks/test.sh"
      command-working-directory: "/hooks/"
      # 是否应该等待脚本程序执行完毕,并将原始程序输出返回给调用方。
      include-command-output-in-response: true
    EOF

    这里配置了一个名为 test 的钩子,运行目录为 /hooks/,执行的命令为 /hooks/test.sh。(这里的路径为容器内路径)

    所以接下来要创建 test.sh

    mkdir -p /home/docker/webhook/hooks && \
    touch /home/docker/webhook/hooks/test.sh && \
    chmod +x /home/docker/webhook/hooks/test.sh && \
    cat > /home/docker/webhook/hooks/test.sh << EOF
    #!/bin/bash
    
    sleep 3
    echo "test ok"
    EOF

    然后就可以运行容器了:

    docker run -d \
    --name=webhook \
    -p 9000:9000 \
    -v /home/docker/webhook/config:/etc/webhook \
    -v /home/docker/webhook/hooks:/hooks \
    hausen1012/webhook -verbose -hooks=/etc/webhook/hooks.yaml -hotreload

    访问 ip:9000/hooks/test,输出 test ok 就搭建成功了。另外,容器安装了常用的工具,如 ping、curl、sshpass 和 python3,接下来就看自己发挥了吧!

    提醒:本文发布于132天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • ES6 语法详解


    共计 10695 个字符,预计需要花费 27 分钟才能阅读完成。

    ES6(ECMAScript 2015)是 JavaScript 的一个版本,它于 2015 年发布。ES6 引入了很多新的语法和功能,使得 JavaScript 更加强大、灵活和易于使用。

    一、块级作用域:

    ES6 引入了let 和 const 关键字,可以在块级作用域中声明变量,解决了以前使用 var 声明变量可能导致的问题。在 ES6 之前,JavaScript 中的变量声明使用var关键字,它具有函数作用域而不是块级作用域。这意味着使用**var**声明的变量可以在其所在的函数内部任何位置访问,而不仅仅是在声明的块级作用域内。

    1、let关键字:

    let关键字用于声明可变的变量,它的作用范围限定在当前的块级作用域内,包括花括号({})内部的任何代码块。在同一个作用域内,不能重复声明同名的let变量。

    function example() {  
        if (true) {    
            let x = 10; // 声明一个块级作用域内的变量 x    
            console.log(x); // 输出 10  
        }  
        console.log(x); // 报错,x 未定义
    }
    example();

    2、const关键字:

    const关键字用于声明常量,它的作用范围也是在当前的块级作用域内。与let不同,const声明的变量是不可变的,即不能被重新赋值。同时,const声明的变量必须在声明时进行初始化,且不能再次修改其值

    function example() {
      const PI = 3.14159; // 声明一个常量PI
      console.log(PI); // 输出 3.14159
    
      PI = 3.14; // 报错,常量不能被重新赋值
    }
    
    example();

    二、箭头函数

    ES6 引入了箭头函数=>语法,简化了函数的定义和使用

    1、箭头函数可以简化的函数定义

    // 传统函数定义
    function add(a, b) {
      return a + b;
    }
    
    // 箭头函数定义
    const add = (a, b) => a + b;

    2、隐式返回值

    指箭头函数中省略了return关键字,并且直接返回一个表达式的值。这意味着箭头函数可以在一行代码中完成函数体的定义和返回值的指定

    // 传统函数定义
    function multiply(a, b) {
      return a * b;
    }
    
    // 箭头函数定义
    const multiply = (a, b) => a * b;
    
    //箭头函数中省略了return关键字,并且直接返回了a * b的结果。这就是隐式返回值的概念

    需要注意的是,隐式返回值只适用于一行代码的情况。如果函数体有多行代码或者需要进行复杂的逻辑处理,仍然需要使用传统的函数定义并显式地使用return关键字。 

    const calculate = (a, b) => {
      if (a > b) {
        return a - b;
      } else {
        return b - a;
      }
    };

    在上述示例中,根据条件判断使用了显式返回值(使用return关键字),而在其他情况下则使用了隐式返回值。这样可以兼顾简洁性和灵活性。 

    3、使用箭头函数作为回调函数

    在 JavaScript 中,回调函数是指作为参数传递给其他函数的函数。在某些情况下,我们需要在回调函数中定义一些简单的逻辑来处理数据或完成一些操作。使用箭头函数作为回调函数可以使代码更加简洁,提高开发效率。

    const numbers = [1, 2, 3, 4, 5];
    
    // 传统函数定义
    //map()方法用于对数组中的每个元素进行处理,并返回一个新的数组
    const square = numbers.map(function (number) {
      return number * number;
    });
    //在传统的函数定义中,我们需要使用function关键字,同时需要使用return关键字来指定返回值。
    
    // 箭头函数定义
    const square = numbers.map((number) => number * number);
    //在箭头函数中,由于只有一行代码,我们可以使用隐式返回值的方式来简化函数定义和返回值的指定。

    需要注意的是,在使用箭头函数作为回调函数时,要根据具体的情况来考虑是否需要使用括号来包裹参数。如果只有一个参数,可以省略括号,但如果没有参数或者有多个参数,则需要使用括号。 

    4、使用箭头函数绑定外部 this 值

    箭头函数可以绑定外部 this 值,这是因为箭头函数没有自己的 this 上下文。箭头函数的 this 值继承了它所在上下文的 this 值。当我们在箭头函数中使用 this 时,它指向的就是箭头函数所在的上下文中的 this 值。

    export default {
      data() {
        return {
          message: 'Hello, World!'
        }
      },
      mounted() {
        setTimeout(() => {
          console.log(this.message) // 输出:Hello, World!
        }, 1000)
      }
    }

    在上述代码中,我们在组件的 mounted 钩子函数中使用了一个 setTimeout 函数,该函数中包含一个箭头函数作为回调函数。由于箭头函数继承了它所在上下文的 this 值,因此在箭头函数中我们可以访问到组件实例的 this 值。 

    三、模板字符串

    在 ES6 中,模板字符串是一种特殊的字符串语法,使用反引号(`)来包裹字符串内容。它允许在字符串中插入表达式,并且支持多行字符串的定义,提供了更加灵活和方便的字符串处理方式。

    1、字符串插值

    使用${}语法,在模板字符串中嵌入表达式或变量。这样可以方便地将变量的值插入到字符串中

    const name = 'SHANDONG';
    const message = `Hello, ${name}!`;
    console.log(message); // 输出:Hello, SHANDONG!

    2、多行字符串

    使用模板字符串可以方便地定义多行字符串,而无需使用\n进行换行操作

    const multiline = `
      This is
      a multiline
      string.
    `;
    console.log(multiline);
    // 输出:
    //   This is
    //   a multiline
    //   string.

    3、嵌套使用

    模板字符串可以嵌套使用,可以在一个模板字符串中插入另一个模板字符串

    const name = 'Alice';
    const message = `Hello, ${`Welcome, ${name}!`} How are you?`;
    console.log(message); // 输出:Hello, Welcome, Alice! How are you?

    总而言之,ES6 中的模板字符串提供了一种更加灵活和方便的字符串处理方式。它支持字符串插值,在字符串中嵌入表达式或变量;支持定义多行字符串,无需使用\n进行换行;还可以嵌套使用,将一个模板字符串插入到另一个模板字符串中。这些特性使得模板字符串在处理复杂字符串逻辑时更加简洁和直观。

    四、解构赋值

    一种特殊的赋值语法,可以方便地将数组或对象中的值解构到变量中;

    这样可以简化变量的声明和赋值操作,提高代码的可读性和可维护性。

    1、数组解构

    使用数组解构可以将数组中的元素解构到变量中。解构时需要使用方括号([])来包裹变量名

    const numbers = [1, 2, 3, 4];
    const [a, b, c, d] = numbers;
    console.log(a, b, c, d); // 输出:1 2 3 4

    在上面的例子中,数组中的第一个元素被解构到变量a中,第二个元素被解构到变量b中,以此类推。如果数组中的元素数量少于变量数量,未被解构的变量将会是undefined

    const numbers = [1, 2, 3];
    const [a, b, c, d] = numbers;
    console.log(a, b, c, d); // 输出:1 2 3 undefined

    2、对象解构

    使用对象解构可以将对象中的属性解构到变量中。解构时需要使用花括号({})来包裹变量名,并且变量名要与对象属性名相同

    const person = { name: 'asd', age: 20 };
    const { name, age } = person;
    console.log(name, age); // 输出:asd 20

    在上面的例子中,对象中的name属性被解构到变量name中,age属性被解构到变量age中。如果对象中没有对应的属性,变量将会是undefined

    const person = { name: 'asd', age: 20 };
    const { name, age,sex } = person;
    console.log(name, age,sex); // 输出:asd 20 undefined

    3、默认值

    可以为解构赋值设置默认值,当变量未被解构时将会使用默认值。

    const numbers = [1, 2];
    const [a, b, c = 3] = numbers;
    console.log(a, b, c); // 输出:1 2 3

    在上面的例子中,变量c设置了默认值为3。由于数组中只有两个元素,变量c未被解构,因此使用了默认值。

    4、剩余操作符

    可以使用剩余操作符(…)将剩余的数组元素或对象属性解构到一个新的数组或对象中。

    const numbers = [1, 2, 3, 4];
    const [a, b, ...rest] = numbers;
    console.log(a, b, rest); // 输出:1 2 [3, 4]
    
    const person = { name: 'Alice', age: 20, gender: 'female' };
    const { name, ...rest } = person;
    console.log(name, rest); // 输出:Alice { age: 20, gender: 'female' }

    在上面的例子中,使用剩余操作符可以将剩余的数组元素或对象属性解构到一个新的数组或对象中。在数组解构中,剩余操作符需要放在最后;在对象解构中,剩余操作符可以放在任意位置。

    五、默认参数

    在 ES6 中,可以为函数的参数设置默认值,这样在函数调用时,如果没有传递该参数或传递的值为 undefined,就会使用默认值。这样可以简化函数的调用,避免出现 undefined 的情况。

    1、设置默认值

    在函数定义时,可以通过赋值运算符(=)来为参数设置默认值。

    function greet(name = 'Guest') {
      console.log(`Hello, ${name}!`);
    }
    
    greet(); // 输出:Hello, Guest!
    greet('Alice'); // 输出:Hello, Alice!

    在上面的例子中,greet函数的name参数设置了默认值为'Guest'。当没有传递参数或传递的参数为undefined时,将会使用默认值

    2、默认值表达式

    function multiply(a, b = 2 * a) {
      return a * b;
    }
    
    console.log(multiply(5)); // 输出:50
    console.log(multiply(5,2)); // 输出:10

    在上面的例子中,multiply函数的b参数设置了默认值为2 * a。当没有传递第二个参数时,将会使用默认值,计算结果为 b=5 * 2 = 10,a*b=5*10=50;当传递第二个参数,就会直接计算 a*b=5 * 2 = 10

    3、默认参数对 arguments 对象的影响

    使用默认参数不会影响 arguments 对象的长度

    function sum(a, b = 0) {
      console.log(arguments.length);
      return a + b;
    }
    
    console.log(sum(1)); // 输出:1,返回:1
    console.log(sum(1, 2)); // 输出:2,返回:3 

    sum函数的b参数设置了默认值为0。即使没有传递第二个参数,arguments 对象的长度仍然是 1。

    需要注意的是,默认参数的作用域是函数内部,而不是全局作用域。这意味着默认参数可以访问函数体内的其他变量和参数,但不能访问函数外部的变量。

    六、Promise

    Promise 是一种用于处理异步操作的对象。它可以将异步操作封装成一个 Promise 对象,通过 then() 方法来添加回调函数,当异步操作完成时自动执行回调函数。

    function delay(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    delay(1000).then(() => console.log('1 秒后输出该信息'));

    在上面的例子中,定义了一个 delay() 函数,该函数返回一个 Promise 对象。该 Promise 对象会在指定的时间间隔之后自动执行 resolve() 方法,从而触发 then() 方法中设置的回调函数。使用 Promise 对象可以使异步操作的代码更加清晰、简洁,并且可以避免回调地狱的问题。

    Promise 对象还提供了一些其他的方法,例如 catch() 方法可以捕获异步操作中的异常,并且可以通过 Promise.all() 方法来并行处理多个异步操作。

    const promise1 = Promise.resolve(1);
    const promise2 = Promise.resolve(2);
    const promise3 = new Promise((resolve, reject) => {
      setTimeout(resolve, 1000, '3 秒后输出该信息');
    });
    
    Promise.all([promise1, promise2, promise3]).then(values => {
      console.log(values); // 输出:[1, 2, "3 秒后输出该信息"]
    });

    在上面的例子中,我们通过 Promise.resolve() 方法来创建了两个 Promise 对象,并且通过 new Promise() 方法创建了一个延时执行的 Promise 对象。我们将三个 Promise 对象放入了一个数组中,并且使用 Promise.all() 方法来并行处理这些异步操作。当所有异步操作都完成时,then() 方法中设置的回调函数将会被自动执行。

    总的来说,平时使用:

    jiekouming().then((res)=>{
    
    console.log(res)
    
    })

    七、简化对象字面量的语法

    ES6 简化对象字面量的语法主要包括两个方面的改进:属性名和方法名的简写、计算属性名。

    1、属性名和方法名的简写

    在 ES6 之前,如果我们需要将一个变量作为对象的属性名,通常需要使用计算属性名。例如:

    const obj = {  [propName]: 'value'};

    在 ES6 中,我们可以使用属性名和方法名的简写来更加方便地创建对象。

    const name = 'John';
    const age = 20;
    
    const obj = {
      name,
      age,
      sayHi() {
        console.log(`Hi, my name is ${this.name}, I'm ${this.age} years old.`);
      }
    };
    
    obj.sayHi(); // 输出:Hi, my name is John, I'm 20 years old.

    在上面的例子中,我们使用了属性名和方法名的简写语法,将变量 nameage 直接作为了对象的属性名。同时,我们也定义了一个 sayHi() 方法,并且在对象初始化时直接将其作为了一个属性。

    2、计算属性名

    ES6 提供了计算属性名的语法,允许我们在对象字面量中使用表达式来作为属性名。

    const propName = 'size';
    
    const obj = {
      [propName + 'Label']: 'Size',
      ['get' + propName]() {
        return this[propName];
      },
      set [propName](value) {
        this._size = value;
      },
      get [propName]() {
        return this._size;
      }
    };
    
    console.log(obj.sizeLabel); // 输出:Size
    
    obj.size = 10;
    console.log(obj.getSize()); // 输出:10

    在上面的例子中,我们在对象字面量中使用了计算属性名的语法,将变量 propName 和字符串 'Label' 进行了拼接,并且作为了一个属性名。同时,我们也定义了一个计算属性 size,并且使用 getset 关键字来定义了该属性的读取和修改方法。

    八、扩展运算符

    ES6 中的扩展运算符用三个连续的点 ... 表示,主要用于将一个可迭代对象(如数组、字符串或类数组对象)展开成多个元素

    1、数组的展开

    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    
    const combinedArray = [...arr1, ...arr2];
    console.log(combinedArray); // 输出:[1, 2, 3, 4, 5, 6]

    在上面的例子中,我们使用扩展运算符将两个数组 arr1arr2 展开,并且合并成一个新的数组 combinedArray

    2、字符串的展开

    const str = 'hello';
    const chars = [...str];
    
    console.log(chars); // 输出:['h', 'e', 'l', 'l', 'o']

    在上面的例子中,我们使用扩展运算符将字符串 str 展开成一个字符数组 chars,每个字符都成为了数组的一个元素。 

    3、函数的参数传递

    function sum(a, b, c) {
      return a + b + c;
    }
    
    const numbers = [1, 2, 3];
    const result = sum(...numbers);
    
    console.log(result); // 输出:6

     在上面的例子中,我们定义了一个求和函数 sum(),并且使用扩展运算符将数组 numbers 的元素作为函数的参数进行传递。

    4、对象的展开

    const obj1 = { foo: 'bar' };
    const obj2 = { baz: 'qux' };
    
    const mergedObj = { ...obj1, ...obj2 };
    console.log(mergedObj); // 输出:{ foo: 'bar', baz: 'qux' } 

    在上面的例子中,我们使用扩展运算符将两个对象 obj1obj2 的属性展开,并且合并成一个新的对象 mergedObj

    扩展运算符不仅可以用于数组、字符串、对象的展开,还可以用于函数调用时的参数展开等场景,能够让我们更方便地处理和操作数据。

    九、模块化导入和导出

    当使用模块化导入和导出时,可以将 JavaScript 代码分割为多个模块,每个模块负责封装和导出特定的功能,然后在其他模块中导入并使用这些功能。这种模块化的方式有助于提高代码的可维护性和可重用性。

    假设我们有一个名为 math.js 的模块,其中定义了一些数学相关的函数:

    // math.js 
    export function add(a, b) {  
        return a + b;
    } 
    
    export function subtract(a, b) {  
        return a - b;
    } 
    
    export const PI = 3.14159;

    在另一个模块中,我们可以使用 import 关键字导入 math.js 模块中的函数和变量:

    // app.js 
    import { add, subtract, PI } from './math.js'; 
    
    console.log(add(2, 3)); // 输出:5
    console.log(subtract(7, 4)); // 输出:3
    console.log(PI); // 输出:3.14159

    我们使用 import 关键字从 math.js 模块中导入 addsubtract 函数和 PI 变量。然后,在 app.js 模块中,我们可以像使用本地函数和变量一样使用它们。

    除了按需导入特定函数和变量外,还可以使用 import * as 语法导入整个模块的所有导出:

    // app.js 
    import * as math from './math.js'; 
    console.log(math.add(2, 3)); // 输出:5
    console.log(math.subtract(7, 4)); // 输出:3
    console.log(math.PI); // 输出:3.14159

    我们使用 import * as 将整个 math.js 模块导入为 math 对象。然后,我们可以通过该对象访问模块中的所有导出。

    十、数组新增方法

    ES6 在数组原型上新增了一些方法,如 find、findIndex、includes 等,方便对数组进行查找和操作

    1、Array.prototype.find()

    find() 方法返回数组中满足指定条件的第一个元素。如果找到了符合条件的元素,则返回该元素;否则返回 undefined。

    const arr = [1, 2, 3, 4, 5];
    
    // 查找数组中第一个大于等于 3 的元素
    const result = arr.find(item => item >= 3);
    
    console.log(result); // 输出:3

    2、Array.prototype.findIndex()

    findIndex() 方法返回数组中满足指定条件的第一个元素的索引。如果找到了符合条件的元素,则返回该元素的索引;否则返回 -1。

    const arr = [1, 2, 3, 4, 5];
    
    // 查找数组中第一个大于等于 3 的元素的索引
    const index = arr.findIndex(item => item >= 3);
    
    console.log(index); // 输出:2

    3、Array.prototype.includes()

    includes() 方法判断数组中是否包含指定元素,如果包含则返回 true;否则返回 false。

    const arr = [1, 2, 3, 4, 5];
    
    // 判断数组中是否包含 3
    const isIncluded = arr.includes(3);
    
    console.log(isIncluded); // 输出:true

    4、Array.prototype.fill()

    fill() 方法用指定的值填充数组中的所有元素。

    const arr = [1, 2, 3, 4, 5];
    
    // 将数组中所有元素都填充为 0
    arr.fill(0);
    
    console.log(arr); // 输出:[0, 0, 0, 0, 0]

    5、Array.prototype.flat()

    flat() 方法将多维数组扁平化为一维数组。

    const arr = [1, [2, [3, [4, 5]]]];
    
    // 扁平化数组
    const flatArr = arr.flat();
    
    console.log(flatArr); // 输出:[1, 2, 3, 4, 5]

    十一、迭代器和生成器

    ES6 引入了迭代器和生成器的概念,通过 Symbol.iterator 和 function*关键字可以创建可迭代对象和生成器函数,用于更灵活地进行迭代操作。

    1、迭代器

    迭代器是一种特殊对象,可以用来遍历集合中的元素。在 JavaScript 中,一个对象如果具有 Symbol.iterator 属性并且该属性是一个函数,则称该对象为可迭代对象,并且可以使用 for...of 循环或者 ... 运算符对其进行遍历。

    const myIterator = {
      data: [1, 2, 3],
      [Symbol.iterator]() {
        let index = 0;
        return {
          next: () => {
            if (index < this.data.length) {
              return { value: this.data[index++], done: false };
            } else {
              return { done: true };
            }
          }
        };
      }
    };
    
    for (let item of myIterator) {
      console.log(item);
    }
    // 输出:1 2 3
    我们定义了一个自定义迭代器 myIterator,它包含一个数组 data 和一个 Symbol.iterator 属性,该属性返回一个迭代器对象。该迭代器对象包含一个 next() 方法,每次调用 next() 方法都会返回一个包含 value 和 done 两个属性的对象。

    2、生成器

    生成器是一种特殊的函数,可以通过 function* 关键字来定义。生成器函数执行时不会立即执行函数体,而是返回一个迭代器对象,通过迭代器对象可以逐步执行函数体,并返回多个值。

    function* myGenerator() {
      yield 1;
      yield 2;
      yield 3;
    }
    
    const generator = myGenerator();
    
    console.log(generator.next()); // 输出:{ value: 1, done: false }
    console.log(generator.next()); // 输出:{ value: 2, done: false }
    console.log(generator.next()); // 输出:{ value: 3, done: false }
    console.log(generator.next()); // 输出:{ done: true }

    我们定义了一个生成器函数 myGenerator,它包含三个 yield 表达式。我们通过调用该函数得到一个迭代器对象 generator,每次调用 generator.next() 都会执行一次函数体,并返回一个包含 valuedone 两个属性的对象。当函数执行完毕时,done 属性为 true

    十二、类和继承

    ES6 引入了类的概念,更贴近传统面向对象编程的语法。

    在 JavaScript 中,是通过构造函数来生成实例对象。

    function A(a){
        this.a=a
    }
    A.prototype.sayA=function(){
        console.log(this.a)
    }
    var a=new A('a')
    a.sayA()

    ES6中引入了 class(类)的概念,通过class关键字可以定义类。这种写法使得对象原型的写法更加清晰、更像面对对象编程的语法了。

    class A{
        // constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
        constructor(a){
            this.a=a
        }
        sayA(){
            console.log(this.a)
        }
    }
    var a=new A('a')
    a.sayA()

    在定义类的方法时,不需要加上 function 关键字,使用的时候也是直接对类进行new命令,跟构造函数是一样的。

    构造函数的prototype属性,在 ES6 的类中继续存在,类的所有方法都定义在类的prototype属性上面。

    class A{
        constructor(){
        }
        sayA(){}
        sayB(){}
    }

    相当于

    A.prototype={
        sayA(){},
        sayB(){}
    }

    十三、Map和Set

    提供了更方便的键值对集合和无重复值的集合。

    const map = new Map();
    map.set('key', 'value');
    const set = new Set([1, 2, 3]);

    本文转载自:ES6 语法详解+面试必备

    提醒:本文发布于129天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • Vue2 基础详解


    共计 20556 个字符,预计需要花费 52 分钟才能阅读完成。

    一、项目结构和入口

    1. 创建vue项目

    # 1. 安装vue-cli
    npm install -g vue-cli
    
    # 2. 创建vue项目
    vue init webpack demo_vue2
    
    # 接下来会提示输入项目名称、描述等等
    (node:12404) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
    (Use `node --trace-deprecation ...` to show where the warning was created)
    ? Project name demo_vue2
    ? Project description vue
    ? Author hausen1012 <9470835+hausen1012@user.noreply.gitee.com>
    ? Vue build standalone
    ? Install vue-router? No
    ? Use ESLint to lint your code? No
    ? Set up unit tests No
    ? Setup e2e tests with Nightwatch? No
    ? Should we run `npm install` for you after the project has been created? (recommended) npm
    
       vue-cli · Generated "demo_vue2".
    # Installing project dependencies ... 

    2. vue 的项目结构

    vue2 创建后的项目结构如下:

    demo_vue2/
    │
    ├── build/
    │   ├── build.js               # 生产环境构建脚本
    │   ├── buildjs.js             # 生成生产环境的 JavaScript
    │   ├── check-versions.js      # 检查当前环境的 Node 和 npm 版本
    │   ├── logo.png               # 一个 logo 图片
    │   ├── utils.js               # 构建过程中的工具函数
    │   ├── vue-loader.conf.js     # Vue 组件的 webpack loader 配置
    │   ├── webpack.base.conf.js   # webpack 基础配置
    │   ├── webpack.dev.conf.js    # webpack 开发环境配置
    │   └── webpack.prod.conf.js   # webpack 生产环境配置
    │
    ├── config/
    │   ├── dev.env.js         # 开发环境配置
    │   ├── index.js           # 项目配置的主要入口
    │   └── prod.env.js        # 生产环境配置
    │
    ├── node_modules/          # 依赖的 npm 包
    │
    ├── src/
    │   ├── assets/            # 静态资源文件,如图片、样式表等
    │   │   └── logo.png       # 一个 logo 图片
    │   ├── components/        # 可复用的 Vue 组件
    │   │   └── HelloWorld.vue # HelloWorld 组件
    │   ├── App.vue            # 应用的根组件
    │   └── main.js            # 应用的入口文件
    |
    ├── static/            # 静态文件目录
    ├── .babelrc               # Babel 配置文件
    ├── .editorconfig          # 编辑器配置文件,用于统一不同编辑器的代码风格
    ├── .gitignore             # Git 版本控制忽略文件
    ├── .postcssrc.js          # PostCSS 配置文件
    ├── index.html             # 应用的 HTML 入口文件
    ├── package-lock.json      # 锁定依赖包版本的 npm 自动生成文件
    ├── package.json           # 项目的配置文件,包含了依赖信息、脚本等
    └── README.md              # 项目说明文档

    Babel 配置文件通常,.babelrc 文件会包含一些预设(presets)和插件(plugins),例如 @babel/preset-env,它可以根据指定的目标环境自动确定需要转换的 JavaScript 特性。

    3. vue项目的运行

    这里的入口文件是 scr/main.js,它是由 webpack 的构建配置文件决定的,这个文件通常为 webpack.base.conf.js

    运行流程:

    Vue2 基础详解

    />

    main.js 内容通常为如下:

    // 导入vue组件库
    import Vue from 'vue'
    // 导入根组件 App
    import App from './App'
    
    // 这行代码关闭了 Vue.js 在控制台输出生产模式提示的功能。在生产环境中,通常不需要这些提示,因此关闭可以减少输出的噪音。
    Vue.config.productionTip = false
    
    // 创建vue实例。
    new Vue({
      el: '#app', // 指定 vue 实例要挂载的 DOM 元素。(将 vue 模板内容挂载到该容器下)
      components: { App }, // 注册App组件才能在模板中使用。否则下面那行不能使用
      template: '<App/>' // 指定了 Vue 实例的模板。(将 App 组件渲染的内容挂载到 id 为 app 的元素下)
    })

    然后可以看看 App.vue 文件里面具体是什么内容。

    <!--相当于 html -->
    <template>
      <div id="app">
        <img src="https://www.amjun.com/assets/logo.png">
        <HelloWorld/>
      </div>
    </template>
    
    <!--相当于 js -->
    <script>
    import HelloWorld from './components/HelloWorld'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      }
    }
    </script>
    
    <!--相当于 css -->
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    .vue 为后缀的文件,即 vue 项目中的组件。一般分为三个部分,templatescriptstyle 分别对应网页三元素中的 htmljscss

    这里的 App 组件主要的作用是,显示一个 logo 图片,下面是 HelloWorld 组件的内容。

    HelloWorld.vue 内容基本都是一些 vue 相关的链接,内容在这里就不贴了,运行后访问可以看见内容如下:

    Vue2 基础详解

    />

    二、vue指令

    Vue 中的指令是一种特殊的语法,用于向 HTML 元素添加特殊行为。指令以 v- 开头,后跟指令名称,例如 v-bindv-ifv-for 等。每个指令都提供了一些特定的功能,可以根据特定的条件或数据来改变 DOM 的结构、属性或其他行为。

    1. 内容渲染指令

    • v-text(类似innerText)

      • 使用语法:<p v-text="uname">hello</p>,意思是将uname值渲染到p标签中
      • 类似innerText,使用该语法,会覆盖p标签原有内容
    • v-html(类似innerHTML)

      • 使用语法:<p v-html="intro">hello</p>,意思是将intro值渲染到p标签中
      • 类似innerHTML,使用该语法,会覆盖p标签原有内容,能够将HTML标签的样式呈现出来
    <template>
        <div id="app">
            <h2>个人信息</h2>
            <!-- 指令是 vue 提供的特殊的 html 属性,写的时候就当成属性来用即可 -->
            姓名:<span v-text="uname">张三</span><br>
            简介:<span v-html="intro">没有简介</span>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    uname: '李四',
                    intro: '<h2>这是一个<strong>非常优秀</strong>的boy<h2>'
                }
            }
        }
    </script>

    其中模板内的 张三没有简介 将被替换,并且会有相关提示:

    v-text/v-html will override element children.

    意思就是即使里面写了内容,也会被 v-textv-html 重写。

    2. 条件渲染指令

    条件判断指令,用来辅助开发者按需控制DOM的显示与隐藏。条件渲染指令有如下两个,分别是:

    • v-show

      • 作用:控制元素显示隐藏
      • 语法:v-show=”表达式”。表达式值为 true 显示,false 隐藏
      • 原理:切换display:none控制显示隐藏
      • 场景:频繁切换显示隐藏的场景
    • v-if

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

    v-elsev-else-if 是复制 v-if 的指令。

    <template>
        <!-- 
            v-show 底层原理:切换css的display:none来控制显示隐藏
            v-if 底层原理:根据判断条件控制元素的创建和移除
        -->
        <div id="app">
            <div v-show="flag" class="box">我是v-show控制的盒子</div>
    
            <hr>
            <div>成绩:{{ score }}</div>
            <p v-if="score>=90">成绩评定A:奖励电脑一台</p>
            <p v-else-if="score>=70">成绩评定B:奖励周末郊游</p>
            <p v-else-if="score>=60">成绩评定C:奖励零食礼包</p>
            <p v-else>成绩评定D:惩罚一周不能玩手机</p>
    
            <button @click="addScore()">成绩-10</button>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    flag: true,
                    score: 90
                }
            },
            methods: {
                addScore(){
                    console.log(this.score)
                    this.score -= 10
                }
            }
        }
    </script>

    3. 事件绑定指令

    v-on 指令用于向 DOM 注册事件,语法如下:

    • <button v-on:事件名=”内联语句”>按钮
    • <button v-on:事件名=”处理函数”>按钮
    • <button v-on:事件名=”处理函数(实参)”>按钮

    语法糖: v-on: 简写为 @

    3.1 内联语句

    <template>
        <div id="app">
        <button v-on:click="count--">-</button> 
        <span>{{count}}</span>
        <!-- 使用语法糖 -->
        <button @click="count++">+</button>
    </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    count: 100
                }
            },
            methods: {
    
            }
        }
    </script>

    3.2 内联语句

    <template>
        <div id="app">
            <button @click="changeStatus">显示/隐藏</button>
            <h1 v-show="isShow">你好啊</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    isShow:true
                }
            },
            methods: {
                changeStatus(){
                    //app.isShow=!app.isShow
                    //methods函数内的this指向Vue实例
                    this.isShow=!this.isShow
                }
            }
        }
    </script>

    3.3 给事件处理函数传参

    <template>
        <div id="app">
            <div class="box">
            <h3>小黑自动售货机</h3>
            <button @click="buy(5)">可乐5元</button>
            <button @click="buy(10)">咖啡10元</button>
            </div>
            <p>银行卡余额:{{money}}元</p>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    money: 100
                }
            },
            methods: {
                buy(price) {
                    this.money -= price
                }
            }
        }
    </script>

    4. 属性绑定指令

    4.1 基本使用

    v-bind 指令用于设置 html 的标签属性,如:src、url、title。

    语法糖: v-bind: 简写为 :

    <template>
        <div id="app">
            <img v-bind:src="https://www.amjun.com/pic">
            <!-- 简写 -->
            <img :src="https://www.amjun.com/pic">
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    pic: "https://picsum.photos/960/540"
                }
            }
        }
    </script>

    4.2 动态参数

    从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

    <a v-bind:[attributeName]="url"> ... </a>
    <!-- 动态参数的缩写 (2.6.0+) -->
    <a :[attributeName]="url"> ... </a>

    这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 “href”,那么这个绑定将等价于 v-bind:href。

    <template>
        <div id="app">
            <img v-bind:[attributeName]="pic">
            <!-- 简写 -->
            <img :[attributeName]="pic">
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    attributeName: "src",
                    pic: "https://picsum.photos/960/540"
                }
            }
        }
    </script>

    同样地,你可以使用动态参数为一个动态的事件名绑定处理函数

    <a v-on:[eventName]="doSomething"> ... </a>
    <!-- 动态参数的缩写 (2.6.0+) -->
    <a @[event]="doSomething"> ... </a>

    在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus

    4.3 样式控制增强

    v-bind 对样式控制的增强。Vue 扩展了 v-bind 的语法,可以针对 class 类名和 style 行内样式进行控制。

    • 普通形式:
    <div :class="对象or数组">这是一个div</div>
    • 对象语法:

    当 class 动态绑定的是对象时,键就是类名,值就是布尔值,如果值是 true,就有这个类,否则没有这个类

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

    适用场景:一个类名来回切换

    <template>
        <div id="app">
            <h1 class="box" :class="{ 'red-font': flag, 'green-font': !flag }">{{ msg }}</h1>
            <button @click="change()">切换字体颜色</button>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    msg: "hello",
                    flag: true
                }
            },
            methods: {
                change() {
                    console.log(this.flag)
                    this.flag = !this.flag
                }
            }
        }
    </script>
    
    <style scoped>
        .red-font {
            color: red;
        }
        .green-font {
            color: green;
        }
    </style>
    • 数组语法:

    当 class 动态绑定的是数组时,数组中所有的类都会添加到盒子上,本质就是一个 class 列表

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

    使用场景:批量添加或删除类。

    <template>
        <div id="app">
            <h1 class="box" :class=classList >{{ msg }}</h1>
            <button @click="addClass()">增加样式</button>
            <button @click="removeClass()">去掉样式</button>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    msg: "hello",
                    classList: []
                }
            },
            methods: {
                addClass() {
                    this.classList.push('red-font', 'green-background');
                },
                removeClass() {
                    this.classList = []
                }
            }
        }
    </script>
    
    <style scoped>
        .red-font {
            color: red;
        }
        .green-background {
            background-color: green;
        }
    </style>

    5. 列表渲染指令

    v-for 指令用来辅助开发者基于一个数组来循环渲染一个列表结构。

    v-for 指令需要使用(item , index) in arr形式的特殊语法,其中:

    • item是数组中的每一项
    • index是每一项的索引,不需要可以省略
    • arr是被遍历的数组
    <template>
        <div id="app">
            <h3>小黑的书架</h3>
            <ul v-for="(item,index) in booksList" :key="item.id">
                <li>
                    <span>{{ index }}</span>
                    <span>{{item.name}}</span>
                    <span>{{item.author}}</span>
                    <button @click="del(item.id)">删除</button>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    booksList: [
                        { id: 1, name: '《红楼梦》', author: '曹雪芹' },
                        { id: 2, name: '《西游记》', author: '吴承恩' },
                        { id: 3, name: '《水浒传》', author: '施耐庵' },
                        { id: 4, name: '《三国演义》', author: '罗贯中' }
                    ]
                }
            },
            methods: {
                del(id) {
                    this.booksList = this.booksList.filter(item => item.id != id);
                }
            }
        }
    </script>

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

    注意:

    • key的值只能是字符串或数字类型
    • key的值必须具有唯一性
    • 推荐使用id作为key(唯一),不推荐使用index作为key

    6. 双向绑定指令

    6.1 概述

    所谓双向绑定就是:

    1. 数据改变后,呈现的页面结果会更新
    2. 页面结果更新后,数据也会随之改变

    作用:给表单元素(input、radio、select)使用,双向绑定数据,可以快速获取或设置表单元素内容。

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

    它会根据控件类型自动选取正确的方法来更新元素:

    输入框 input:text ——> value
    文本域 textarea ——> value
    复选框 input:checkbox ——> checked
    单选框 input:radio ——> checked
    下拉菜单 select ——> value

    <template>
        <div id="app">
            <h3>小黑学习网</h3>
            <div>姓名:{{ username }}</div>
            输入姓名:
            <input type="text" v-model="username">
            <hr>
    
            <div>
                是否勾选:
                <span v-if="isSingle">是</span>
                <span v-else>否</span>
            </div>
            是否单身:
            <input type="checkbox" v-model="isSingle">
            <hr>
    
            <!-- 
            前置理解:
                1. name:  给单选框加上 name 属性 可以分组 → 同一组互相会互斥
                2. value: 给单选框加上 value 属性,用于提交给后台的数据
            结合 Vue 使用 → v-model
            -->
            <div>
                你选择的性别:
                <span v-if="gender == 1">男</span>
                <span v-else>女</span>
            </div>
            性别:
            <input v-model="gender" type="radio" name="gender" value="1">男
            <input v-model="gender" type="radio" name="gender" value="2">女
            <hr>
    
            <!-- 
            前置理解:
                3. option 需要设置 value 值,提交给后台
                4. select 的 value 值,关联了选中的 option 的 value 值
            结合 Vue 使用 → v-model
            -->
            <div>
                所在的城市:
                <span v-if="city == 101">北京</span>
                <span v-else-if="city == 102">上海</span>
                <span v-else-if="city == 103">成都</span>
                <span v-else-if="city == 104">南京</span>
            </div>
            所在城市:
            <select v-model="city">
                <option value="101">北京</option>
                <option value="102">上海</option>
                <option value="103">成都</option>
                <option value="104">南京</option>
            </select>
            <hr>
    
            <div>自我描述:{{ desc }}</div>
            <textarea v-model="desc"></textarea>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    username: 'zhangsan',
                    isSingle: false,
                    gender: 1,
                    city: '102',
                    desc: "暂无"
                }
            }
        }
    </script>

    6.2 原理

    v-model 本质上是一个语法糖。例如应用在输入框上,就是 value 属性和 input 事件的合写。

    <template>
      <div id="app" >
        <input v-model="msg" type="text">
        <input :value="msg" @input="msg = $event.target.value" type="text">
      </div>
    </template>

    对于 select:

    <select :value="selectedOption" @change="selectedOption = $event.target.value">
        <option value="option1">Option 1</option>
        <option value="option2">Option 2</option>
    </select>

    7. 指令修饰符

    指令修饰符就是通过 . 指明一些指令后缀,不同的后缀封装了不同的处理操作。

    按键修饰符

    • @keyup.enter:当点击 enter 键的时候才触发
    <template>
        <div id="app">
            <h3>@keyup.enter → 监听键盘回车事件</h3>
            <input @keyup.enter="fn" v-model="username" type="text">
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    username: '张三'
                }
            },
            methods: {
                fn(e) {
                    if (e.key === "Enter") {
                        alert(this.username);
                    }
                }
            }
        }
    </script>

    v-model修饰符

    • v-model.trim:去除首位空格
    • v-model.number:转数字
    <template>
        <div id="app">
            <h3>v-model修饰符 .trim .number</h3>
            姓名:<input v-model.trim="username" type="text"><br>
            年纪:<input v-model.number="age" type="text"><br>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    username: '',
                    age: '',
                }
            }
        }
    </script>

    事件修饰符

    • @事件名.stop:阻止冒泡
    • @事件名.prevent:阻止默认行为
    • @事件名.stop.prevent:可以连用,即阻止事件冒泡也阻止默认行为
    <template>
        <div id="app">
            <h3>@事件名.stop → 阻止冒泡</h3>
            <div @click="fatherFn" class="father">
                <!-- 不阻止冒泡会弹窗两次 -->
                <div @click.stop="sonFn" class="son">儿子</div>
            </div>
            <h3>@事件名.prevent → 阻止默认行为</h3>
            <!-- 阻止默认行为后无法跳转百度 -->
            <a @click.prevent href="http://www.baidu.com">阻止默认行为</a>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            methods: {
                fatherFn() {
                    alert('老父亲被点击了')
                },
                sonFn() {
                    alert('儿子被点击了')
                }
            }
        }
    </script>

    三、计算属性和侦听器

    1. 计算属性

    1.1 概念

    计算属性的概念是基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算。

    语法

    • 声明在 computed 配置项中,一个计算属性对应一个函数
    • 使用起来和普通属性一样使用 {{计算属性名}}

    优势

    • 计算属性会对计算出来的结果缓存,再次使用直接读取缓存
    • 依赖项变化了,会自动重新计算并再次缓存

    注意

    • computed 配置项和 data 配置项是同级的
    • computed 中的计算属性虽然是函数的写法,但他仍然是个属性
    • computed 中的计算属性不能和 data 中的属性同名
    • 使用 computed 中的计算属性和使用 data 中的属性是一样的用法
    • computed 中计算属性内部的 this 依然指向的是 Vue 实例

    1.2 基本使用

    对于任何复杂逻辑,都应当使用计算属性,如下案例:

    <template>
        <div id="app">
          <p>原始内容: "{{ message }}"</p>
          <p>反转原始内容: "{{ reversedMessage }}"</p>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    message: 'Hello'
                }
            },
            computed: {
                // 计算属性的 getter
                reversedMessage: function () {
                    // `this` 指向 vm 实例
                    return this.message.split('').reverse().join('')
                }
            }
        }
    </script>

    1.3 完整写法

    计算属性默认的简写,只能读取访问,不能修改,如果要修改,需要写计算属性的完整写法。

    <template>
        <div id="app">
            姓:<input type="text" v-model="firstName"><br>
            名:<input type="text" v-model="lastName"><br>
            <p>姓名:{{fullName}}</p>
            <button @click="changeName">修改姓名</button>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    firstName: '刘',
                    lastName: '备',
                }
            },
            methods: {
                changeName() {
                    this.fullName = "吕小布"
                }
            },
            computed: {
                //完整写法:获取+设置
                fullName: {
                    //当fullName计算属性被获取求值时,执行get(有缓存,优先读缓存)
                    //会将返回值作为求值的结果
                    get() {
                        return this.firstName + this.lastName
                    },
                    //当fullName计算属性被修改赋值时,执行set
                    //修改的值传递给set方法的形参
                    set(value) {
                        this.firstName = value.slice(0, 1)
                        this.lastName = value.slice(1)
                    }
                }
            }
        }
    </script>

    2. 侦听器

    2.1 概念

    侦听器用于监视数据变化,执行一些业务逻辑或异步操作。

    语法

    • watch 同样声明在跟 data 同级的配置项中
    • 简单写法:简单类型数据直接监视
    • 完整写法:添加额外配置项

    2.2 基本使用

    除了以下案例,还可以使用侦听器监听输入框的变化,发送ajax请求,判断用户可能需要输入的关键词,比如百度搜索。

    <template>
        <div id="app">
            <p>计数器: {{ counter }}</p>
            <button @click="increment">增加</button>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data () {
                return {
                    counter: 0
                }
            },
            methods: {
                increment() {
                    this.counter++;
                }
            },
            watch: {
                counter(newValue, oldValue) {
                    alert('计数器的值发生变化了:' +  oldValue + '→' + newValue);
                    console.log('计数器的值发生变化了:', oldValue, '→', newValue);
                }
            }
        }
    </script>

    四、生命周期

    1. 简介

    Vue 生命周期:就是一个 Vue 实例从创建到销毁的整个过程

    生命周期分为四个阶段:创建、挂载、更新、销毁

    1. 创建阶段:创建Vue实例
    2. 挂载阶段:渲染模板
    3. 更新阶段:修改数据,更新视图
    4. 销毁阶段:销毁Vue实例

    Vue2 基础详解

    />

    2. 生命周期钩子

    Vue 生命周期过程中,会自动运行一些函数,被称为生命周期钩子,让开发者可以在特定阶段运行自己的代码。

    既然有 4 个阶段,每个阶段都有两个周期,所以一共是八个周期。

    <template>
      <div>
        <h3>计数器:{{ count }}</h3>
        <button @click="count++">计数器+1</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data() {
        return {
            count: 100,
        };
      },
      beforeCreate() {
        // this.count 为 undefined
        console.log('vue 实例创建之前', this.count);
      },
      created() {
        // this.count 为 100
        console.log('vue 实例创建之后', this.count);
      },
      beforeMount() {
        console.log('模板挂载之前');
      },
      mounted() {
        console.log('模板挂载之后');
      },
      // 更新之前和更新之后打印的 count 时一样的,区别只在于数据有没有更新到页面上
      beforeUpdate() {
        console.log('数据更新之前', this.count);
      },
      updated() {
        console.log('数据更新之后', this.count);
      },
      // 比如说到路由时,需要展示其他组件,那个这个组件就需要销毁
      beforeDestroy() {
        console.log('vue 实例销毁之后');
      },
      destroyed() {
        console.log('vue 实例销毁之后');
      },
    };
    </script>

    五、组件

    1. 概念

    在 Vue 中,组件是可复用的 Vue 实例,可以将其看作是自定义元素,用于构建用户界面中的各种功能块。

    并且 Vue 中有组件树的概念,其中 App.vue 就是根组件,它包含应用的整体布局和结构,同时它也可以包含其他的子组件。

    Vue2 基础详解

    />

    使用组件化开发有利于维护,并且便于复用。

    Vue2 基础详解

    />

    2. 构成

    组件是由三部分构成

    • template:结构(有且只有一个根元素)
    • script:js 逻辑
    • style:样式(可支持 less)
    <template>
      <div>
        <h3>计数器:{{ count }}</h3>
        <button @click="count++">计数器+1</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data() {
        return {
            count: 100,
        };
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    • data 返回函数

    这里需要注意的是,除了根组件,其他组件定义的 data 数据都是返回一个函数。目的是为了:保证每个组件实例,维护独立的一份数据对象。

    • scoped 解决样式冲突

    通过添加 scoped 属性到 <style>标签,可以使得样式仅对当前组件起作用。这意味着在一个组件中定义的样式规则将不会影响到其他组件,即使它们使用了相同的类名或选择器。

    3. 组件注册

    组件需要使用到另外一个组件,需要进行组件注册,否则无法使用。其中,组件注册又分为全局组件注册和局部组件注册。

    • 全局组件注册

    全局组件注册是指在 Vue 对象中直接注册组件,这种方式注册的组件在任何地方都可以使用,而不需要再次注册。

    import Vue from 'vue'
    import App from './App'
    
    Vue.component('HelloWorld', HelloWorld)
    
    new Vue({
      el: '#app',
      components: { App },
      template: '<App/>'
    })
    • 局部注册

    局部注册指,某个组件需要哪个组件,就在这个组件中注册需要的组件。

    <template>
      <div id="app">
        <HelloWorld/>
      </div>
    </template>
    
    <script>
    import Test from './components/HelloWorld'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      }
    }
    </script>

    像上面这样,局部注册了 HelloWorld 组件,那么在 App.vue 中就可以直接使用 HelloWorld 组件。

    六、组件通信

    1. 简介

    组件通信,就是指组件与组件之间的数据传递

    • 组件的数据是独立的,无法直接访问其他组件的数据。
    • 想使用其他组件的数据,就需要组件通信

    组件关系分类

    • 父子关系
    • 非父子关系

    通信解决方案

    Vue2 基础详解

    />

    2. 父子组件通信

    2.1 父传子

    父组件通过 props 将数据传递给子组件,props 是组件上注册的一些自定义属性。

    特点:

    • 可以传递任意数量的 prop
    • 可以传递任意类型的 prop

    props 和 data 都可以给组件提供数据,区别是 data 的数据是自己的,可以随便改;props 的数据是外部的,不能直接改,要遵循单向数据流。(父级props的数据更新,会向下流动,影响子组件。这个数据流动是单向的)

    三个步骤:

    1. 给子组件以添加属性的方式传值
    2. 子组件内部通过props接收
    3. 模板中直接使用props接收的值

    Vue2 基础详解

    />

    2.2 子传父

    子传父需要通过事件来进行修改。

    三个步骤:

    1. 父组件监听 $emit 触发的事件
    2. $emit 触发事件,给父组件发送消息通知
    3. 提供处理函数,在函数的形参中获取传过来的参数

    Vue2 基础详解

    />

    3. 非父子组件通信

    3.1 event bus

    event bus 事件总线可以在非父子组件之间,进行简易的消息传递。

    四个步骤:

    1. 创建全局事件总线
    2. 设置监听事件
    3. 触发监听事件
    4. 提供处理函数,在函数的形参中获取传过来的参数

    Vue2 基础详解

    />

    3.2 provide&inject

    语法

    1. 父组件provide提供数据
    export default {
      provide () {
        return {
           // 普通类型【非响应式】
           color: this.color, 
           // 复杂类型【响应式】
           userInfo: this.userInfo, 
        }
      }
    }
    1. 子/孙组件 inject获取数据
    export default {
      inject: ['color','userInfo'],
    }

    注意:

    • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式的。(推荐实验复杂类型的数据)
    • 子/孙组件通过inject获取的数据,不能在自身组件内修改

    七、自定义指令

    1. 概念

    自定定义的指令,可以封装一些 DOM 操作,扩展额外的功能。

    • 内置指令:v-htmlv-ifv-bindv-on… 这都是 Vue 内置的一些指令,可以直接使用
    • 自定义指令:同时Vue也支持让开发者自己注册一些指令。这些指令被称为自定义指令。每个指令都有自己各自独立的功能。

    2. 基本语法

    • 全局指令注册
    //全局注册指令
    Vue.directive('focus', {
      //inserted 会在指令所在的元素被插入到页面中时触发
      inserted(el) {
        //el 就是指令所绑定的元素
        el.focus();
      }
    })
    • 局部指令注册
    directives:{
        //指令名:指令的配置项
        focus: {
            inserted(el){
                el.focus()
            }
        }
    }

    注意:

    • 使用指令之前一定要注册
    • 注册指令时不加 -v,使用时一定要加 -v

    3. 实现自定义指令

    实现一个color指令,传入不同的颜色,给标签设置文字颜色。

    <template>
        <div id="app" >
            <h1 v-color="color1">指令的值1测试</h1>
            <h1 v-color="color2">指令的值2测试</h1>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            data: function () {
                return {
                    color1: 'red',
                    color2: 'green'
                }
            },
            directives: {
                color: {
                    //1.inserted 提供的是元素被添加到页面中的逻辑
                    inserted(el, binding) {
                        //el.style.color='red'
                        el.style.color = binding.value
                    },
                    //2.update 指令的值修改的时候触发,提供值变化后,dom 更新的逻辑
                    update(el, binding) {
                        el.style.color = binding.value
                    }
                }
            }
        }
    </script>

    八、插槽

    1. 概念

    Vue 的插槽(slot)是一种机制,允许在父组件中向子组件传递内容。它允许你在子组件的特定位置插入任意内容,而不受子组件内部结构的限制。这对于创建可复用的组件以及在不同场景下灵活地组合内容非常有用。

    插槽可分为默认插槽、具名插槽和作用域插槽。

    • 默认插槽:默认插槽是一种简单的插槽,其实是一种特殊的具名插槽,名称为 default
    • 具名插槽:具名插槽允许子组件定义多个插槽位置,并且可以在父组件中指定要插入的内容到哪个插槽中
    • 作用域插槽:作用域插槽允许子组件将数据传递到父组件,使父组件可以在插槽中使用子组件的数据。(作用域可以这么理解,子组件的数据有作用域限制,但是作用域插槽可以将其传递到父组件使用)

    2. 默认插槽

    使用默认插槽非常简单,只需要预留一个插槽位置即可,然后引用组件,组件中间的内容就会插入到插槽中。

    HelloWorld.vue

    <template>
      <div id="app">
        <h3>父组件</h3>
        <div class="content">
          <Card title="游戏列表">
              <ul>
                <li v-for="item in gameList" :key="item.id">{{ item.name }}</li>
              </ul>
          </Card>
          <Card title="图片展示">
              <img :src="https://www.amjun.com/picUrl">
          </Card>
          <Card title="消息通知">
             {{ msg }}
          </Card>
        </div>
      </div>
    </template>
    
    <script>
    import Card from './Card.vue';
    
    export default {
      name: 'HelloWorld',
      components: {
        Card
      },
      data () {
        return {
          gameList: [
            { id: 1, name: "王者荣耀"},
            { id: 2, name: "原神"},
            { id: 3, name: "英雄联盟"}
          ],
          picUrl: "https://fastly.picsum.photos/id/77/960/540.jpg?hmac=idkrsBSL_IbzHXXXS3HYS-ZmT3_P4cq0hWPynF1llk8",
          msg: "明天放假!"
        }
      }
    }
    </script>
    
    <style scoped>
      #app {
        background-color: #ccc;
        padding: 20px;
      }
    
      .content {
        display: flex;
        justify-content: space-evenly;
      }
    
      img, video {
        width: 100%;
      }
    </style>

    Card.vue

    <template>
        <div class="category">
            <h2> {{ title }}</h2>
            <slot></slot>
        </div>
    </template>
    
    <script>
        export default {
            name: 'Card',
            props: ['title']
        }
    </script>
    
    <style scoped>
        .category {
            background-color: skyblue;
            border-radius: 10px;
            box-shadow: 0 0 10px;
            padding: 10px;
            width: 200px;
            height: 300px;
        }
    </style>

    效果:

    Vue2 基础详解

    />

    需要注意的是,很多时候可能需要插槽有一个默认内容,那么将默认内容放在插槽内即可。

    <template>
        <div class="category">
            <h2> {{ title }}</h2>
            <slot>默认展示的内容</slot>
        </div>
    </template>
    
    <script>
        export default {
            name: 'HelloWorld',
            props: ['title'],
            data () {
                return {
                }
            }
        }
    </script>
    
    <style scoped>
        .category {
            background-color: skyblue;
            border-radius: 10px;
            box-shadow: 0 0 10px;
            padding: 10px;
            width: 200px;
            height: 300px;
        }
    </style>

    3. 具名插槽

    3.1 基本使用

    上面的案例,其实 title 没必要传递,将其定义为一个插槽即可。但是如果有多个插槽,父组件在插入时就不知道哪个对应哪个,所以需要给插槽设置名称。

    HelloWorld.vue

    <template>
      <div id="app">
        <h3>父组件</h3>
        <div class="content">
          <Card>
            <template v-slot:content>
              <ul>
                <li v-for="item in gameList" :key="item.id">{{ item.name }}</li>
              </ul>
            </template>
            <template v-slot:title>
              <h2>游戏列表</h2>
            </template>
          </Card>
          <Card>
            <template v-slot:title>
              <h2>图片展示</h2>
            </template>
            <template v-slot:content>
              <img :src="https://www.amjun.com/picUrl">
            </template>
          </Card>
          <Card>
            <template v-slot:title>
              <h2>消息通知</h2>
            </template>
            <template v-slot:content>
              {{ msg }}
            </template>
          </Card>
        </div>
      </div>
    </template>
    
    <script>
    import Card from './Card.vue';
    
    export default {
      name: 'HelloWorld',
      components: {
        Card
      },
      data () {
        return {
          gameList: [
            { id: 1, name: "王者荣耀"},
            { id: 2, name: "原神"},
            { id: 3, name: "英雄联盟"}
          ],
          picUrl: "https://fastly.picsum.photos/id/77/960/540.jpg?hmac=idkrsBSL_IbzHXXXS3HYS-ZmT3_P4cq0hWPynF1llk8",
          msg: "明天放假!"
        }
      }
    }
    </script>
    
    <style scoped>
      #app {
        background-color: #ccc;
        padding: 20px;
      }
    
      .content {
        display: flex;
        justify-content: space-evenly;
      }
    
      img, video {
        width: 100%;
      }
    </style>

    Card.vue

    <template>
        <div class="category">
            <slot name="title"></slot>
            <slot name="content"></slot>
        </div>
    </template>
    
    <script>
        export default {
            name: 'Card'
        }
    </script>
    
    <style scoped>
        .category {
            background-color: skyblue;
            border-radius: 10px;
            box-shadow: 0 0 10px;
            padding: 10px;
            width: 200px;
            height: 300px;
        }
    </style>

    其中游戏列表故意将标题放在下面,是为了表示具名插槽与位置无关,实现的效果一样。

    Vue2 基础详解

    />

    3.2 动态插槽名

    动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:

    <base-layout>
      <template v-slot:[dynamicSlotName]>
        ...
      </template>
    </base-layout>

    3.3 具名插槽的缩写

    2.6.0 新增

    v-onv-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:title 可以被重写为 #title

    <Card>
        <template #content>
            <ul>
            <li v-for="item in gameList" :key="item.id">{{ item.name }}</li>
            </ul>
        </template>
        <template #title>
            <h2>游戏列表</h2>
        </template>
    </Card>

    4. 作用域插槽

    作用域插槽主要是用于数据在子组件,但是父组件需要使用这个数据的情况。需要在 slot 组件中将数据传递给插槽,然后在父组件通过 v-slot 指令拿到数据。

    HelloWorld.vue

    <template>
      <div id="app">
        <h3>父组件</h3>
        <div class="content">
          <Card>
            <template v-slot="params">
              <ul>
                <li v-for="item in params.gameList" :key="item.id">{{ item.name }}</li>
              </ul>
            </template>
          </Card>
          <Card>
            <template v-slot="params">
              <ol>
                <li v-for="item in params.gameList" :key="item.id">{{ item.name }}</li>
              </ol>
            </template>
          </Card>
          <Card>
            <template v-slot="params">
              <h3 v-for="item in params.gameList" :key="item.id">{{ item.name }}</h3>
            </template>
          </Card>
        </div>
      </div>
    </template>
    
    <script>
    import Card from './Card.vue';
    
    export default {
      name: 'HelloWorld',
      components: {
        Card
      }
    }
    </script>
    
    <style scoped>
      #app {
        background-color: #ccc;
        padding: 20px;
      }
    
      .content {
        display: flex;
        justify-content: space-evenly;
      }
    </style>

    Card.vue

    <template>
        <div class="category">
            <h2>游戏列表</h2>
            <slot :gameList="gameList"></slot>
        </div>
    </template>
    
    <script>
        export default {
            name: 'Card',
            props: ['title'],
            data () {
                return {
                    gameList: [
                        { id: 1, name: "王者荣耀"},
                        { id: 2, name: "原神"},
                        { id: 3, name: "英雄联盟"}
                    ],
                }
            }
        }
    </script>
    
    <style scoped>
        .category {
            background-color: skyblue;
            border-radius: 10px;
            box-shadow: 0 0 10px;
            padding: 10px;
            width: 200px;
            height: 300px;
        }
    </style>

    注意:

    • 当只有默认插槽时,可以将 v-slot 放在子组件上。(上面第二种情况)
    • 当只有默认插槽时,可以忽略插槽名称。上面的 v-slot="params"v-slot:default="params" 的缩写。

    注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。

    效果:

    Vue2 基础详解

    />

    作用域插槽还可以进行结构,具体可参考 解构插槽 Prop

    还有被废弃的 slotslot-scope 属性,参考 废弃了的语法

    提醒:本文发布于125天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • Ubuntu 优化 dns 解析


    共计 830 个字符,预计需要花费 3 分钟才能阅读完成。

    使用的 Ubuntu 系统之前尝试过修改 /etc/resolv.conf,发现修改会被重置,只知道本机启动了一个 dns 的解析服务 systemd-resolved。(今天才知道原来是因为这个文件是一个软连接)

    ls -alh /etc | grep resolv.conf     
    
    lrwxrwxrwx   1 root root     39  2月 27 14:19 resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

    然后最近使用出现了 ping 很慢的问题,但是却没有丢包,怀疑可能是自带的 systemd-resolved 的问题,于是准备关掉这个程序。

    关闭程序:

    sudo systemctl disable --now systemd-resolved

    设置 NetworkManager 将使用系统默认的 DNS,编辑 /etc/NetworkManager/NetworkManager.conf:

    # 不要删除原来的,在 main 下面新增一行
    [main]
    dns=default

    取消软连接:

    sudo unlink /etc/resolv.conf

    创建resolv.conf:

    sudo touch /etc/resolv.conf 

    如果使用 /etc/netplan/01-network-manager-all.yaml 文件设置了网络,那么在网卡下定义 dns 即可。

    network:
      version: 2
      renderer: NetworkManager
      wifis:
        wlo1:   # 配置的网卡的名称
          access-points: # 无线接入点
            "xxxx": # 无线网 ssid
              password: "xxxx"
          addresses: [172.20.3.3/24]   # 配置的静态ip地址和掩码
          dhcp4: false   # 关闭dhcp4
          optional: true
          routes:
          - to: "default"
            via: "172.20.3.254"
          nameservers:
            addresses: [114.114.114.114, 8.8.8.8]

    提醒:本文发布于124天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • Docker 本地 latest 镜像如何找到 dockerhub 对应版本


    共计 968 个字符,预计需要花费 3 分钟才能阅读完成。

    使用 docker 有时候为了方便拉下来的镜像是 latest 版本,但是迁移的时候,可能镜像更新了。这样的话,拉下来的镜像就和原来的不一致,如果启动报错了,就非常的麻烦。所以为了避免这种情况发生,最好使用指定版本。

    万一真的出现了版本不一致不能启动的情况,首先就需要找到之前 latest 所对应的版本。这里以我这里的 linuxserver/freshrss 镜像为例:

    docker inspect linuxserver/freshrss:latest

    此时结果如下:

    [
        {
            "Id": "sha256:7b384ece68d958ef0688ec7afb74bbc66cfbde2ffbb5a0bde59320eb040238b6",
            "RepoTags": [
                "linuxserver/freshrss:latest"
            ],
            "RepoDigests": [
                "linuxserver/freshrss@sha256:807e9bf3c9a887108375125a0b58a4251282ee40e331475e623b9504a6dbab1e"
            ]
        }
    ]

    比较重要的是 RepoDigests 中的结果 807e9bf3c9a887108375125a0b58a4251282ee40e331475e623b9504a6dbab1e

    然后可以通过浏览器访问如下地址:

    # 不同的镜像,替换 linuxserver/freshrss 部分即可
    https://registry.hub.docker.com/v2/repositories/linuxserver/freshrss/tags?page=1&page_size=1000

    这样可以查询 linuxserver/freshrss 所有的 tag。(这里的分页数据设置大一点,方便查询到所有的标签)

    此时将访问得到的结果使用浏览器插件 JSON-handle 或者其他 json 处理工具打开,再 ctrl + f 查询上面查到 hash 值。

    需要注意的是,也有可能找不到对应的标签,这种情况可能是所有者将这个标签删除了。

    Docker 本地 latest 镜像如何找到 dockerhub 对应版本

    />

    这里索引是从 0 开始的,那么这条记录索引为 33,得到这个标签在 dockerhub 的位置就是 34。并且,dockerhub 基本都是 25 个镜像一页,那么直接找到第 2 页的第 9 个镜像即可。

    Docker 本地 latest 镜像如何找到 dockerhub 对应版本

    />

    如果 hash 值一致说明就找对了,如果不一样,可能是数错了。

    提醒:本文发布于123天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • Vue-router 使用教程


    共计 6414 个字符,预计需要花费 17 分钟才能阅读完成。

    1. 简介

    vue-router 是官方提供的路由插件。Vue 中的路由其实就是路径和组件之间的对应关系,因为 vue 是单页应用类网站,所以创建的网站都在一个页面中。当需要展示不同的内容时,就需要通过修改浏览器的访问路径,来达到根据路径展示不同组件的目的。

    官方文档:https://router.vuejs.org/zh/

    可以使用 <router-link> 组件进行导航,使用 <router-view> 做为路由出口,即点击导航所对应的组件。

    2. 简单使用

    vue2 中使用 vue-router 分为以下几个步骤:

    • 安装 vue-router
    • 引入 vue-router
    • 注册 vue-router 插件
    • 创建 VueRouter 实例
    • VueRouter 注入 Vue 实例

    其中第一步当然是在控制台完成。

    npm install vue-router

    接下来要创建 VueRouter,一般会在 src目录下新建一个 router/index.js 文件。

    // 引入 vue-router
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '@/components/Home.vue';
    import About from '@/components/About.vue';
    
    // 注册 vue-router 插件。
    // 告诉 Vue.js 使用 VueRouter 插件,所有插件使用之前都需要进行注册
    Vue.use(VueRouter)
    
    // 创建 VueRouter 实例
    export default new VueRouter({
        routes: [{
            path: '/',
            name: 'home',
            component: Home
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    main.js 中引入 VueRouter,并注入。

    import router from './router'
    
    new Vue({
        el: '#app',
        components: { App },
        template: '<App/>',
        router
    })

    在组件中这样使用即可。

    <template>
      <div id="app">
        <h1>Hello App!</h1>
        <div class="nav">
          <router-link to="/">Home</router-link>
          <router-link to="/about">About</router-link>
        </div>
        <div class="content">
          <router-view></router-view>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: 'HelloWorld',
      }
    </script>
    
    <style scoped>
      .content {
        background-color: skyblue;
      }
    </style>

    3. 嵌套路由

    一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构。

    其中 routes 定义如下:

    const router = new VueRouter({
        routes: [{
            path: '/home',
            name: 'home',
            component: Home,
            children: [
                { path: 'foo', component: Foo },
                { path: 'bar', component: Bar }
            ]
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    可以看见 FooBar 组件都在 /home 路由下,他们的完整路由为 /home/foo/home/bar。所以,此时 Home 应该包含 FooBar 组件。

    Home.vue 内容如下:

    <template>
        <div>
            <h2>我是Home组件</h2>
            <router-link to="/home/foo">Foo</router-link>
            <router-link to="/home/bar">Bar</router-link>
            <router-view></router-view>
        </div>
    </template>
    
    <script>
        export default {
            name: 'Home'
        }
    </script>

    HelloWorld.vue

    <template>
      <div id="app">
        <h1>我是HelloWorld组件</h1>
        <div class="nav">
          <router-link to="/home">Home</router-link>
          <router-link to="/about">About</router-link>
        </div>
        <div class="content">
          <router-view></router-view>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: 'HelloWorld'
      }
    </script>
    
    <style scoped>
      .content {
        background-color: skyblue;
      }
    </style>

    效果:

    Vue-router 使用教程

    />

    4. 命名路由

    定义路由时,可以看见不仅定义了路径,同时还定义了名称,所以导航也可以指定为路由的名称。

    使用方式如下:

    <router-link to="/home">Home</router-link>
    <!-- 等价于 -->
    <router-link :to="{ path: '/home' }">Home</router-link>
    <!-- 如果 /home 对应的名称为 home -->
    <router-link :to="{ name: 'home' }">Home</router-link>

    5. 路由传参

    5.1 动态路由参数

    使用动态路由参数,可以在路由路径中包含参数,这些参数可以在路由组件中通过 $route.params来获取。

    路由定义:

    const router = new VueRouter({
        routes: [{
            path: '/home',
            name: 'home',
            component: Home
        }, {
            path: '/about/:id',
            name: 'about',
            component: About
        }]
    });

    路由链接:

    <router-link to="/about/123">About</router-link>

    About 组件中,可以通过如下方式获取参数:

    let id = this.$route.params.id

    5.2 Props传参

    可以通过路由配置中的 props 选项,将路由组件需要的参数直接作为 props 传递给组件。这种方式需要将 $route 对象的内容直接传递给组件,可以在组件中像普通 props 一样访问这些参数。

    路由定义:

    const router = new VueRouter({
        routes: [{
            path: '/home',
            name: 'home',
            component: Home
        }, {
            path: '/about/:id',
            name: 'about',
            props: true
            component: About
        }]
    });

    路由链接:

    <router-link to="/about/123">About</router-link>

    About 组件中,可以通过如下方式获取参数:

    props: [ 'id'],

    5.3 查询参数

    通过查询参数传递数据,参数会出现在URL中的 ? 后面,并且可以通过 $route.query 来获取。

    路由定义:

    const router = new VueRouter({
        routes: [{
            path: '/home',
            name: 'home',
            component: Home
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    路由链接:

    <router-link :to="{ path: '/about', query: { id: 123 }}">About</router-link>

    About 组件中,可以通过如下方式获取参数:

    let id = this.$route.query.id

    5.4 通过导航钩子传参

    6. 重定向和别名

    6.1 重定向

    例如增加一个 / 的路由,访问该路径默认会跳转到 home 路由。

    const router = new VueRouter({
        routes: [{
            path: '/',
            redirect: { name: 'home' },
            //redirect: { path: '/home' }
        },{
            path: '/home',
            name: 'home',
            component: Home
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    甚至是一个方法,动态返回重定向目标:

    const router = new VueRouter({
        routes: [{
            path: '/test/:id',
            redirect:  to => {
                // 访问 /test/100 => /home?id=100
                return { path: '/home', query: { id: to.params.id } }
            }
        },{
            path: '/home',
            name: 'home',
            component: Home,
            children: [
                { path: 'foo', component: Foo },
                { path: 'bar', component: Bar }
            ]
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由。如果一个路由记录有 childrenredirect 属性,它也应该有 component 属性。

    6.2 别名

    上述例子中,重定向 / 路由会导致浏览器 url 发生改变 /home。但是可以使用重命名,访问 / 时,浏览器 url 不发生改变,但页面内容仍然是和 /home 路由一样的内容。

    const router = new VueRouter({
        routes: [{
            path: '/home',
            name: 'home',
            alias: "/",
            component: Home
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    通过别名,可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。甚至可以将两者结合起来,用一个数组提供多个别名。

    7. 历史记录模式

    历史记录模式分为两种:

    • hash 模式。特定是有#,SEO 效果差,适用于后台管理系统。
    • history 模式。和传统url类似,适合需要搜索引擎收录的网站。

    之前创建的 VueRouter 实例,默认都是 hash 模式。所以都是带 # 的。

    如果需要修改为 history 模式,指定 mode 即可。

    const router = new VueRouter({
        //mode: 'hash',
        mode: 'history',
        routes: [{
            path: '/home',
            name: 'home',
            alias: "/",
            component: Home
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    8. 编程式导航

    除了使用 创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编写代码来实现。并且需要注意的是,开发中更多的是使用的编程式导航。

    在组件中可以使用 this 对象,拿到 router 实例,然后调用 router 的 api 进行路由的修改。(这里修改的其实就是浏览器的地址)

    1. 使用 $router.push(location):导航到一个新的 URL,可以是一个字符串路径或一个描述地址的对象。例如:
    // 字符串路径
    this.$router.push('/home')
    
    // 对象
    this.$router.push({ path: '/home' })
    
    // 带查询参数
    this.$router.push({ path: '/home', query: { key: 'value' } })
    1. 使用 $router.replace(location):类似 $router.push(),但是不会在导航历史记录中留下记录,所以点击后退按钮无法返回上一个页面。用法与 $router.push() 相同。

    2. 使用 $router.go(n):在导航历史记录中向前或向后移动多少步。例如:

    // 后退一步
    this.$router.go(-1)
    
    // 前进一步
    this.$router.go(1)
    1. 使用 $router.back()$router.forward():分别用于后退和前进。这两种方式相当于 $router.go(-1)$router.go(1)。例如:
    // 后退
    this.$router.back()
    
    // 前进
    this.$router.forward()

    这些方法可以需求选择使用,比如根据用户的操作进行页面导航、处理表单提交后的页面跳转等。

    9. 导航守卫

    导航守卫是 Vue Router 提供的一种机制,用于在路由导航过程中进行拦截和控制。它允许你在路由导航发生前、发生时、发生后等不同的阶段执行一些自定义逻辑。Vue Router 提供了全局导航守卫、路由独享守卫和组件内的守卫。

    9.1 全局导航守卫

    全局导航守卫包括 beforeEachbeforeResolveafterEach,它们分别在路由导航之前、导航被确认之前、导航成功完成之后触发。这些守卫可以在 Vue Router 实例上直接设置:

    const router = new VueRouter({ ... });
    
    router.beforeEach((to, from, next) => {
        console.log(" 在路由导航之前执行的逻辑");
    });
    
    router.beforeResolve((to, from, next) => {
        console.log("在导航被确认之前执行的逻辑");
    });
    
    router.afterEach((to, from) => {
        console.log("在导航成功完成之后执行的逻辑");
    });

    以上 beforeEachbeforeResolve 均可以使用 next(false) 来终端导航,并且如果导航没问题,必须使用 next() 放行。

    9.2 路由独享守卫

    路由独享守卫是针对某个特定路由设置的守卫,通过在路由配置中使用 beforeEnter 字段来定义:

    const router = new VueRouter({
        //mode: 'hash',
        mode: 'history',
        routes: [{
            path: '/home',
            name: 'home',
            component: Home,
            beforeEnter: (to, from, next) => {
                // 在进入 '/foo' 路由之前执行的逻辑
            }
        }, {
            path: '/about',
            name: 'about',
            component: About
        }]
    });

    9.3 组件内的守卫

    组件内的守卫包括 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave,它们分别在组件被创建、更新和销毁时触发。

    export default {
        name: 'Home',
        beforeRouteEnter(to, from, next) {
            // 注意:在这里无法通过 this 访问组件实例,因为组件还未被创建
            console.log("在进入该组件路由之前执行的逻辑");
            next();
        },
        beforeRouteUpdate(to, from, next) {
            // 可以访问组件实例
            console.log("在当前路由改变,但是该组件被复用时执行的逻辑");
            next();
        },
        beforeRouteLeave(to, from, next) {
            // 在离开该组件的路由时执行的逻辑
            console.log("在离开该组件的路由时执行的逻辑");
            next();
        }
    }

    提醒:本文发布于123天前,文中所关联的信息可能已发生改变,请知悉!

    Tips:清朝云网络工作室

  • 08月19日,星期一, 每天60秒读懂全世界!

    百度热搜新闻

    新闻来源:百度热搜榜

    1. 樊振东谈畸形饭圈文化:输赢都不行 近日,樊振东在接受央视专访时谈畸形饭圈文化,坦言一度因饭圈文化感到困扰。他表示,有时候会觉得输球不行,赢球好像也没那么行。

    2. 上海一小哥开50万黄牌摩托送外卖?

    3. “科技范儿”点燃文旅热 这个暑期,“科技范儿”为传统文旅带来了新的打开方式。科技为文旅融合注入新动能,也让游客们从另一个视角感受中国传统文化之美。

    4. 江西一私人影院进行卖淫嫖娼活动

    5. 新一波猴痘疫情青少年死亡比例上升

    6. 西瓜价格大涨

    7. 越共中央总书记苏林抵达北京 应中共中央总书记、国家主席习近平邀请,越共中央总书记、国家主席苏林于18日至20日来华国事访问。18日傍晚,苏林抵达北京。

    8. 湖南博物院辟谣展品被盗 近日,湖南博物院两汉罗马时期女性文物展中,展品辛追夫人曲裾式素纱单衣引起网友疑惑。湖南博物院辟谣:曲裾式素纱单衣从未被盗。

    9. 警方提醒警惕“高收低租”租房骗局

    10. 满载演出人员巴士发生车祸 2人身亡 8月18日,网传山西孝义一满载演出人员的巴士发生车祸。对此,当地回应:事发在郝家湾村,两名女子现场身亡,两人重伤送医。

    —- 百度热搜新闻 End —-

    知乎新闻

    新闻来源:知乎日榜

    标题: 小事 ·「求复活卷轴一张。」
    链接: https://daily.zhihu.com/story/9774682
    ———————-
    标题: 既然神经元的结构非常简单,那么为什么不制造几百亿个模拟神经元来模拟人脑?
    链接: https://daily.zhihu.com/story/9774692
    ———————-
    标题: 傅里叶变换如何应用于实际的物理信号?
    链接: https://daily.zhihu.com/story/9774699
    ———————-
    标题: 蚊子的天敌是什么?
    链接: https://daily.zhihu.com/story/9774708
    ———————-

    —- 知乎新闻 End —-

    IT之家新闻

    新闻来源:ITHome之家科技新闻

    标题: 《黑神话:悟空》开启预下载,8 月 20 日上午 10 点解锁
    发布时间: 2024-08-18T10:14:48.943
    新闻简介: 《黑神话:悟空》现已可在 PS5 / STEAM / WEGAME 平台提前下载,游戏将于 8 月 20 日上午 10 点解锁。
    ———————-
    标题: 福建平潭问界 M7 沙滩陷车后续:如果保险拒赔,用户中心会给予维修优惠
    发布时间: 2024-08-18T16:40:58.83
    新闻简介: 抖音平台有多个视频显示,8 月 15 日,一辆未上牌的问界新 M7 被开到了福建平潭海滩上游玩。海水涨潮后车主想要开出,结果却越陷越深,新车直接变成泡海车。
    ———————-
    标题: 领克车主发布联合声明:车机一年更新一次,希望升级至 Flyme Auto
    发布时间: 2024-08-18T17:57:42.9
    新闻简介: 声明称,领克汽车提供了搭载 8155 芯片的 OS N 车机系统。OS N 推出两年之久,自上次更新距今近一年的时间,经长达一年之久的维护及优化无实质性改变,操作界面卡顿不跟手,导航适配等问题频发。
    ———————-
    标题: 概念设计师遭苹果律师“找上门”:设计过于真实,需要调整
    发布时间: 2024-08-18T12:49:36.627
    新闻简介: 概念设计师 Antonio De Rosa 本周收到了一封来自苹果公司律师的邮件,称其部分设计作品过于真实,可能引起消费者混淆。尽管苹果方面表示欣赏 De Rosa 的创意和热情,但希望就某些设计进行调整。
    ———————-
    标题: 华为鸿蒙 HarmonyOS NEXT 系统首款 MOBA 游戏《曙光英雄》上线,支持多账号体系登录
    发布时间: 2024-08-18T15:49:10.887
    新闻简介: 《曙光英雄》遵循 HarmonyOS NEXT 系统规范,在登录页面支持华为账号登录和 JJ 官方账号登录,用户可自行选择登录方式。
    ———————-
    标题: 国家安全部:境外间谍利用测风塔非法采集敏感数据并私自传输至境外
    发布时间: 2024-08-18T09:49:22.623
    新闻简介: 测风塔是一种用于测量风速、风向等气象数据的高耸塔架结构,在塔体不同位置安装有风速计、风向标以及温度计、气压计等监测设备,能够为气象观测和大气环境监测提供参考数据。
    ———————-
    标题: 联想拯救者 Y9000P《黑神话:悟空》联名定制版笔记本外观公布,8 月 20 日开售
    发布时间: 2024-08-18T18:48:27.653
    新闻简介: 联想拯救者今日公布了 Y9000P《黑神话:悟空》联名定制版部分外观信息,8 月 20 日 10 点开售,倒计时发售还有两天。
    ———————-
    标题: 华为推出 5 本软件工程教材:分别基于鲲鹏、开源鸿蒙 OpenHarmony、openEuler 等
    发布时间: 2024-08-18T17:41:45.103
    新闻简介: 为解决我国软件工程专业核心教材缺乏基于自主创新的软件系统的教材体系问题,由示范性软件学院联盟、高等教育出版社、华为技术有限公司和高校老师四方协同,携手打造 10 本软件工程系列教材。
    ———————-
    标题: 女子花费近三万购买 Vertu 纬图手机,因“太卡”想退货被拒
    发布时间: 2024-08-18T22:44:03.483
    新闻简介: 据“1818 黄金眼”报道,马女士在杭州万象城 Vertu 纬图专柜花费近 3 万元购买了一款手机。拿回家以后发现手机使用起来不是特别丝滑,打游戏会“很卡”。
    ———————-
    标题: 哪吒张勇:寻找最长里程电动汽车车主,免费换一台哪吒 S 猎装车
    发布时间: 2024-08-18T20:02:55.437
    新闻简介: 继今年 6 月向来自江西宜春等地两名“全网最长里程哪吒 U 车主”免费更换新款哪吒 X 汽车后,哪吒汽车 CEO 张勇今天又在微博表示将在全网寻找一台里程最长的电动轿车,为车主更换一辆哪吒 S 猎装车。作为此次活动的参考车型,哪吒 S 猎装车目前已经开启预售,提供增程和纯电两种动力选择,系列车型采用浩智滑板底盘技术,长宽高分别为 4980x1980x1480 毫米,轴距为 2980 毫米,其中纯电版的预售价为 16.69-21.99 万元,增程版的预售价区间为 17.59-20.99 万元。
    ———————-
    标题: 京东自营 7.5 折 1501 元:Redmi K70E 手机直降 498 元
    发布时间: 2024-08-18T14:23:02.123
    新闻简介: Redmi K70E 手机发布于去年 11 月 29 日,搭载联发科天玑 8300-Ultra 处理器,运行澎湃 OS,12GB + 256GB 发售价 1999 元。
    ———————-
    标题: 小米 MIX Flip 小折叠手机获推澎湃 HyperOS 1.0.11.0 更新:外屏支持米家、开心消消乐等应用
    发布时间: 2024-08-18T07:06:56.933
    新闻简介: 此次更新后,小米 MIX Flip 新增外屏智能悬窗-焦点通知卡片、支持使用米家 / 开心消消乐应用、支持点击外屏小部件开启应用等功能。
    ———————-

    —- IT之家新闻 End —-

  • 08月19日,星期一, 每天60秒读懂全世界!

    百度热搜新闻

    新闻来源:百度热搜榜

    1. 樊振东谈畸形饭圈文化:输赢都不行 近日,樊振东在接受央视专访时谈畸形饭圈文化,坦言一度因饭圈文化感到困扰。他表示,有时候会觉得输球不行,赢球好像也没那么行。

    2. 上海一小哥开50万黄牌摩托送外卖?

    3. “科技范儿”点燃文旅热 这个暑期,“科技范儿”为传统文旅带来了新的打开方式。科技为文旅融合注入新动能,也让游客们从另一个视角感受中国传统文化之美。

    4. 江西一私人影院进行卖淫嫖娼活动

    5. 新一波猴痘疫情青少年死亡比例上升

    6. 西瓜价格大涨

    7. 越共中央总书记苏林抵达北京 应中共中央总书记、国家主席习近平邀请,越共中央总书记、国家主席苏林于18日至20日来华国事访问。18日傍晚,苏林抵达北京。

    8. 湖南博物院辟谣展品被盗 近日,湖南博物院两汉罗马时期女性文物展中,展品辛追夫人曲裾式素纱单衣引起网友疑惑。湖南博物院辟谣:曲裾式素纱单衣从未被盗。

    9. 警方提醒警惕“高收低租”租房骗局

    10. 满载演出人员巴士发生车祸 2人身亡 8月18日,网传山西孝义一满载演出人员的巴士发生车祸。对此,当地回应:事发在郝家湾村,两名女子现场身亡,两人重伤送医。

    —- 百度热搜新闻 End —-

    知乎新闻

    新闻来源:知乎日榜

    标题: 小事 ·「求复活卷轴一张。」
    链接: https://daily.zhihu.com/story/9774682
    ———————-
    标题: 既然神经元的结构非常简单,那么为什么不制造几百亿个模拟神经元来模拟人脑?
    链接: https://daily.zhihu.com/story/9774692
    ———————-
    标题: 傅里叶变换如何应用于实际的物理信号?
    链接: https://daily.zhihu.com/story/9774699
    ———————-
    标题: 蚊子的天敌是什么?
    链接: https://daily.zhihu.com/story/9774708
    ———————-

    —- 知乎新闻 End —-

    IT之家新闻

    新闻来源:ITHome之家科技新闻

    标题: 《黑神话:悟空》开启预下载,8 月 20 日上午 10 点解锁
    发布时间: 2024-08-18T10:14:48.943
    新闻简介: 《黑神话:悟空》现已可在 PS5 / STEAM / WEGAME 平台提前下载,游戏将于 8 月 20 日上午 10 点解锁。
    ———————-
    标题: 福建平潭问界 M7 沙滩陷车后续:如果保险拒赔,用户中心会给予维修优惠
    发布时间: 2024-08-18T16:40:58.83
    新闻简介: 抖音平台有多个视频显示,8 月 15 日,一辆未上牌的问界新 M7 被开到了福建平潭海滩上游玩。海水涨潮后车主想要开出,结果却越陷越深,新车直接变成泡海车。
    ———————-
    标题: 领克车主发布联合声明:车机一年更新一次,希望升级至 Flyme Auto
    发布时间: 2024-08-18T17:57:42.9
    新闻简介: 声明称,领克汽车提供了搭载 8155 芯片的 OS N 车机系统。OS N 推出两年之久,自上次更新距今近一年的时间,经长达一年之久的维护及优化无实质性改变,操作界面卡顿不跟手,导航适配等问题频发。
    ———————-
    标题: 概念设计师遭苹果律师“找上门”:设计过于真实,需要调整
    发布时间: 2024-08-18T12:49:36.627
    新闻简介: 概念设计师 Antonio De Rosa 本周收到了一封来自苹果公司律师的邮件,称其部分设计作品过于真实,可能引起消费者混淆。尽管苹果方面表示欣赏 De Rosa 的创意和热情,但希望就某些设计进行调整。
    ———————-
    标题: 华为鸿蒙 HarmonyOS NEXT 系统首款 MOBA 游戏《曙光英雄》上线,支持多账号体系登录
    发布时间: 2024-08-18T15:49:10.887
    新闻简介: 《曙光英雄》遵循 HarmonyOS NEXT 系统规范,在登录页面支持华为账号登录和 JJ 官方账号登录,用户可自行选择登录方式。
    ———————-
    标题: 国家安全部:境外间谍利用测风塔非法采集敏感数据并私自传输至境外
    发布时间: 2024-08-18T09:49:22.623
    新闻简介: 测风塔是一种用于测量风速、风向等气象数据的高耸塔架结构,在塔体不同位置安装有风速计、风向标以及温度计、气压计等监测设备,能够为气象观测和大气环境监测提供参考数据。
    ———————-
    标题: 联想拯救者 Y9000P《黑神话:悟空》联名定制版笔记本外观公布,8 月 20 日开售
    发布时间: 2024-08-18T18:48:27.653
    新闻简介: 联想拯救者今日公布了 Y9000P《黑神话:悟空》联名定制版部分外观信息,8 月 20 日 10 点开售,倒计时发售还有两天。
    ———————-
    标题: 华为推出 5 本软件工程教材:分别基于鲲鹏、开源鸿蒙 OpenHarmony、openEuler 等
    发布时间: 2024-08-18T17:41:45.103
    新闻简介: 为解决我国软件工程专业核心教材缺乏基于自主创新的软件系统的教材体系问题,由示范性软件学院联盟、高等教育出版社、华为技术有限公司和高校老师四方协同,携手打造 10 本软件工程系列教材。
    ———————-
    标题: 女子花费近三万购买 Vertu 纬图手机,因“太卡”想退货被拒
    发布时间: 2024-08-18T22:44:03.483
    新闻简介: 据“1818 黄金眼”报道,马女士在杭州万象城 Vertu 纬图专柜花费近 3 万元购买了一款手机。拿回家以后发现手机使用起来不是特别丝滑,打游戏会“很卡”。
    ———————-
    标题: 哪吒张勇:寻找最长里程电动汽车车主,免费换一台哪吒 S 猎装车
    发布时间: 2024-08-18T20:02:55.437
    新闻简介: 继今年 6 月向来自江西宜春等地两名“全网最长里程哪吒 U 车主”免费更换新款哪吒 X 汽车后,哪吒汽车 CEO 张勇今天又在微博表示将在全网寻找一台里程最长的电动轿车,为车主更换一辆哪吒 S 猎装车。作为此次活动的参考车型,哪吒 S 猎装车目前已经开启预售,提供增程和纯电两种动力选择,系列车型采用浩智滑板底盘技术,长宽高分别为 4980x1980x1480 毫米,轴距为 2980 毫米,其中纯电版的预售价为 16.69-21.99 万元,增程版的预售价区间为 17.59-20.99 万元。
    ———————-
    标题: 京东自营 7.5 折 1501 元:Redmi K70E 手机直降 498 元
    发布时间: 2024-08-18T14:23:02.123
    新闻简介: Redmi K70E 手机发布于去年 11 月 29 日,搭载联发科天玑 8300-Ultra 处理器,运行澎湃 OS,12GB + 256GB 发售价 1999 元。
    ———————-
    标题: 小米 MIX Flip 小折叠手机获推澎湃 HyperOS 1.0.11.0 更新:外屏支持米家、开心消消乐等应用
    发布时间: 2024-08-18T07:06:56.933
    新闻简介: 此次更新后,小米 MIX Flip 新增外屏智能悬窗-焦点通知卡片、支持使用米家 / 开心消消乐应用、支持点击外屏小部件开启应用等功能。
    ———————-

    —- IT之家新闻 End —-