seho 发布的文章

u=2703915976,3722517054&fm=26&gp=0.jpg

品优购:

我们需要做一个功能就是完成商品的分类,需要操作的pojo是itemcat,我们的根分类的id是0,所以我们现在的需求是当我们点击哪一个的时候就要查询当前id的下级
所以我们的第一个service产生了,就是根据父类id查询子类:我们这样写:

/**

  * 根据父id查询对象
  */
 public List<TbItemCat> getItemByParentId(Long parentId) {
     TbItemCatExample example = new TbItemCatExample();
     Criteria createCriteria = example.createCriteria();
     // 匹配父ID
     createCriteria.andParentIdEqualTo(parentId);
     List<TbItemCat> selectByExample = itemCatMapper.selectByExample(example);
     return selectByExample;
 }

这样就我们能查询出来,action省略,我们来看看主要的前端代码:

初始化:ng-init="selectByParentId(0)"
传参为0,我们循环的是父级;

ng-click="findOne(entity.id)"

这样就可以在列表中点击哪个就出现哪个的分类了,我们这一部分完成了,现在的需求就是我们要完成面包屑的操作;

我们面包屑的层级是这样的,默认是父级是1,二级是2,三级是3;

然后我们定义一些方法:

1.首先是初始化层级和设置层级

//设置面包屑初始为0根目录

 $scope.grade = 1;
 //设置级别
 $scope.setGrade = function(value) {
     $scope.grade = value;
 }

2.判断当前的层级,如果层级是2,就把对应的参数传递层级2的对象中,然后通过这个对象中的id再查询

//读取列表

 $scope.selectGrade = function(p_entity) {
     //如果为一级
     if ($scope.grade === 1) {
          $scope.entity_1 = null;
          $scope.entity_2 = null;
     }
     if ($scope.grade === 2) {
          $scope.entity_1 = p_entity;
          $scope.entity_2 = null;
     }
     if($scope.grade === 3){
          $scope.entity_2 = p_entity;
     }
     
     $scope.selectByParentId(p_entity.id)
 }

然后我们的html可以这样写:

面包屑:

  • 顶级分类列表

  • {{entity_1.name}}

  • {{entity_2.name}}
  • 我们的列表的按钮:

    ng-click="setGrade(grade+1);selectGrade(entity)

    面包屑思路:当我们点击查询下一级的时候,会把层级关系加1,然后进行查询,查询的条件碰到了层级2,就会把它的对象变成entity_1,然后我们的面包屑上写的就是entity_1.name ; 所以我们就可以通过这样的方式来达到面包屑的效果。

    ----实现商品录入,在进行商品录入之前,我们需要知道2个概念:

    我们在写电商系统的时候,必须得要理解spu和sku是什么概念,具体就不阐述了,sku就是具体的商品列表,spu是商品的一些主干。
    这个商品的录入我们要结合2张表,一个是goods一个是goodsDesc,所以我们需要写一个组合表

    // 电商spu
     private TbGoods goods;
     // 商品拓展介绍
     private TbGoodsDesc goodsDesc;
     // 电商sku列表
     private List<TbItem> itemList;
    

    组合写好之后,我们需要更改mapper中,添加一个selectkey查询一下主键,这个主键的意图很简单,在添加商品成功之后,需要拿这个id做商品的拓展增加;

    所以我们的service层是这样写的:

    public void add(Goods goods) {

         // 增加商品记录
         // 设置未申请状态
         goods.getGoods().setAuditStatus("0");
         goodsMapper.insert(goods.getGoods());
         // 插入拓展信息,获取添加后的id
          goods.getGoodsDesc().setGoodsId(goods.getGoods().getId());
         // 添加
         goodsDescMapper.insert(goods.getGoodsDesc());
     }
    

    action同样省略(需要获取登陆名词并且set到里面去),我们这样就可以做好商品录入了,我们的前端进行对应的绑定即可,主要的是我们用到了一个富文本的编辑器:

    初始化,拿到editor对象,可以通过.html拿到里面的值进行添加到goodsDesc对象即可;

    FastDFS分布式文件管理服务器:

    我们开发过程中,可以只用一台服务器,这个服务器准备好了,运行开启即可,然后我们需要准备几个配置文件,一个是conf文件一个是简单封装了上传的文件
    具体的步骤我们可以看写的demo,不要忘记在springmvc中加入媒体解析器,上传后端代码:

     @RequestMapping("upload")
     public Result upload(MultipartFile file) {
         // 获取文件名
         String OriginalFilename = file.getOriginalFilename();
         // 截取文件的后缀
         String name = OriginalFilename.substring(OriginalFilename.lastIndexOf(".") + 1);
         try {
              util.FastDFSClient client = new FastDFSClient("classpath:config/fdfs_client.conf");
              String fileName = client.uploadFile(file.getBytes(), name);
              // 拼接图片url
              String url = images_server_url + fileName;
              return new Result(true, url);
         } catch (Exception e) {
              return new Result(false, "上传失败");
              // TODO: handle exception
         }
     }
    

    工具类在common中,util包中,需要加maven依赖才能引入,可以通过value注解来给images_server_url注入值,通过application.properties

    前端代码:

    this.upload = function() {

         //上传二进制文件需要的form对象
         var formData = new FormData();
         //添加文件到对象
         formData.append("file", file.files[0]); //name为file的第0个文件
         //执行上传,设置相关配置
         return $http({
              url : '../upload.do',
              method : "POST",
              //携带数据:
              data : formData,
              //设置头信息,如果不写,默认是json格式
              headers : {
                  'Content-Type' : undefined
              },
              //angular上传必须要写的:序列化
              transformRequest : angular.identity
         })
     }
    

    控制层:

    //上传图片

     $scope.upload = function() {
         $scope.imageEntity = {}
         uploadFile.upload().success(
              function(response) {
                  if (response.success) {
                       $scope.imageEntity.url = response.message
                  } else {
                       alert(response.message)
                  }
              }
         )
     }
     
     
     //定义实体结构
     $scope.entity = {goods:{},goodsDesc:{itemImages:[]}}
     //添加图片列表
     $scope.addImgList = function() {
          $scope.entity.goodsDesc.itemImages.push($scope.imageEntity)
     }
     //移出出图片列表
     $scope.deleImgList = function(index) {
          $scope.entity.goodsDesc.itemImages.splice(index, 1);
     }
    
    

    timg (1).jpg
    今天学习了这个SpringSecurity这个框架,记录一下注意的知识点和坑

    首先这个是一个安全框架,主要用途就是在登陆上,它为我们提供了很好的安全性和性能,为我们减少了很多开发需求

    我们可以花费一点点时间做一个入门小demo

    引入包和webxml加载配置我就不说了,都是复制粘贴的,最主要就是看我们的框架xml配置,我们需要了解一些功能。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"

     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd">

     
     
     <!-- 以下页面不拦截 -->
     <http pattern="/login.html" security="none"></http>
     <http pattern="/login_error.html" security="none"></http>
     <!-- 页面拦截规则 -->
     <http use-expressions="false">
         <intercept-url pattern="/**" access="ROLE_USER"/>
         <!-- 开启表单自动生成 -->
         <form-login default-target-url="/index.html" authentication-failure-url="/login_error.html"/>
         <csrf disabled="true"/>
     </http>
     
     <!-- 认证管理器 -->
     <authentication-manager>
         <authentication-provider>
              <user-service>
                  <user name="admin" password="admin" authorities="ROLE_USER"/>
              </user-service>
         </authentication-provider>
     </authentication-manager>

    </beans:beans>

    我们的页面拦截规则的pattern主要是不拦截资源,比如我们的一些登陆页面或者错误页面,这些页面是不需要拦截的。
    我们拦截的规则设置成跟目录下的所有资源,匹配的用户是ROLE_USER , 框架必须指定前缀是ROLE,这里要注意,我们可以开启表单自动生成,然后成功跳转到首页,错误跳转
    到错误页面。

    我们的认证管理器,主要是写死账号和密码。

    这样就可以给我们提供了一个自动生成的,包括html页面都是框架帮助我们生成好了,我们通过了一个入门小案例知道了这个框架的大体运用。

    然后开始运用到项目中,引入依赖和webxml就不敲了,我们还是来熟悉一下业务场景,首先我们不能让框架帮助我们生成丑陋的登陆页面了,我们需要指定自己的登陆页面。
    我们可以这样写:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"

     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd">

     <!-- 匹配不拦截的资源 -->
     <http pattern="/*.html" security="none"></http>
     <http pattern="/css/**" security="none"></http>
     <http pattern="/img/**" security="none"></http>
     <http pattern="/js/**" security="none"></http>
     <http pattern="/plugins/**" security="none"></http>
     <!-- 页面拦截规则 -->
     <http use-expressions="false">
         <intercept-url pattern="/**" access="ROLE_ADMIN" />
         <form-login login-page="/login.html" default-target-url="/admin/index.html"
              authentication-failure-url="/login.html" always-use-default-target="true" />
         <!-- 跨域拦截是否禁用 -->
         <csrf disabled="true" />
         <!--设置不拦截iframe框架内置 -->
         <headers>
              <frame-options policy="SAMEORIGIN" />
         </headers>
         <logout/>
     </http>
     <!-- 认证管理器 -->
     <authentication-manager>
         <authentication-provider>
              <user-service>
                  <user name="admin" password="123456" authorities="ROLE_ADMIN" />
              </user-service>
         </authentication-provider>
     </authentication-manager>
     

    </beans:beans>

    我们不拦截的资源就根据项目的场景来决定,我们在form中配置指定登陆页面,而且要加入一个成功默认跳转页面(很重要)
    认证管理器我们还是写死一个账号密码,让他可以登陆,这样我们就在管理员后台登陆的时候用到了这个安全框架,值得注意的是:

    前端html:action : /login 必须post方法 账号和密码的name必须是username和password

    然后我们开始做运营商的商家入驻申请其中非常关键的安全框架的查询数据库登陆+密码加密:

    查询数据库进行登陆,我们之前写的security写的是固定的admin和密码,我们如何查询数据库呢??

    我们需要自己在controller写一个包,在包下建立一个特殊的服务,我们在中配置扫描的是controller的包,所以我们这边的注入service是不起作用的通过注解
    因为这个服务是在doubbo远程注册,所以我们只能通过xml注入,我们先看看具体的查询服务:

    package com.pinyougou.service;

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;

    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;

    import com.pinyougou.pojo.TbSeller;
    import com.pinyougou.sellergoods.service.SellerService;

    /**

    • 认证类
      *
    • @author LAOSHEN
      *
      */
      public class UserDetailsServiceImpl implements UserDetailsService {

      // 此服务注入通过dubbo远程注入
      private SellerService sellerService;

      public void setSellerService(SellerService sellerService) {

        this.sellerService = sellerService;

      }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 添加角色集合
        List<GrantedAuthority> authorities = new ArrayList();
        authorities.add(new SimpleGrantedAuthority("ROLE_SELLER"));
        TbSeller seller = sellerService.findOne(username);
        // 判断用户是否存在
        if (seller != null) {
            // 判断用户是否通过审核
            if (seller.getStatus().equals("1")) {
                // 如果通过审核就生成改用户的正确密码与输入的进行匹配
                return new User(username, seller.getPassword(), authorities);
            } else {
                // 如果没有通过审核
                return null;
            }
        } else {
            // 如果没有此用户
            return null;
        }
    }

    }

    返回空就直接不能登陆成功,重定向到login页面中,最重要的是我们的安全框架的配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"

     xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

    http://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd
    http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd">

     <!-- 匹配不拦截的资源 -->
     <http pattern="/*.html" security="none"></http>
     <http pattern="/css/**" security="none"></http>
     <http pattern="/img/**" security="none"></http>
     <http pattern="/js/**" security="none"></http>
     <http pattern="/plugins/**" security="none"></http>
     <http pattern="/seller/add.do" security="none"></http>   //把一些业务逻辑的url进行放行,否则无法进行业务逻辑的操作
     <!-- 页面拦截规则 -->
     <http use-expressions="false">
         <intercept-url pattern="/**" access="ROLE_SELLER" />
         <form-login login-page="/shoplogin.html" default-target-url="/admin/index.html"
              authentication-failure-url="/shoplogin.html" always-use-default-target="true" />
         <!-- 跨域拦截是否禁用 -->
         <csrf disabled="true" />
         <!--设置不拦截iframe框架内置 -->
         <headers>
              <frame-options policy="SAMEORIGIN" /> 
         </headers>
         <logout/> //注销选项,页面通过访问/logout 即可注销
     </http>
     <!-- 认证管理器 -->
     <authentication-manager>
         <authentication-provider user-service-ref="UserDetailsService">
              <password-encoder ref="bcryptEncoder"></password-encoder>  //依赖于加密实现类,登陆的时候可以把原密码自动加密,无需将加密后的密码解密进行匹配
         </authentication-provider>
     </authentication-manager>
     
     <beans:bean id="UserDetailsService" class="com.pinyougou.service.UserDetailsServiceImpl">
         <beans:property name="sellerService" ref="sellerService"></beans:property>  //认证类:注入service接口,从dubbo中,需要拥有set方法别忘记了
     </beans:bean>
     
     <!-- 引用dubbo 服务 ,从注册中心去寻找接口服务并且注入-->
     <dubbo:application name="pinyougou-shop-web" />
     <dubbo:registry address="zookeeper://192.168.25.151:2181"/>
     <dubbo:reference id="sellerService" interface="com.pinyougou.sellergoods.service.SellerService"></dubbo:reference>  //从dubbo注册地址找service接口的服务,并且注册给认证类
     
     
     <beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="bcryptEncoder"></beans:bean>  //加密实现类

    </beans:beans>

    我们存入数据库的密码,可以通过在controller中这样定义:

    public Result add(@RequestBody TbSeller seller) {

         // 对密码进行加密存储到数据库
         BCryptPasswordEncoder passwordLock = new BCryptPasswordEncoder();
         String newPassWord = passwordLock.encode(seller.getPassword());
         seller.setPassword(newPassWord);
         try {
              sellerService.add(seller);
              return new Result(true, "增加成功");
         } catch (Exception e) {
              e.printStackTrace();
              return new Result(false, "增加失败");
         }
     }
    

    可以通过 BCrypt 类进行封装,让数据库存入加密之后的密码即可

    具体的可以看品优购的第四天的讲义。

    前段时间刚刚结束了我的18岁生日,一些很久不联系的朋友给我送上了祝福。
    简单的回忆一下最近几年发生的事情吧,很多人timg.jpg都已经知道我的经历了,高三辍学,学习编程,那个时候不到17岁,16岁可以说是,15岁左右就开始
    接触一点互联网灰色的产业,跟几个大哥哥一起写脚本赚一点收入,也算是满足了当时我一点点的虚荣心吧。
    我觉得,我长得那一瞬间是有一次放学回家,我把书房门一关上,书包中的书本取出来,电脑打开(假装写作业),然后每天看行业动态,写脚本更新
    软件,然后老妈一来我就假装写作业,然后那一天晚上,我觉得这样不是一个长久之计,就给妈妈坦白:“我想正规训练一下计算机”,就这样我就来到了西安某技校大专。
    在这之前,我觉得我的技术在同龄人已经很超前了,所以有沾沾自喜的自豪感:但是现实把我狠狠的打击一番,我几乎浪费了一年的时间,为什么这么说呢?我的这个浪费指的是没有那种渴望学习,因为没有学习路径,很迷茫很迷茫,到18年,我停了手里所有的业务线,只剩下一个博客;18年的6月份开始学习前端+Java;随身带笔记本,去图书馆查资料,看视频,看纯英文官方文档;对我的提升无疑是最大的,在短短几个月时间,我认识了非常多的好友,有跟我一样学习中的,有已经工作的程序员,他们有时候讨论的问题总是是我的下一个学习知识点,在当时我的技术栈是Vue和Java;
    转折发生了,班上应该是感觉到了快毕业了(为期2年),很多开始找工作的,测试啊,运维一大堆,都想找,我也想找,但是我有点坐井观天,想去面试看看面试官问我什么,我就写好简历(18岁,大专),去投了西安3个小厂,只有一个通知我面试:
    面试跟一个好朋友一起去的,他的原生js有正规的学习过,他21岁,当兵出来的;我就去了,那是一个比较大的小区,里面就是工作室,大概就是7个人左右的小团队,进去之后,老板不在,ok我忍,一个php的老阿姨(20出头吧)来跟我聊了一下,我就跟他说,简单的介绍了一下自己,我还以为他要问原生js的一些知识点或者vue的hook,或者通信协议之类的等等,结果什么都没问,说:“我们最近有一个项目是vue的,所以想找一个vue有经验的带带我们,我们也在学习” , 我懵了,朋友也懵了,这算什么?逗我吗?然后又问我:“会php吗?” 我说:“学过2天,但是如果需要这个的话,我可以一周上手一下框架快速学习一下” 她说:“你只会java是吧?” 我说:“是的” 她说:“nuxt框架会吗” (她当时说的是读的英文字母拼起来的) 觉得好不专业,我说我会,昨天还看了一些文档。 然后她又想了一下:“她说今天早上来了2个前端的再等通知,说简历先放在我这里,有实习机会的话就给我说” (百分之99凉了) 我觉得这次面试的尴尬有几个原因:“准备太仓促,那个时候才17岁,不能录用,简历太草率,项目经验没有写全等很多原因” 这次面试对我的帮助很大,我找到了方向,出了那个大门之后,我心中的自信伴随着复仇之火又起来了,接下来的2个月我学习了很多东西,也安排了明年和过年的计划。

    这两天解决了2天的bug,关于java的,老师也束手无策,我已经再崩溃的边缘,今天写这个文章是要警醒我自己,不能放弃任何一件事情,年龄虽小,可以用技术征服,但是心智小,是真的结束了。

    很久没更新了,最近写了很多笔记,读者可以下载印象笔记,可以分享出来大家一起研究一下。

    github地址:https://github.com/1018715564
    知乎:@胖版吴彦祖
    wechat:meng99huan

    QQ截图20181115232109.png
    触了很久的vue,也做了几个项目,对于vue这款框架,我们对此非常认可,但是我们也要正确的看待它的缺点,它属于渐进式框架,非常轻量级,也非常适合做spa单页应用,但是在我们的新闻,论坛,商城等需要很多搜索引擎流量的一些站点,我们需要正确做好ssr渲染,能够把vue的短板弥补,为了解决这样的问题,nuxt是我们可以优先考虑的选择。

    nuxt是一个基于vue的渲染框架,它学起来非常简单,上手快,在工作中也经常用到,我们可以用一篇文章来快速的入门并且掌握项目的一些技巧。

    首先我们需要搭建nuxt的环境,node和vuecli是必不可少的.

    node和vuecli的安装我就不多说了,我们直接安装nuxt

    输入命令:vue init nuxt/starter

    我们就可以下载模板,然后进入目录install一下就ok

    然后我们的组件和页面都在page下,我们可以更改

    pages/index.vue来输出hello world来实现热加载编译

    然后启动服务,等待打包成html : npm run dev

    然后我们会在页面上看到我们输入的

    hello world


    目录介绍

    |-- .nuxt // Nuxt自动生成,临时的用于编辑的文件,build
    |-- assets // 用于组织未编译的静态资源入LESS、SASS 或 JavaScript
    |-- components // 用于自己编写的Vue组件,比如滚动组件,日历组件,分页组件
    |-- layouts // 布局目录,用于组织应用的布局组件,不可更改。
    |-- middleware // 用于存放中间件
    |-- pages // 用于存放写的页面,我们主要的工作区域
    |-- plugins // 用于存放JavaScript插件的地方
    |-- static // 用于存放静态资源文件,比如图片
    |-- store // 用于组织应用的Vuex 状态管理。
    |-- .editorconfig // 开发工具格式配置
    |-- .eslintrc.js // ESLint的配置文件,用于检查代码格式
    |-- .gitignore // 配置git不上传的文件
    |-- nuxt.config.json // 用于组织Nuxt.js应用的个性化配置,已覆盖默认配置
    |-- package-lock.json // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
    |-- package-lock.json // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
    |-- package.json // npm包管理配置文件


    常用配置选项

    我们在开发中经常会遇到端口被占用的情况,这种情况我们可以通过packge.json对端口和ip进行更改。

    "config":{
    "nuxt":{
      "host":"127.0.0.1",
      "port":"1818"
    }

    }

    在开发我们的多页应用的时候,经常会有一些公用样式来约束我们的标签,我们可以通过一个公共的css来控制样式,我们可以对/assets/css/normailze.css下进行配置

    (以下说明来自技术胖博客:http://jspang.com)对webpack设置的说明

    配置webpack的loader

    在nuxt.config.js里是可以对webpack的基本配置进行覆盖的,比如现在我们要配置一个url-loader来进行小图片的64位打包。就可以在nuxt.config.js的build选项里进行配置。

    build: {

    loaders:[
      {
        test:/\.(png|jpe?g|gif|svg)$/,
        loader:"url-loader",
        query:{
          limit:10000,
          name:'img/[name].[hash].[ext]'
        }
      }
    ],
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }

    }


    nuxt对我们操作路由提供了很大的帮助,它实现了自动装配路由的强大功能,我们只需要按照它的规则来写代码,就可以省配置路由的环节

    简要说明以下,nuxt是以目录来做路由的基线的,什么意思呢,大白话来说就是我们在pages目录下建立一个目录为news,在news目录下

    建立index.vue,在这个组件中我们就可以通过/news来访问这个组件,那么对于路由之间的参数传递我们该怎么操作呢?

    路由配置

    我们可以通过点击这里跳转到首页

    nuxt是不太建议我们拿a标签进行链接跳转,他们提供这样的组件来让我们使用,想必是对nuxt更友好,所以我们经常用nuxt-link来做跳转

    这个name就是文件夹名字,它会自动找这个文件夹下的index.vue来展示出来,路由的参数就是可以这样写:

    params是一个对象,我们可以在里面同时传入多个参数,在目标组件通过$route.params.具体的键就可以取到对应的值。


    nuxt的动态路由和参数校验

    我们在nuxt中定义动态路由,通常是以下划线结尾的组件,我们在news文件夹下建立_id.vue的组件
    然后在这个组件还是用相同的方法来接受参数。

    然后我们更改一下news/index.vue

    <template>

    News Index page

    NewsID:{{$route.params.newsId}}

    然后可以看到可以正常接受参数,那我们可以进行对这个参数的校验,我们拥有一个方法

    validate ({ params }) {

    // Must be a number
    return /^\d+$/.test(params.id)

    }

    我们利用这个正则可以对id这个参数进行校验,如果不是数字就会被驳回,页面会显示404页面。


    路由动画效果

    我们如何通过nuxt来实现路由之间切换并且带有动画呢?

    全局动画

    我们在assets/css下建立main.css

    在这个css中我们写一些样式

    .page-enter-active, .page-leave-active {
        transition: opacity 2s;
    }
    .page-enter, .page-leave-active {
        opacity: 0;
    }
    

    必须按照这样写,前缀务必是.page,然后我们让这个链接定义nuxt.config.js中即可

    css:['assets/css/main.css']

    然后刷新页面,我们会看到一个隐藏显示过渡的效果。
    如果你没有看到效果,得要改成

    这就是全局动画的使用

    而我们的局部动画,是针对局部的组件切换的动画。

    我们只需要更改刚刚写的css,page改成随意的名字,然后在组件中定义

    transition:'你定义的名字'

    然后就会让这个组件有效果。


    我们做多页应用经常遇到一些公共的内容,比如大标题等,我们可以通过Nuxt的默认模版和默认布局来实现
    它们的区别就是一个需要重启服务器,一个不需要,一个是公用的,一个是每个组件需要引入,复杂程度不一样

    Nuxt的默认模版和默认布局

    首先我们说默认模板,默认模板只需要在根目录定义一个app.html即可

       <!DOCTYPE html>
    <html lang="en">
    <head>
       {{ HEAD }}
    </head>
    <body>
        <p>因卓诶</p>
        {{ APP }}
    </body>
    </html>
    

    这样每个页面都可以显示因卓诶,需要重启服务器,这就是默认模板,那我们的默认布局就比较麻烦了。

        <template>
      <div>
        <p>因卓诶2</p>
        <nuxt/>
      </div>
    </template>
    

    <nuxt/>中就是内容,这样这个组件就有默认的布局,我们可以根据不同的业务需求来更改我们的代码,但是个人不建议

    总结:要区分默认模版和默认布局的区别,模版可以订制很多头部信息,包括IE版本的判断;模版只能定制