前端及开发文章及欣赏

web前端客户端基础学习

前端达人

!DOCTYPE html

功能是:告知浏览以哪个版本来解析HTML的元素

注:必须放在第一行

DOCTYPE 文档声明定义

document 文档

type 类型

charset

utf-8



字符编码集



告诉浏览器用哪一个版本来解析文本(包括标点符号,文字)



viewport

视口(可视窗口)



title

标签页标题



HTML元素的组成部分

元素:起始标记、内容和结束标记



某些元素的起始标记内有属性



属性:属性名和属性值



例如:



<a href="/classroom/17">班级</a>

1

起始标记:



结束标记:



内容:班级



属性:href="/classroom/17"



属性名:href



属性值:"/classroom/17"



空元素

类似img元素



<img src="" alt="">

1

没有元素内容和结束标记,称之为:空元素、自闭合元素



乱序铭文

功能:批量生成文本

书写格式:lorem数量(单词个数)

p标签

p标签不能包含(嵌套)p标签,也不能包含标题、div,语义化标签



解析

将我们写出的代码,转换成计算机可以看懂的语言



渲染

再将解析好的语言,通过浏览器渲染展示出来,给用户看。



HTML

是用于定义文档的结构内容(标题、图片等)

HTML英文全称:Hyper Text Markup Language

中文全称:超文本标记语言

CSS

用于定义HTML文档的样式(外观)

CSS英文全称:Cascading Style Sheets

中文全称:层叠样式表

语义化结构

header 页面的头部或者某个区域的头部,一个页面可以使用多个header元素

nav 表示导航栏

article 代表文档、页面或其他可独立部分,常用于定义一篇日志、一条新闻或用户评论。

aside 用于表示当前页面或文章相关的附属信息,可包含该页面或内容相关的引用、侧边栏、广告、导航条等

section 用于表示一个整体的一部分主题

footer 用于表示页面或者某个区域的脚注,可以包含所有放在页面底部的内容

div与语义化结构的区别

div与语义化结构标签的功能是一样的,但是使用语义化结构标签可以让页面结构更加清晰。



a标签

元素书写格式

<a href="目标">内容</a>

1

href属性

页面地址(路径)



多个页面中相互跳转



锚点



可以在同一个页面之间,相互跳转



先将要跳转的位置加上id属性



<h1 id="title2">标题二</h1>

1

将#+属性名



<a href="#title2">跳转到标题二</a>

1

功能链接



打电话



<a href="tel:12345678910">给我打电话</a>

1

发邮件



<a href="mailto:123456789@163.com">给我发邮件</a>

1

返回顶部

<a href="#">返回顶部</a>

1

a标签的打开方式

书写方式:



<a target="_blank" href="目标"></a>

1

属性 target



属性值



_blank 新页面打开



_self 当前页面打开(默认值)



link外部引用的好处

批量修改

复用

绝对路径和相对路径

绝对路径

从根目录开始写,写到要找文件的位置



当网站部署到服务器后,网站中的所有资源都可以通过一个地址(路径)访问



书写格式:协议://域名/目录



使用场景:



访问站外资源时,只能使用绝对路径



访问站内资源时,若网站已部署到服务器,可以使用绝对路径,并可以省略协议和域名。推荐使用相对路径



相对路径

相对路径是相对于当前资源的位置,只能用于访问站内资源



相对路径的书写格式为:./路径



./ 表示当前资源所在的目录,必须作为相对路径的开始,可省略


…/ 表示返回上一级目录 (…/…/可以返回上两级目录,写几次就可以返回几次


转自:csdn 作者:

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服

HTML基础知识

前端达人

HTML概念和元素(标签)

什么是HTML

HTML(Hyper Text Markup Language),中文译名为超文本标记语言,它包括一系列标签,通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整体。简单来说,就是我们用它所包含的一系列标签来定义网页的布局结构。



什么是HTML标签(元素)

HTML 文档是由 HTML 元素定义的,元素由三部分组成:开始标签、元素内容、结束标签。



HTML 元素以开始标签起始,以结束标签终止,元素的内容是开始标签与结束标签之间的内容。在VSCode中,使用标签只需要输入需要使用的标签名,再按Tab键,编辑器会自动补齐开始标签和结束标签的样式。



温馨提示:

1.标签的括号我们用的是尖括号,这也是HTML代码和CSS(层叠样式表)代码的区别。

2.HTML 标签对大小写不敏感,也就是说不管我们用大写还是小写浏览器都能成功识别,但是为了统一标准,最好还是写小写。



元素的层次结构

大多数 HTML 元素可以包含其他 HTML 元素,形成嵌套结构



如图,div元素内部包含一个p元素,形成嵌套。在嵌套结构中,p的上一级元素是div,我们称div是p的父元素,p是div的子元素,他们之间是父子级关系。



若是如图这样body、div、p三个元素嵌套,p的上一级元素是div,div的上一级元素是body,那么div是body的子元素,body是div的父元素,body和div是父子关系。而p和body中间隔了一个div,那么p就是body的后代元素,body是p的祖先元素,他们是祖先和后代的关系。

若是两个元素拥有一个共同的父元素,也就是两个元素的上一级元素是同一个,那么这两个元素互为兄弟元素。



需要注意的是,两个元素之间不能相互嵌套



p的起始标签在div内部,结束标签却在div外部,这样的嵌套结构是错误的,浏览器在解析的时候会自动在p的起始标签后补上结束标签,在结束标签前面补上起始标签。



当我们打开浏览器检查器之后就会发现div和p的层次结构已经发生了改变。



元素的属性

属性是元素的附加信息,比如超链链接的地址就是元素的附加信息,属性一般写在元素的起始标签里。



这是一个a标签,起始标签的href="http://www.baidu.com"就是a标签的属性,点击‘百度’后自动跳转属性里的网址。属性由属性名和属性值两部分组成,‘href’是属性的属性名,后面的网址是属性值,属性值要用引号括起来



空元素(自闭合元素)

空元素没有元素内容和结束标签,只有起始标签。空元素内可以加上属性,例如插入图片的img标签



img标签没有元素内容和结束标签,起始标签内有属性,属性值是图片地址。

一般情况下,图片用空标签,音频视频不适用空标签



HTML注释

注释是对代码功能的描述,一般是写给开发者和维护者看的,浏览器并不会解析注释里的内容。因为在代码编写的过程中,代码繁多杂乱,写上注释能帮助我们快速理解当前代码的功能,给维护提供方便。





VSCode注释的写法:在尖括号内写上 !–和--,中间写上注释的内容,或者选中想要注释的行,按下快捷键CTRL+?。



语义化标签和div

div是无语义标签,就是没有含义的标签。而所谓语义化标签,就是有含义的标签,一看就知道其内部含义。我们平时使用语义化标签和div来划分区域,他们在功能上是没有任何区别的,只是语义化标签能帮助开发者和维护者清晰地理解划分的每个区域都是用来干嘛的。在HTML5之前都是用div来划分区域,就会导致整篇代码全是div,看得人眼花缭乱不易于阅读,语义化标签的出现就能解决这个问题。

在HTML5中新增了几个语义化标签:



header:用于表示页面的头部

nav:表示导航栏

article:表示文章或其他可独立存在的页面

section:表示一个整体的一部分主题

aside:表示跟周围主题相关的附加信息

footer:表示页面或某个区域的注脚


蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服

JS学习笔记

前端达人

JS学习笔记

js和java的异同点

变量声明

函数声明

js中的变量提升和函数提升

为什么有变量提升

总结

js和java的异同点

首先,js的语法和kottlin的语法有些相似。比如var,方法声明用



  function 方法名称 (参数名称...){

  //方法内部逻辑

  }



还有变量类型声明 :



数据类型 : 变量名=值



区别:一:js的数据类型和java类似。只不过js中的数据类型number将java中的int,double,float整合了。

二:js中可以不用声明变量类型。变量不声明数据类型的话,那么他的类型取决于当前的值是什么数据类型。举例:



var num=0;

num-"lyyyyyyyyyyyyyy";

num=[];

num={};



三:js中的类型判断:



判断基本类型,返回一个字符串

1

console.log(typeof '');//string

console.log(typeof []);//object

console.log(typeof {});//object

console.log(typeof 1);//number

console.log(typeof null);//object

console.log(typeof undefined);//undefined

console.log(typeof true);//boolean

console.log(typeof function(){});//function

console.log(typeof /\d/);//object





检查某个对象属于哪个构造函数,返回true/false

1

function A(){};

function B(){};

let a = new A();

console.log(a instanceof A);

console.log(a instanceof B);

console.log([] instanceof Array);//true

console.log({} instanceof Object);//true

console.log(/\d/ instanceof RegExp);//true

console.log(function(){} instanceof Object);//true

console.log(function(){} instanceof Function);//true





变量声明

js的变量声明其实大体上可以分为三种:var声明、let与const声明和函数声明。



函数声明

doSomething();

 

function doSomething() {

    console.log('doSomething');

}

var foodoSomething= 2;



你觉得上面会输出什么?TypeError吗?其实输出的结果是foo。这就引出了我们的问题了,当函数声明与其他声明一起出现的时候,是以谁为准呢?答案就是,函数声明高于一切,毕竟函数是js的第一公民。



那么,下面的例子呢?



doSomething();

 

function doSomething() {

    console.log('1');

}

 

function doSomething() {

    console.log('2');

}



当出现多个函数声明,那怎么办呢?以上代码输出结果为2。

因为有多个函数声明的时候,是由最后面的函数声明来替代前面的。



domeSomething();

 

var domeSomething= function() {

    console.log('domeSomething');

}



var domeSomething = function() {}这种格式我们叫做函数表达式。



它其实也是分为两部分,一部分是var foo,而一部分是foo = function() {},参照例2,我们可以知道,这道题的结果应该是报了TypeError(因为foo声明但未赋值,因此foo是undefined)。



js中的变量提升和函数提升

在js中对变量进行操作后打印值经常会出现undefined的现象。其实原因是因为js中有一个叫做变量提升的功能。举例:

1

var data="lyyyyy";

getData();

function getData(){

//第一次打印

console.log("data值为: ", data);

var data="yyyyyyy";

//第二次打印

console.log("data值为: ", data);

}



打印的值第一个为undefined,而第二个打印的值为yyyyy.



原因:

在执行getData()方法的时候会在函数内部首先将变量的声明提升到第一步。

然后再声明函数内部的函数(如果函数内部有函数的话)。

之后才会按照方法内部的逻辑先后顺序执行代码。前两步只是声明!!!

看到这里应该就已经知道为什么会有上面那样的结果了。



实际的方法内部代码执行顺序应该是这样的:



function getData(){

//一。声明变量

var data;

//二。声明函数(如果函数内部有函数的话)



//三。按照代码的顺序执行

console.log("data值为: ", data);

data="yyyyyyy";

//第二次打印

console.log("data值为: ", data);

}



看到拆分后的代码执行顺序对结果也就不迷茫了。



为什么有变量提升

那么为什么会出现变量提升这个现象呢?



其实js和其他语言一样,都要经历编译和执行阶段。而js在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二步则是在执行阶段执行到该语句的时候才执行。



总结

1.js会将变量的声明提升到js顶部执行,因此对于这种语句:var a = 2;其实上js会将其分为var a;和a = 2;两部分,并且将var a这一步提升到顶部执行。



2.变量提升的本质其实是由于js引擎在编译的时候,就将所有的变量声明了,因此在执行的时候,所有的变量都已经完成声明。

3.当有多个同名变量声明的时候,函数声明会覆盖其他的声明。如果有多个函数声明,则是由最后的一个函数声明覆盖之前所有的声明。


————————————————
版权声明:本文为CSDN博主的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。


蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服


postMessage跨域、跨iframe窗口消息传递

前端达人

文章目录

  1. 作用
  2. 语法
  3. 使用
  4. 兼容性
  5. 应用场景

    说起postMessage 可能平时大家也不遇到,但是如果遇到问题了,又想不起它,这里记录下防止后面忘记它。




  6. 作用

    window.postMessage()方法可以安全地实现Window对象之间的跨域通信。例如,在一个页面和它生成的弹出窗口之间,或者是页面和嵌入其中的iframe之间。



    通常情况下,受浏览器“同源策略”的限制跨域问题一直是个问题,window.postMessage()提供了一个受控的机制来安全地规避这个限制(如果使用得当的话)。


  7. 语法

    一般来说,一个窗口可以获得对另一个窗口的引用(例如,通过targetWindow=window.opener),然后使用targetWindow.postMessage()在其上派发MessageEvent。接收窗口随后可根据需要自行处理此事件,传递给window.postMessage()的参数通过事件对象暴露给接收窗口。



    基本语法:



    targetWindow.postMessage(message, targetOrigin, [transfer]);

    1

    targetWindow

    targetWindow就是接收消息的窗口的引用。 获得该引用的方法包括:



    Window.open

    Window.opener

    HTMLIFrameElement.contentWindow

    Window.parent

    Window.frames +索引值

    message

    要发送到目标窗口的消息。 数据使用结构化克隆算法进行序列化。 这意味着我们可以将各种各样的数据对象安全地传递到目标窗口,而无需自己对其进行序列化。



    targetOrigin

    定目标窗口的来源,必须与消息发送目标相一致,可以是字符串或URI。 表示任何目标窗口都可接收,为安全起见,请一定要明确提定接收方的URI。如果为"*"则都可以接收。



    transfer

    可选属性。是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。


  8. 使用

    postMessage程序



    var receiver = document.getElementById('receiver').contentWindow;

    var btn = document.getElementById('send');

    btn.addEventListener('click', function (e) {

        e.preventDefault();

        var val = document.getElementById('text').value;

        receiver.postMessage("Hello "+val+"!", "http://www.xxx.com");

    }); 



    接收端



    window.addEventListener("message", receiveMessage, false);

    function receiveMessage(event){

      if (event.origin !== "http://www.xxx.com")

        return;

    }



    event对象有三个属性,分别是origin,data和source。event.data表示接收到的消息;event.origin表示postMessage的发送来源,包括协议,域名和端口;event.source表示发送消息的窗口对象的引用; 我们可以用这个引用来建立两个不同来源的窗口之间的双向通信。


  9. 兼容性



    总体兼容性还是很好的!




  10. 应用场景

    跨域通信(包括GET请求和POST请求)

    WebWorker

    vue项目中使用到了iframe并且需要传递参数



    ————————————————

    版权声明:本文为CSDN博主「zy1281539626」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/zy1281539626/article/details/114934551


    蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服


SpringBoot与Web开发

前端达人

SpringBoot与Web开发(超详细)

一、简介

二、SpringBoot对静态资源的映射规则

1、所有 /webjars/ ,都去 classpath:/META-INF/resources/webjars/ 找资源

2、"/
" 访问当前项目的任何资源,都去静态资源的文件夹找映射

3、欢迎页: 静态资源文件夹下的所有index.html页面,被"/"映射

三、模板引擎

1、引入Thymeleaf

2、Thymeleaf的使用

1、导入thymeleaf的名称空间

2、使用thymeleaf语法

3、Thymeleaf的语法规则

四、SpringMVC自动配置

1、Spring MVC auto-configuration

2、扩展SpringMVC

原理

3、全面接管SpringMVC

原理

五、如何修改SpringBoot的默认配置

一、简介

使用SpringBoot的步骤:



1、创建SpringBoot应用,选中我们需要的模块。

2、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来。

3、自己编写业务代码。



自动配置原理:



xxxxAutoConfiguration:帮我们给容器中自动配置组件

xxxxProperties:配置类来封装配置文件的内容

1

2

二、SpringBoot对静态资源的映射规则

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)

public class ResourceProperties implements ResourceLoaderAware {

  //可以设置和静态资源有关的参数,缓存时间等

1

2

3

WebMvcAuotConfiguration:

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

if (!this.resourceProperties.isAddMappings()) {

logger.debug("Default resource handling disabled");

return;

}

Integer cachePeriod = this.resourceProperties.getCachePeriod();

if (!registry.hasMappingForPattern("/webjars/
")) {

customizeResourceHandlerRegistration(

registry.addResourceHandler("/webjars/**")

.addResourceLocations(

"classpath:/META-INF/resources/webjars/")

.setCachePeriod(cachePeriod));

}

String staticPathPattern = this.mvcProperties.getStaticPathPattern();

          //静态资源文件夹映射

if (!registry.hasMappingForPattern(staticPathPattern)) {

customizeResourceHandlerRegistration(

registry.addResourceHandler(staticPathPattern)

.addResourceLocations(

this.resourceProperties.getStaticLocations())

.setCachePeriod(cachePeriod));

}

}



       //配置欢迎页映射

@Bean

public WelcomePageHandlerMapping welcomePageHandlerMapping(

ResourceProperties resourceProperties) {

return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),

this.mvcProperties.getStaticPathPattern());

}



      //配置喜欢的图标

@Configuration

@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)

public static class FaviconConfiguration {



private final ResourceProperties resourceProperties;



public FaviconConfiguration(ResourceProperties resourceProperties) {

this.resourceProperties = resourceProperties;

}



@Bean

public SimpleUrlHandlerMapping faviconHandlerMapping() {

SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();

mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);

              //所有  /favicon.ico 

mapping.setUrlMap(Collections.singletonMap("
/favicon.ico",

faviconRequestHandler()));

return mapping;

}



@Bean

public ResourceHttpRequestHandler faviconRequestHandler() {

ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();

requestHandler

.setLocations(this.resourceProperties.getFaviconLocations());

return requestHandler;

}



}





1、所有 /webjars/ ,都去 classpath:/META-INF/resources/webjars/ 找资源

webjars:以jar包的方式引入静态资源。WebJars



访问localhost:8080/webjars/jquery/3.3.1/jquery.js的结果:





2、"/
" 访问当前项目的任何资源,都去静态资源的文件夹找映射

"classpath:/META-INF/resources/", 

"classpath:/resources/",

"classpath:/static/", 

"classpath:/public/" 

"/":当前项目的根路径



例子:访问localhost:8080/abc 就是去静态资源文件夹里面找abc



例如我们访问js文件夹下的Chart.min.js:



访问结果:





3、欢迎页: 静态资源文件夹下的所有index.html页面,被"/"映射

编写index.html文件。



访问结果:





三、模板引擎

常见的模板引擎:JSP、Velocity、Freemarker、Thymeleaf(springboot推荐,语法更简单,功能更强大)





1、引入Thymeleaf

Thymeleaf官网



在pom.xml中添加以下依赖:



 <dependency>

   <groupId>org.springframework.boot</groupId>

     <artifactId>spring-boot-starter-thymeleaf</artifactId>

 </dependency>



2、Thymeleaf的使用

@ConfigurationProperties(prefix = "spring.thymeleaf")

public class ThymeleafProperties {



private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");



private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");



public static final String DEFAULT_PREFIX = "classpath:/templates/";



public static final String DEFAULT_SUFFIX = ".html";



1

只要我们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染。



success.html:



HelloController:



package com.keafmd.springboot.controller;



import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;



/


  Keafmd

 


  @ClassName: HelloController

 
@Description:

  @author: 牛哄哄的柯南

 
@date: 2021-03-04 19:54

 */



@Controller

public class HelloController {



    @ResponseBody

    @RequestMapping("/hello")

    public String hello(){

        return "Hello World";

    }



    @RequestMapping("/success")

    public String success() {

        return "success";

    }

}



访问success的结果:





1、导入thymeleaf的名称空间

<html lang="en" xmlns:th="http://www.thymeleaf.org"&gt;

1

2、使用thymeleaf语法

HelloController:



package com.keafmd.springboot.controller;



import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;



import java.util.Map;



/*

 
Keafmd

 

 
@ClassName: HelloController

  @Description:

 
@author: 牛哄哄的柯南

  @date: 2021-03-04 19:54

 
/



@Controller

public class HelloController {



    @ResponseBody

    @RequestMapping("/hello")

    public String hello(){

        return "Hello World";

    }



    /*

     
查出一些数据在页面显示

      @param map

     
@return

     */

    @RequestMapping("/success")

    public String success(Map<String,Object> map) {

        map.put("hello","你好");

        return "success";

    }

}



success.html:



<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org"&gt;

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

    <h1>成功</h1>

    <!--th:text 将div里面的文本内容设置为-->

    <div th:text="${hello}"></div>

</body>

</html>



运行结果:





3、Thymeleaf的语法规则

1、th:任意html属性,来替换原生属性的值



th:text — 改变当前元素里面的文本内容

更多参考下图:



2、表达式



Simple expressions:(表达式语法)

    Variable Expressions: ${...}:获取变量值;OGNL;

    1)、获取对象的属性、调用方法

    2)、使用内置的基本对象:

    #ctx : the context object.

    #vars: the context variables.

                #locale : the context locale.

                #request : (only in Web Contexts) the HttpServletRequest object.

                #response : (only in Web Contexts) the HttpServletResponse object.

                #session : (only in Web Contexts) the HttpSession object.

                #servletContext : (only in Web Contexts) the ServletContext object.

                

                ${session.foo}

            3)、内置的一些工具对象:

execInfo : information about the template being processed.

messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.

uris : methods for escaping parts of URLs/URIs

conversions : methods for executing the configured conversion service (if any).

dates : methods for java.util.Date objects: formatting, component extraction, etc.

calendars : analogous to #dates , but for java.util.Calendar objects.

numbers : methods for formatting numeric objects.

strings : methods for String objects: contains, startsWith, prepending/appending, etc.

objects : methods for objects in general.

bools : methods for boolean evaluation.

arrays : methods for arrays.

lists : methods for lists.

sets : methods for sets.

maps : methods for maps.

aggregates : methods for creating aggregates on arrays or collections.

ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).



    Selection Variable Expressions: {...}:选择表达式:和${}在功能上是一样;

    补充:配合 th:object="${session.user}:

   <div th:object="${session.user}">

    <p>Name: <span th:text="
{firstName}">Sebastian</span>.</p>

    <p>Surname: <span th:text="{lastName}">Pepper</span>.</p>

    <p>Nationality: <span th:text="
{nationality}">Saturn</span>.</p>

    </div>

    

    Message Expressions: #{...}:获取国际化内容

    Link URL Expressions: @{...}:定义URL;

    @{/order/process(execId=${execId},execType='FAST')}

    Fragment Expressions: ~{...}:片段引用表达式

    <div th:insert="~{commons :: main}">...</div>

   

Literals(字面量)

      Text literals: 'one text' , 'Another one!' ,…

      Number literals: 0 , 34 , 3.0 , 12.3 ,…

      Boolean literals: true , false

      Null literal: null

      Literal tokens: one , sometext , main ,…

Text operations:(文本操作)

    String concatenation: +

    Literal substitutions: |The name is ${name}|

Arithmetic operations:(数学运算)

    Binary operators: + , - , * , / , %

    Minus sign (unary operator): -

Boolean operations:(布尔运算)

    Binary operators: and , or

    Boolean negation (unary operator): ! , not

Comparisons and equality:(比较运算)

    Comparators: > , < , >= , <= ( gt , lt , ge , le )

    Equality operators: == , != ( eq , ne )

Conditional operators:条件运算(三元运算符)

    If-then: (if) ? (then)

    If-then-else: (if) ? (then) : (else)

    Default: (value) ?: (defaultvalue)

Special tokens:

    No-Operation: _ 



注意:内容过多,详细内容参考官方文档。



示例:↓



HelloController:



package com.keafmd.springboot.controller;



import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;



import java.util.Arrays;

import java.util.Map;



/*

 
Keafmd

 

 
@ClassName: HelloController

  @Description:

 
@author: 牛哄哄的柯南

  @date: 2021-03-04 19:54

 
/



@Controller

public class HelloController {



    @ResponseBody

    @RequestMapping("/hello")

    public String hello(){

        return "Hello World";

    }



    /*

     
查出一些数据在页面显示

      @param map

     
@return

     */

    @RequestMapping("/success")

    public String success(Map<String,Object> map) {

        map.put("hello","你好");

        map.put("hello1","<h1>你好</h1>");

        map.put("users", Arrays.asList("柯南","小兰","基德"));

        return "success";

    }

}



success.html:



<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org"&gt;

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

    <h1>成功</h1>

    <!--th:text 将div里面的文本内容设置为-->

    <div id="div01" class="myDiv" th:id="${hello}" th:class="${hello}" th:text="${hello}">这里的内容被覆盖</div>



    <hr/>

    <div th:text="${hello1}"></div>

    <div th:utext="${hello1}"></div>

    <hr/>

    <!--th:each 每次遍历都会生成当前这个标签-->

    <h4 th:text="${user}" th:each="user:${users}"></h4>

    <hr/>

    <h4>

        <span th:each="user:${users}"> [[${user}]] </span>

    </h4>

</body>

</html>



效果:







四、SpringMVC自动配置

1、Spring MVC auto-configuration

参考官方文档:点这里



Spring Boot 自动配置好了SpringMVC



以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration)



Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.



自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))

ContentNegotiatingViewResolver:组合所有的视图解析器的。

如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来。

Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars



Static index.html support. 静态首页访问



Custom Favicon support (see below). favicon.ico



自动注册了 of Converter, GenericConverter, Formatter beans.



Converter:转换器; public String hello(User user):类型转换使用Converter

Formatter :格式化器; 2017.12.17===Date

@Bean

@ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则

public Formatter<Date> dateFormatter() {

    return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件

}

1

2

3

4

5

自己添加的格式化器转换器,我们只需要放在容器中即可



Support for HttpMessageConverters (see below).



HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json



HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter



自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)



Automatic registration of MessageCodesResolver (see below):定义错误代码生成规则



Automatic use of a ConfigurableWebBindingInitializer bean (see below).



我们可以配置一个ConfigurableWebBindingInitializer来替换默认的(添加到容器)



初始化WebDataBinder

请求数据=====JavaBean

1

2

org.springframework.boot.autoconfigure.web:web的所有自动场景



If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.



如果你想保持Spring Boot MVC 功能,你只是想添加额外的(MVC配置)(https://docs.spring.io/spring/docs/4.3.14.RELEASE/spring-framework-reference/htmlsingle MVC)(拦截器,格式器,视图控制器等)您可以添加自己的@ configuration类WebMvcConfigurerAdapter类型,但没有@EnableWebMvc。如果你想提供RequestMappingHandlerMapping, RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,你可以声明一个WebMvcRegistrationsAdapter实例来提供这样的组件。



If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.



如果你想完全控制Spring MVC,你可以添加你自己的@Configuration注解@EnableWebMvc。



2、扩展SpringMVC

实现如下功能:



<mvc:view-controller path="/hello" view-name="success"></mvc:view-controller>



<mvc:interceptors>

    <mvc:interceptor>

        <mvc:mapping path="/hello"/>

        <bean></bean>

    </mvc:interceptor>

</mvc:interceptors>



做法:编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc



特点:既保留了所有的自动配置,也能用我们扩展的配置。



在config包下创建个MyMvcConfig。



代码实现:



package com.keafmd.springboot.config;



import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;





/*

 
Keafmd

 

 
@ClassName: MyMvcConfig

  @Description:

 
@author: 牛哄哄的柯南

  @date: 2021-03-17 20:26

 
/

@Configuration

public class MyMvcConfig implements WebMvcConfigurer {

    @Override

    public void addViewControllers(ViewControllerRegistry registry) {

        //浏览器发送 /keafmd 请求 来到success页面

        registry.addViewController("/keafmd").setViewName("success");

    }

}



原理

1、WebMvcAutoConfiguration是SpringMVC的自动配置类。

2、在做其他自动配置时会导入,@Import(EnableWebMvcConfiguration.class)。



   @Configuration

public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {

     private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();



     //从容器中获取所有的WebMvcConfigurer

     @Autowired(required = false)

     public void setConfigurers(List<WebMvcConfigurer> configurers) {

         if (!CollectionUtils.isEmpty(configurers)) {

             this.configurers.addWebMvcConfigurers(configurers);

            //一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;  

            @Override

            // public void addViewControllers(ViewControllerRegistry registry) {

             //    for (WebMvcConfigurer delegate : this.delegates) {

              //       delegate.addViewControllers(registry);

              //   }

             }

         }

}



3、容器中所有的WebMvcConfigurer都会一起起作用。

4、我们的配置类也会被调用。



效果:SpringMVC的自动配置和我们的扩展配置都会起作用。



3、全面接管SpringMVC

SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置,所有的SpringMVC的自动配置都失效了。



做法:我们需要在配置类中添加@EnableWebMvc即可。



@EnableWebMvc

@Configuration

public class MyMvcConfig implements WebMvcConfigurer {

    @Override

    public void addViewControllers(ViewControllerRegistry registry) {

        //浏览器发送 /keafmd 请求 来到success页面

        registry.addViewController("/keafmd").setViewName("success");

    }

}





全面接管后,静态资源失效。

不推荐这样全面接管。





原理

加了@EnableWebMvc自动配置就失效了。



1、@EnableWebMvc的核心:



@Import({DelegatingWebMvcConfiguration.class})

public @interface EnableWebMvc {



2、DelegatingWebMvcConfiguration



@Configuration(

    proxyBeanMethods = false

)

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {



3、WebMvcAutoConfiguration



@Configuration(

    proxyBeanMethods = false

)

@ConditionalOnWebApplication(

    type = Type.SERVLET

)

@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})

//容器中没有这个组件的时候,这个自动配置类才生效

@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

@AutoConfigureOrder(-2147483638)

@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})

public class WebMvcAutoConfiguration {



4、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来,自动配置类失效了。



5、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。



五、如何修改SpringBoot的默认配置

1、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来。

2、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。

3、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。



以上就是SpringBoot与Web开发(超详细)篇一的全部内容。

————————————————

版权声明:本文为CSDN博主「牛哄哄的柯南」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_43883917/article/details/114375472


蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服


CSS伪类:empty让我眼前一亮

前端达人

最近看过我文章的都知道:我最近在负责一个微信小程序的项目,在其中遇到了很多有趣的事和一些“奇思妙想”。本文的背景就是某天早上我看着wxml文件中一堆wx:if/elsehidden突然很烦躁,先不说wx:if导致的性能问题,就是标签上也是冗杂的。


接着上一篇文章【微信小程序自定义组件库yPicker组件分析及省市区三级联动实现】,在其中我分析了这么一个例子 —— 省市区三级联动的自定义实现,在其中有详细代码这里就不多说,说说如何调用:

我当时是这么想的:一方面出于“不在JavaScript里写太多东西”的考虑,另一方面,由于省、市、区我是分别用三个变量来实现的,所以JavaScript里就关注这三个变量,比如之间的空格或其它东西都拿到wxml文件里。就像这样:

<view class="departments location" bindtap="fixedshow"> <view class="depart_title">所在位置</view> <view wx:if="{{provinces&&citys&&areas}}" class="placeholder depart_content">{{provinces}} {{citys}} {{areas}}</view> <view class="placeholder depart_content befselect" wx:else>请选择当前位置</view> <view class="desc">如有变动请修改后再次提交</view> </view> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(因为调用涉及到后来改动的只有在点击弹窗里的“确认”按钮时在事件中将那三个变量分别赋给这段代码中出现的三个变量 —— 否则会只要改动不管是点取消还是确认已经发生改变了,这样不妥!)

其布局是这样的:

.departments{ width: 100%; height: 96rpx; display: flex; align-items: center; font-size: 36rpx; font-weight: 347; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } .location{ position: relative; border-bottom: 1rpx solid rgba(0,0,0,.009); display: flex; align-items: flex-start; padding-top: 20rpx; } .desc{ position: absolute; right: 19rpx; bottom: 4rpx; color: rgb(63,142,255); font-size: 23rpx; } .departments .depart_title{ width: 20%; } .departments .depart_content{ margin-left: 10%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } .departments .placeholder{ width: 69%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

location


在决定了要替换这里的wx:if以后,你首先要想:用什么替换?
wx:if作用是判断“是否存在”,如果不存在(条件不满足)就切换到wx:else或是wx:elif的逻辑里!

OK,想到这里,你应该能想到一个css伪类::empty !它的作用和我们想要的效果一样:判断如果元素(内容)为空的话…
我迅速对代码做了改动:

<view class="departments location" bindtap="fixedshow"> <view class="depart_title">所在位置</view> <view class="placeholder depart_content">{{provinces}} {{citys}} {{areas}}</view> <view class="desc">如有变动请修改后再次提交</view> </view> 
  • 1
  • 2
  • 3
  • 4
  • 5

然后在class - depart_content上加了这个伪类:

.placeholder:empty::before{ content: "请选择当前位置"; color: rgba(0,0,0,.6); } 
  • 1
  • 2
  • 3
  • 4

wx
一片空白!

经过查阅资料::empty伪类表示如果标签内容为空,那么内容区域如果带有空格,也是不会被匹配到的!

在写标签时一定要注意这一点:标签内是否有空格或换行!(换行常常被解析为一个空格)
遇到非单标签一定注意闭合标签!

最后解决办法是:在js中将三个变量用空格相连接,再渲染到页面上即可!
wx-position
(其实这里是一个自定义的选择器,而自动定位就是往高德地图发送了请求获取到省市区字段而已,代码就不写了。。。)


到这里我们会发现一个事:上面我们不仅用了empty伪类,还用了before伪元素!

其实这一点很平常 —— 毕竟只有empty是添加不了内容的(似乎纵观css,只有before和after这样伪元素可以向页面中添加内容,不管是文字还是图片之类的)

我认为更应该关注到的是两个地方:

  1. 伪元素中没有用position定位!一般来说对一个(存在内容的)元素来说,为其设置“前置”(before)/“后置”(after)样式都需要定位:规定其显示的地方。不然大概率伪元素中的文字是显示不出来的,通过本文的empty可以猜测:他被原本存在的内容覆盖住了。
  2. 从第一点可以得出::before 和 :after 伪元素向标签内插入内容、图形,并不会影响empty伪类的匹配!

这个特性实用的一批。


由上,可见此伪类最大的用处就是“字段缺失提示”!这是非常实用的。而且把这项任务交给CSS也可以减轻许多“(布局)负担”、体验更好、维护起来也更方便!

比如:我在项目优化时就将所有有请求的字段都加上了统一类名:

.ym-empty:empty::before{ content: "暂无数据,请重试", display: block; text-align: center; color: rgba(0,0,0,.6); /** 其它定位、字体更改操作 */ }


作者:,转载


炫酷的大数据可视化设计赏析(八)

前端达人

随着大数据产业的发展,越来越多的公司开始实现数据资源的管理和应用,尤其是一些在日常生活中经常使用大屏幕的大中型企业。此时,用户界面设计者需要呈现相应的视觉效果。


随着信息化的发展,智慧城市、智能油田、政务云、企业云等一系列信息化目标逐一实现。实现了以云平台为目标的各资源管控、资源业务的管理。随着管控触角的延伸、云存储的各种大数据,如何监控、分析、展示出核心数据和重点数据其尤为重要。

在集团企业中、以运维中心人员为用户群体,通过大屏实时掌握业务数据情况,在系统设计时既要考虑数据的直观性,又要考虑视觉疲劳,在其界面构思上要结合行业特点、数据特性进行策划,以立体感形式表现更佳。


接下来为大家介绍大屏可视化的UI设计。

jhk-1603104719964.jpg

jhk-1603104817863.jpg

jhk-1603866385802.jpg

jhk-1603866400790.jpg

jhk-1603866541134.jpg

jhk-1603866858741.jpg

jhk-1603866852818.jpg

jhk-1603866817588.jpg

jhk-1603866706529.jpg

jhk-1603866625088.jpg

jhk-1603866613876.jpg

jhk-1603866605141.jpg

jhk-1603866919828.png

jhk-1603866924130.jpg

jhk-1603866965540.jpg

jhk-1603867076475.jpg

jhk-1603867083483.jpg

jhk-1603867144749.jpg

jhk-1603867206051.jpg

WechatIMG565.png

WechatIMG607.jpeg



 --大屏UI设计--

--大数据可视化ui设计赏析--

(图片均来源于网络)

点击查看更多UI/UE设计案例⬇️⬇️⬇️

  蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服



    更多精彩文章:

       

 大数据可视化设计赏析(一)

  大数据可视化设计赏析(二)

  大数据可视化设计赏析(三)

  大数据可视化设计赏析(四)

  大数据可视化设计赏析(五)

  大数据可视化设计赏析(六)

  大数据可视化设计赏析(七)




JavaScript语法、语句、关键字保留字、变量

前端达人

第三章 基本概念

3.1 语法

3.1.1 区分大小写

  1. 变量名test和Test完全不同

3.1.2 标识符:变量、函数、属性的名字,或者函数的参数

  1. 命名规则
    • 第一个字符必须是一个字母、下划线、或者美元符号$
    • 其他字符可以是字母、下划线、美元符号、数字
  2. 采用驼峰大小写格式:第一个字母小写,剩下每个单词首字母大写。
    • for example:myName、herAge。
    • 驼峰式命名虽不是强制要求,但可以视为一种最佳实践。

3.1.3 注释

包括单行注释和块级注释。

  1. 单行注释:以两个斜杠开头。如下所示:
// alert(“HelloWorld!”) 
  • 1
  1. 块级注释:以一个斜杠和一个星号(/*)开头,以一个星号和一个斜杠结尾。如下所示:
/*
这是一个
多行的
块级注释
*/ 
  • 1
  • 2
  • 3
  • 4
  • 5

3.1.4 严格模式

  1. 定义:为JavaScript定义的一种不同的解析与执行模型。
  2. 使用方法:
    • 在整个脚本中启用严格模式,可以在顶部添加代码“use strict”;
    • 也可以在函数内部的上方包含这条编译指示。
  3. 使用效果:严格模式下,ECMAScript3中的一些不确定行为会得到处理,而且对某些不安全的操作也会抛出错误。严格模式下,js的执行效果会有很大不同。

3.1.5 语句

  • ECMAScript中的语句以一个分号结尾,但非必需。
  • 若省略分号,则由解析器确定语句的结尾。
  • 建议不要省略分号,因为写上解析器就不必要再花时间推测应该在哪里插入分号了。

3.2 关键字和保留字

ECMA-262描述了一组具有特定用途的关键字和一组不能用做标识符的保留字。

  1. 关键字:可以用于表示控制语句的开始或结束、或用于执行特定操作等。
  2. 保留字:保留字虽然在这门语言中还没有特定的用途,但他们有可能在将来被用作关键字。

3.3 变量

  • ECMAScript的变量是松散类型,即可以用来保存任何类型的数据。
  • 定义变量时要用var操作符,后跟变量名,例如var message,当然了,也可以直接在定义的时候对变量做一个初始化,例如var message = ‘hi’ ;
  • 这段的意思是变量message中保存了一个字符串“hi”。像这样初始化变量并不会把它标记为字符串类型,初始化的过程就只是给变量赋了一个值。
  • 因此,划重点,可以在修改变量的同时修改值的类型。例如:
var message = ‘hi’ ;
message = 100 ;   //有效,但不推荐
//这个例子代表变量message一开始保存了一个字符串“hi”,然后该值又被一个数字值100取代了。 
  • 1
  • 2
  • 3
  • 有一点需要注意,用var操作符定义的变量将成为该变量的作用域中的局部变量。也就是说如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁。例如:
function test(){
    var  message = ‘hi’ ; //局部变量
} ;
test();
alert(message); //错误

//为什么是错误?
//这里,变量message是在函数里用var定义的,当函数被调用时,就会创建该变量并为其赋值。而在此之后,这个变量会立即被销毁。所以在执行alerat()那行代码的时候message已经被销毁了,因此报错。 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

那么,该怎么解决呢?

  • 在函数内部省略掉var操作符,就可以创建一个全局变量,例子:
function test(){
    message = ‘hi’ ; //局部变量
} ;
test();
alert(message); // hi
//在函数内部不用var会创建全局变量。
//但我们并不提倡这种做法,因为局部作用域中定义的全局变量很难去维护。
//所以我们应该选择在开始就定义好所有的变量。

《跨域------>三种跨域底层分析》

前端达人

 转载:   原创作者: 

在这里插入图片描述

1.方式一:利用< script >标签,< script >不存在跨域问题


在这里插入图片描述

2. (服务端解决)SpringMVC的controller中加入注解@CrossOrigin(value = “http://localhost:8080”)

即:给响应头设置一个Access-Control-Allow-Origin属性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.(客户端解决)使用Ajax中的JSONP实现跨域(常用)

3.1原理:利用< script >标签

3.2代码

将callback当成一个参数传递下去在这里插入图片描述
在这里插入图片描述
前后端运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

深入理解vue中的slot与slot-scope

前端达人

写在前面

vue中关于插槽的文档说明很短,语言又写的很凝练,再加上其和methods,data,computed等常用选项使用频率、使用先后上的差别,这就有可能造成初次接触插槽的开发者容易产生“算了吧,回头再学,反正已经可以写基础组件了”,于是就关闭了vue说明文档。

实际上,插槽的概念很简单,下面通过分三部分来讲。这个部分也是按照vue说明文档的顺序来写的。

进入三部分之前,先让还没接触过插槽的同学对什么是插槽有一个简单的概念:插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定。 实际上,一个slot最核心的两个问题这里就点出来了,是显示不显示怎样显示

由于插槽是一块模板,所以,对于任何一个组件,从模板种类的角度来分,其实都可以分为非插槽模板插槽模板两大类。
非插槽模板指的是html模板,指的是‘div、span、ul、table’这些,非插槽模板的显示与隐藏以及怎样显示由插件自身控制;插槽模板是slot,它是一个空壳子,因为它显示与隐藏以及最后用什么样的html模板显示由父组件控制。但是插槽显示的位置确由子组件自身决定,slot写在组件template的哪块,父组件传过来的模板将来就显示在哪块

单个插槽 | 默认插槽 | 匿名插槽

首先是单个插槽,单个插槽是vue的官方叫法,但是其实也可以叫它默认插槽,或者与具名插槽相对,我们可以叫它匿名插槽。因为它不用设置name属性。

单个插槽可以放置在组件的任意位置,但是就像它的名字一样,一个组件中只能有一个该类插槽。相对应的,具名插槽就可以有很多个,只要名字(name属性)不同就可以了。

下面通过一个例子来展示。

父组件:


  1. <template>
  2. <div class="father">
  3. <h3>这里是父组件</h3>
  4. <child>
  5. <div class="tmpl">
  6. <span>菜单1</span>
  7. <span>菜单2</span>
  8. <span>菜单3</span>
  9. <span>菜单4</span>
  10. <span>菜单5</span>
  11. <span>菜单6</span>
  12. </div>
  13. </child>
  14. </div>
  15. </template>

子组件:


  1. <template>
  2. <div class="child">
  3. <h3>这里是子组件</h3>
  4. <slot></slot>
  5. </div>
  6. </template>

在这个例子里,因为父组件在<child></child>里面写了html模板,那么子组件的匿名插槽这块模板就是下面这样。也就是说,子组件的匿名插槽被使用了,是被下面这块模板使用了。


  1. <div class="tmpl">
  2. <span>菜单1</span>
  3. <span>菜单2</span>
  4. <span>菜单3</span>
  5. <span>菜单4</span>
  6. <span>菜单5</span>
  7. <span>菜单6</span>
  8. </div>

最终的渲染结果如图所示:



  1. 注:所有demo都加了样式,以方便观察。其中,父组件以灰色背景填充,子组件都以浅蓝色填充。

具名插槽

匿名插槽没有name属性,所以是匿名插槽,那么,插槽加了name属性,就变成了具名插槽。具名插槽可以在一个组件中出现N次。出现在不同的位置。下面的例子,就是一个有两个具名插槽单个插槽的组件,这三个插槽被父组件用同一套css样式显示了出来,不同的是内容上略有区别。

父组件:


  1. <template>
  2. <div class="father">
  3. <h3>这里是父组件</h3>
  4. <child>
  5. <div class="tmpl" slot="up">
  6. <span>菜单1</span>
  7. <span>菜单2</span>
  8. <span>菜单3</span>
  9. <span>菜单4</span>
  10. <span>菜单5</span>
  11. <span>菜单6</span>
  12. </div>
  13. <div class="tmpl" slot="down">
  14. <span>菜单-1</span>
  15. <span>菜单-2</span>
  16. <span>菜单-3</span>
  17. <span>菜单-4</span>
  18. <span>菜单-5</span>
  19. <span>菜单-6</span>
  20. </div>
  21. <div class="tmpl">
  22. <span>菜单->1</span>
  23. <span>菜单->2</span>
  24. <span>菜单->3</span>
  25. <span>菜单->4</span>
  26. <span>菜单->5</span>
  27. <span>菜单->6</span>
  28. </div>
  29. </child>
  30. </div>
  31. </template>

子组件:


  1. <template>
  2. <div class="child">
  3. // 具名插槽
  4. <slot name="up"></slot>
  5. <h3>这里是子组件</h3>
  6. // 具名插槽
  7. <slot name="down"></slot>
  8. // 匿名插槽
  9. <slot></slot>
  10. </div>
  11. </template>

显示结果如图:


可以看到,父组件通过html模板上的slot属性关联具名插槽。没有slot属性的html模板默认关联匿名插槽。

作用域插槽 | 带数据的插槽

最后,就是我们的作用域插槽。这个稍微难理解一点。官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽。什么意思呢,就是前面两种,都是在组件的template里面写


  1. 匿名插槽
  2. <slot></slot>
  3. 具名插槽
  4. <slot name="up"></slot>

但是作用域插槽要求,在slot上面绑定数据。也就是你得写成大概下面这个样子。


  1. <slot name="up" :data="data"></slot>
  2. export default {
  3. data: function(){
  4. return {
  5. data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
  6. }
  7. },
  8. }

我们前面说了,插槽最后显示不显示是看父组件有没有在child下面写模板,像下面那样。


  1. <child>
  2. html模板
  3. </child>

写了,插槽就总得在浏览器上显示点东西,东西就是html该有的模样,没写,插槽就是空壳子,啥都没有。
OK,我们说有html模板的情况,就是父组件会往子组件插模板的情况,那到底插一套什么样的样式呢,这由父组件的html+css共同决定,但是这套样式里面的内容呢?

正因为作用域插槽绑定了一套数据,父组件可以拿来用。于是,情况就变成了这样:样式父组件说了算,但内容可以显示子组件插槽绑定的。

我们再来对比,作用域插槽和单个插槽和具名插槽的区别,因为单个插槽和具名插槽不绑定数据,所以父组件是提供的模板要既包括样式由包括内容的,上面的例子中,你看到的文字,“菜单1”,“菜单2”都是父组件自己提供的内容;而作用域插槽,父组件只需要提供一套样式(在确实用作用域插槽绑定的数据的前提下)。

下面的例子,你就能看到,父组件提供了三种样式(分别是flex、ul、直接显示),都没有提供数据,数据使用的都是子组件插槽自己绑定的那个人名数组。

父组件:


  1. <template>
  2. <div class="father">
  3. <h3>这里是父组件</h3>
  4. <!--第一次使用:用flex展示数据-->
  5. <child>
  6. <template slot-scope="user">
  7. <div class="tmpl">
  8. <span v-for="item in user.data">{{item}}</span>
  9. </div>
  10. </template>
  11. </child>
  12. <!--第二次使用:用列表展示数据-->
  13. <child>
  14. <template slot-scope="user">
  15. <ul>
  16. <li v-for="item in user.data">{{item}}</li>
  17. </ul>
  18. </template>
  19. </child>
  20. <!--第三次使用:直接显示数据-->
  21. <child>
  22. <template slot-scope="user">
  23. {{user.data}}
  24. </template>
  25. </child>
  26. <!--第四次使用:不使用其提供的数据, 作用域插槽退变成匿名插槽-->
  27. <child>
  28. 我就是模板
  29. </child>
  30. </div>
  31. </template>

子组件:


  1. <template>
  2. <div class="child">
  3. <h3>这里是子组件</h3>
  4. // 作用域插槽
  5. <slot :data="data"></slot>
  6. </div>
  7. </template>
  8. export default {
  9. data: function(){
  10. return {
  11. data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
  12. }
  13. }
  14. }

结果如图所示:


转载地址:https://segmentfault.com/a/1190000012996217

转载作者/云荒杯倾

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档