精华内容
下载资源
问答
  • Vue 3 源码公布

    千次阅读 2019-10-06 23:26:15
    10 月 5 日凌晨,Vue.js 框架的作者兼核心开发者尤雨溪公布了尚处于 Pre-Alpha ...作者表示,Vue 3 主要的架构改进、优化和新功能均已完成,剩下的主要任务是完成一些 Vue 2 现有功能的移植。 稳定版的具体发布时间...

    10 月 5 日凌晨,Vue.js 框架的作者兼核心开发者尤雨溪公布了尚处于 Pre-Alpha 状态的 Vue 3 源码(https://github.com/vuejs/vue-next)。

    (说学不动的童鞋抓紧剩余的国庆假期撸一遍源码吧 : D)

    作者表示,Vue 3 主要的架构改进、优化和新功能均已完成,剩下的主要任务是完成一些 Vue 2 现有功能的移植。

    稳定版的具体发布时间尚未提及,不过根据 Vue 在 GitHub repo 公开展示的 Roadmap,后面应该还会发布 Alpha(计划于 Q4 发布)、Beta 等版本,所以至少要等到 2020 年第一季度才有可能发布 3.0 稳定版。

    尤雨溪在去年发表的"Vue 3.0 Updates"主题演讲中曾强调过 Vue 3 包含的五个关键变化:

    1. 速度
    2. 体积
    3. 可维护性
    4. 面向原生
    5. 易用性

    下面了解一下针对 Vue 3 计划并已实现的主要架构改进和新功能:

    • 编译器(Compiler)

      • 使用模块化架构
      • 优化 "Block tree"
      • 更激进的 static tree hoisting 功能
      • 支持 Source map
      • 内置标识符前缀(又名 "stripWith")
      • 内置整齐打印(pretty-printing)功能
      • 移除 source map 和标识符前缀功能后,使用 Brotli 压缩的浏览器版本精简了大约 10KB
    • 运行时(Runtime)

      • 速度显著提升
      • 同时支持 Composition API 和 Options API,以及 typings
      • 基于 Proxy 实现的数据变更检测
      • 支持 Fragments
      • 支持 Portals
      • 支持 Suspense w/ async setup()

    最后,还有一些 2.x 的功能尚未移植过来:

    • 服务器端渲染
    • <keep-alive>
    • <transition>
    • Compiler DOM-specific transforms
      • v-on DOM 修饰符
      • v-model
      • v-text
      • v-pre
      • v-once
      • v-html
      • v-show

    对了,还有与浏览器兼容性方面的问题,虽然去年尤雨溪曾提出会支持 IE11,但目前发布的 Pre-Alpha 版本打包后的代码是 ES2015+,并且【尚未】支持 IE11。

    至于与旧版本的兼容情况,因为 Vue 3.0 是主要版本,所以会包含一些重大变更。不过,开发组会非常重视兼容性问题,他们也将尽快开始传达这些重大变更,并做了这样的保证:除了渲染函数 API 和作用域插槽语法之外的所有内容都将保持不变,或者通过兼容性构建让其与 2.x 保持兼容。

    总的来说,Vue 3.0 虽然会对顶级 API 进行重大的修整,但依然会保持与 2.x 的兼容。此外,2.x 的最后一个次要版本将成为 LTS,并在 3.0 发布后继续享受 18 个月的 bug 和安全修复更新。

    展开全文
  • (说学不动的童鞋抓紧剩余的国庆假期撸一遍源码吧 : D)作者表示,Vue 3 主要的架构改进、优化和新功能均已完成,剩下的主要任务是完成一些 Vue 2 现有功能的移植。稳定版的具体发布时间尚未提及,不过根...

    10 月 5 日凌晨,Vue.js 框架的作者兼核心开发者尤雨溪公布了尚处于 Pre-Alpha 状态的 Vue 3 源码(https://github.com/vuejs/vue-next)。

    68bfdf3476ef0c6acd06a67b23f67ce1.gif

    (说学不动的童鞋抓紧剩余的国庆假期撸一遍源码吧 : D)

    作者表示,Vue 3 主要的架构改进、优化和新功能均已完成,剩下的主要任务是完成一些 Vue 2 现有功能的移植。

    稳定版的具体发布时间尚未提及,不过根据 Vue 在 GitHub repo 公开展示的 Roadmap,后面应该还会发布 Alpha(计划于 Q4 发布)、Beta 等版本,所以至少要等到 2020 年第一季度才有可能发布 3.0 稳定版。

    68bfdf3476ef0c6acd06a67b23f67ce1.gif

    尤雨溪在去年发表的"Vue 3.0 Updates"主题演讲中曾强调过 Vue 3 包含的五个关键变化:

    速度

    体积

    可维护性

    面向原生

    易用性

    68bfdf3476ef0c6acd06a67b23f67ce1.gif

    下面了解一下针对 Vue 3 计划并已实现的主要架构改进和新功能:

    编译器(Compiler)

    使用模块化架构

    优化 "Block tree"

    更激进的 static tree hoisting 功能

    支持 Source map

    内置标识符前缀(又名 "stripWith")

    内置整齐打印(pretty-printing)功能

    移除 source map 和标识符前缀功能后,使用 Brotli 压缩的浏览器版本精简了大约 10KB

    运行时(Runtime)

    速度显著提升

    同时支持 Composition API 和 Options API,以及 typings

    基于 Proxy 实现的数据变更检测

    支持 Fragments

    支持 Portals

    支持 Suspense w/ async setup()

    最后,还有一些 2.x 的功能尚未移植过来:

    服务器端渲染

    Compiler DOM-specific transforms

    v-on DOM 修饰符

    v-model

    v-text

    v-pre

    v-once

    v-html

    v-show

    对了,还有与浏览器兼容性方面的问题,虽然去年尤雨溪曾提出会支持 IE11,但目前发布的 Pre-Alpha 版本打包后的代码是 ES2015+,并且【尚未】支持 IE11。

    68bfdf3476ef0c6acd06a67b23f67ce1.gif

    至于与旧版本的兼容情况,因为 Vue 3.0 是主要版本,所以会包含一些重大变更。不过,开发组会非常重视兼容性问题,他们也将尽快开始传达这些重大变更,并做了这样的保证:除了渲染函数 API 和作用域插槽语法之外的所有内容都将保持不变,或者通过兼容性构建让其与 2.x 保持兼容。

    总的来说,Vue 3.0 虽然会对顶级 API 进行重大的修整,但依然会保持与 2.x 的兼容。此外,2.x 的最后一个次要版本将成为 LTS,并在 3.0 发布后继续享受 18 个月的 bug 和安全修复更新。

    展开全文
  • ├─public (发布模板) └─src (源码包) ├─api (向后台发送ajax的封装层) ├─assets (静态文件) ├─components(组件) ├─router (前端路由) ├─store (vuex 状态管理仓) ├─style ...
  • ├─public (发布模板) └─src (源码包) ├─api (向后台发送ajax的封装层) ├─assets (静态文件) ├─components(组件) ├─router (前端路由) ├─store (vuex 状态管理仓) ├─style ...
  • Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中的痛苦,例如: 。 。 用于和存储的多个后端。 富有表现力,直观的 。 数据库不可知。 。 。 Laravel易于访问,功能强大,并提供大型,...
  • gopub(基于vue.js元素框架+ golang beego框架开发)是一个基于运维场景设计的企业级运维发布系统。配置简单,功能完善,界面流畅,开箱即用!支持git,jenkins版本管理,支持各种网络代码发布,一键完成Golang,...
  • 分页参数的使用列表分页-页码处理文章标签列表优化并行异步任务标签列表链接和数据导航栏-业务介绍导航栏-展示状态处理导航栏-标签高亮及链接导航栏-用户关注的文章列表统一设置用户Token文章发布时间格式化处理文章...

    11.4 首页

    公共文章列表

    在这里插入图片描述

    请求方法:GET

    请求地址:/api/articles

    查询参数:

    • 按标签筛选
      • ?tag=AngularJS
    • 按作者筛选
      • ?author=jake
    • 按用户筛选
      • ?favorited=jake
    • 文章分页数(默认20)
      • ?limit=20
    • 文章偏移/跳跃数(默认0)
      • ?offset=0

    api/article.js

    import request from '@/utils/request'
    
    // 获取公共文章列表
    export const getArticles = params => {
      return request({
        method: 'GET',
        url: '/api/articles',
        params
      })
    }
    

    pages/home/index.vue

    import { getArticles } from '@/api/article'
    
    export default {
      name: 'HomeIndex',
      async asyncData () {
        const { data } = await getArticles()
        console.log(data)
      }
    }
    

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

    export default {
      name: 'HomeIndex',
      async asyncData () {
        const { data } = await getArticles()
        return {
          articles: data.articles,
          articlesCount: data.articlesCount
        }
      }
    }
    

    在这里插入图片描述

    遍历数据:

    <div
      class="article-preview"
      v-for="article in articles"
      :key="article.slug"
    >
      <div class="article-meta">
        <!-- <a href="profile.html"><img src="http://i.imgur.com/Qr71crq.jpg" /></a> -->
        <nuxt-link :to="{
          name: 'profile',
          params: {
            username: article.author.username
          }
        }">
          <img :src="article.author.image" />
        </nuxt-link>
        <div class="info">
          <!-- <a href="" class="author">Eric Simons</a> -->
          <nuxt-link class="author" :to="{
            name: 'profile',
            params: {
              username: article.author.username
            }
          }">
            {{ article.author.username }}
          </nuxt-link>
          <span class="date">{{ article.createdAt }}</span>
        </div>
        <button class="btn btn-outline-primary btn-sm pull-xs-right"
          :class="{
              active: article.favorited
            }">
          <i class="ion-heart"></i> {{ article.favoritesCount }}
        </button>
      </div>
      <!-- <a href="" class="preview-link"> -->
      <nuxt-link 
        class="preview-link" 
        :to="{
          name: 'article',
          params: {
            slug: article.slug
          }
        }">
        <h1>{{ article.title }}</h1>
        <p>{{ article.description }}</p>
        <span>Read more...</span>
      <!-- </a> -->
      </nuxt-link>  
    </div>
    

    列表分页-分页参数的使用

    pages/home/index.vue

    export default {
      name: 'HomeIndex',
      async asyncData () {
        const page = 1
        const limit = 10
        const { data } = await getArticles({
          // 文章分页数(默认20)
          limit,
          // 文章偏移/跳跃数(默认0)
          offset: (page - 1) * limit
        })
        return {
          articles: data.articles,
          articlesCount: data.articlesCount
        }
      }
    }
    

    列表分页-页码处理

    添加页码,页码改变获取对应页码的数据:pages/home/index.vue

    <!-- 分页列表 -->
    <nav>
      <ul class="pagination">
    
        <li class="page-item active">
    
          <a class="page-link ng-binding" href="">1</a>
    
        </li>
      </ul>
    </nav>
    

    在这里插入图片描述

    export default {
      name: 'HomeIndex',
      async asyncData ({ query }) {
        const page = Number.parseInt(query.page || 1)
        const limit = 10
        const { data } = await getArticles({
          // 文章分页数(默认20)
          limit,
          // 文章偏移/跳跃数(默认0)
          offset: (page - 1) * limit
        })
        return {
          articles: data.articles,
          articlesCount: data.articlesCount,
          page,
          limit
        }
      },
      computed: {
        // 总页码
        totalPage () {
          return Math.ceil(this.articlesCount / this.limit)
        }
      }
    }
    
    <!-- 分页列表 -->
    <nav>
      <ul class="pagination">
    
        <li 
          class="page-item"
          :class="{
            active: item === page
          }"
          v-for="item in totalPage"
          :key="item"  
        >
    
          <!-- 默认query的改变不会调用asyncData方法。
          如果要监听这个行为,可以设置应通过页面组建的watchQuery参数监听参数 -->
          <nuxt-link 
            class="page-link" 
            :to="{
              name: 'home',
              query: {
                page: item
              }
            }"
          >{{ item }}</nuxt-link>
    
        </li>
      </ul>
    </nav>
    
    export default {
      ...
      watchQuery:['page']
    }
    

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

    文章标签列表

    在这里插入图片描述

    请求方法:GET

    请求地址:/api/tags

    ap/tag.js

    import request from '@/utils/request'
    
    // 获取文章标签列表
    export const getTags = () => {
      return request({
        method: 'GET',
        url: '/api/tags',
      })
    }
    

    pages/home/index.vue

    ...
    import { getTags } from '@/api/tag'
    
    export default {
      name: 'HomeIndex',
      async asyncData ({ query }) {
        ...
        const { data: tagData } = await getTags()
        return {
          ...
          tags: tagData.tags
        }
      },
      ...
    }
    
    <div class="col-md-3">
      <div class="sidebar">
        <p>Popular Tags</p>
    
        <div class="tag-list">
          <a 
            href="" 
            class="tag-pill tag-default"
            v-for="item in tags"
            :key="item"
          >{{ item }}</a>
        </div>
      </div>
    </div>
    

    在这里插入图片描述

    优化并行异步任务

    在这里插入图片描述

    对于以上两个异步操作:获取文章列表和获取标签列表。它们的执行顺序是先拿到文章列表,再去请求获取标签列表,是串行的方式。

    对于多个异步任务,它们之间并没有依赖关系,因此我们可以将多个异步任务并发执行。通过并行来提高获取请求加载的速度。

    pages/home/index.vue

    export default {
      name: 'HomeIndex',
      async asyncData ({ query }) {
        const page = Number.parseInt(query.page || 1)
        const limit = 10
        const [ articleRes, tagRes ] = await Promise.all([
          getArticles({
            limit, // 文章分页数(默认20)
            offset: (page - 1) * limit // 文章偏移/跳跃数(默认0)
          }),
          getTags()
        ])
    
        const { articles, articlesCount } = articleRes.data
        const { tags } = tagRes.data
    
        return {
          articles,
          articlesCount,
          tags,
          page,
          limit
        }
      },
      ...
    }
    

    优化前:4.37s - 7.42s 不等
    在这里插入图片描述
    在这里插入图片描述

    优化后:2.68s - 3.98s 不等
    在这里插入图片描述

    在这里插入图片描述

    经过多次尝试后,发现优化后的代码整体比优化前要快一些(网络对速度有一定影响),甚至有时候不到两秒就可以完成。

    标签列表链接和数据

    pages/home/index.vue

    <div class="col-md-3">
      <div class="sidebar">
        <p>Popular Tags</p>
    
        <div class="tag-list">
          <nuxt-link 
            :to="{
              name: 'home',
              query: {
                tag: item
              }
            }" 
            class="tag-pill tag-default"
            v-for="item in tags"
            :key="item"
          >{{ item }}</nuxt-link>
        </div>
      </div>
    </div>
    
    watchQuery:['page', 'tag'],
    

    对应数据:

    getArticles({
      limit, // 文章分页数(默认20)
      offset: (page - 1) * limit, // 文章偏移/跳跃数(默认0)
      tag: query.tag // 按标签筛选
    })
    

    解决标签和分页共存问题:

    <!-- 分页列表 -->
    <nav>
      <ul class="pagination">
    
        <li 
          class="page-item"
          :class="{
            active: item === page
          }"
          v-for="item in totalPage"
          :key="item"  
        >
    
          <!-- 默认query的改变不会调用asyncData方法。
          如果要监听这个行为,可以设置应通过页面组建的watchQuery参数监听参数 -->
          <nuxt-link 
            class="page-link" 
            :to="{
              name: 'home',
              query: {
                page: item,
                tag: $route.query.tag
              }
            }"
          >{{ item }}</nuxt-link>
    
        </li>
      </ul>
    </nav>
    <!-- /分页列表 -->
    

    在这里插入图片描述

    导航栏-展示状态处理

    补全三个导航栏,示例:
    在这里插入图片描述

    pages/home/index.vue

    <div class="feed-toggle">
      <ul class="nav nav-pills outline-active">
        <li class="nav-item">
          <a class="nav-link disabled" href="">Your Feed</a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="">Global Feed</a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="">#标签</a>
        </li>
      </ul>
    </div>
    

    业务逻辑:

    • Your Feed:只有在登录状态下才被展示
    • Global Feed:不论登录与否均被展示
    • #标签:只有在点击某个标签才被展示,切换回Your Deed或Global Feed后不再展示
    import { mapState } from 'vuex'
    
    export default {
      name: 'HomeIndex',
      async asyncData ({ query }) {
        ...
        const { tag } = query
        const [ articleRes, tagRes ] = await Promise.all([
          getArticles({
            ...
            tag // 按标签筛选
          }),
          ...
        ])
    
        ...
    
        return {
          ...
          tag
        }
      },
      computed: {
        ...mapState(['user']),
        ...
      }
    }
    
    <li v-if="user" class="nav-item">
      <a class="nav-link disabled" href="">Your Feed</a>
    </li>
    
    ...
    
    <li v-if="tag" class="nav-item">
      <a class="nav-link active" href="">#{{ tag }}</a>
    </li>
    

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

    导航栏-标签高亮及链接

    导航链接优化:pages/home/index.vue

    async asyncData ({ query }) {
      ...
    
      return {
        ...
        tab: query.tab || 'global_feed'
      }
    },
    watchQuery:['page', 'tag', 'tab'],
    ...
    
    <div class="feed-toggle">
      <ul class="nav nav-pills outline-active">
      
        <li v-if="user" class="nav-item">
          <!-- exact 精确匹配 -->
          <nuxt-link 
            class="nav-link"
            :class="{
              active: tab === 'your_feed'
            }"
            exact
            :to="{
              name: 'home',
              query: {
                tab: 'your_feed'
              }
            }"
          >Your Feed</nuxt-link>
        </li>
        
        <li class="nav-item">
          <nuxt-link 
            class="nav-link"
            :class="{
              active: tab === 'global_feed'
            }"
            exact
            :to="{
              name: 'home',
              query: {
                tab: 'global_feed'
              }
            }"
          >Global Feed</nuxt-link>
        </li>
        
        <li v-if="tag" class="nav-item">
          <nuxt-link 
            class="nav-link"
            :class="{
              active: tab === 'tag'
            }"
            exact
            :to="{
              name: 'home',
              query: {
                tab: 'tag',
                tag: tag
              }
            }"
          >#{{ tag }}</nuxt-link>
        </li>
        
      </ul>
    </div>
    

    修改分页列表,添加tab: tab

    <nuxt-link 
      class="page-link" 
      :to="{
        name: 'home',
        query: {
          page: item,
          tag: $route.query.tag,
          tab: tab
        }
      }"
    >{{ item }}</nuxt-link>
    

    修改标签列表,添加tab: 'tag'

    <div class="col-md-3">
      <div class="sidebar">
        <p>Popular Tags</p>
    
        <div class="tag-list">
          <nuxt-link 
            :to="{
              name: 'home',
              query: {
                tab: 'tag',
                tag: item
              }
            }" 
            class="tag-pill tag-default"
            v-for="item in tags"
            :key="item"
          >{{ item }}</nuxt-link>
        </div>
      </div>
    </div>
    

    导航栏-用户关注的文章列表

    在这里插入图片描述

    请求方法:GET

    请求地址:/api/articles/feed

    在这里插入图片描述

    身份验证标头:

    Authorization: Token jwt.token.here
    

    重新登录获取一个新Token:(长时间不使用会过期)

    在这里插入图片描述

    api/article.js

    ...
    
    // 获取关注的用户文章列表
    export const getFeedArticles = params => {
      return request({
        method: 'GET',
        url: '/api/articles/feed',
        // Authorization: Token jwt.token.here
        headers: {
          // 注意数据格式:Token空格数据Token
          // 先手动写死,自动处理后续介绍
          Authorization: `Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
            .eyJpZCI6MTMzMjY4LCJ1c2VybmFtZSI6InNoaWd1YW5naGFpIiwiZXhwIjoxNjE1MjgyMzcxfQ
            ._QB6VDwPXLFSa30IScJ1q5Q_1zk5FXB99OYAKU3qMW0`
        },
        params
      })
    }
    

    pages/home/index.vue

    async asyncData ({ query, store }) {
      const page = Number.parseInt(query.page || 1)
      const limit = 10
      const { tag } = query
      const tab = query.tab || 'global_feed'
      const loadArticles = store.state.user && tab === 'your_feed'
        ? getFeedArticles
        : getArticles
    
      const [ articleRes, tagRes ] = await Promise.all([
        loadArticles({
          limit, // 文章分页数(默认20)
          offset: (page - 1) * limit, // 文章偏移/跳跃数(默认0)
          tag // 按标签筛选
        }),
        getTags()
      ])
    
      const { articles, articlesCount } = articleRes.data
      const { tags } = tagRes.data
    
      return {
        articles,
        articlesCount,
        tags,
        page,
        limit,
        tag,
        tab
      }
    }
    

    在这里插入图片描述

    在这里插入图片描述

    统一设置用户Token

    接下来把手动写死的接口中数据Token的方式变成自动的,让它通过Cookie来拿到用户的Token。

    我们可以使用 axios 拦截器 的方式来实现:

    在这里插入图片描述

    // Add a request interceptor
    axios.interceptors.request.use(function (config) {
        // Do something before request is sent
        return config;
      }, function (error) {
        // Do something with request error
        return Promise.reject(error);
      });
    
    // Add a response interceptor
    axios.interceptors.response.use(function (response) {
        // Any status code that lie within the range of 2xx cause this function to trigger
        // Do something with response data
        return response;
      }, function (error) {
        // Any status codes that falls outside the range of 2xx cause this function to trigger
        // Do something with response error
        return Promise.reject(error);
      });  
    

    在这里插入图片描述

    utils/request.js

    // 请求拦截器
    // Add a request interceptor
    // 任何请求都要经过请求拦截器
    // 我们可以在请求拦截器中做一些公共的业务处理,例如统一设置 Token
    // config 包括本次请求的请求地址、方法、参数等等
    request.interceptors.request.use(function (config) {
      // 请求就会经过这里(正确)
      // Do something before request is sent
      // console.log('123')
      config.headers.Authorization = `Token 用户Token`
    
      // 返回 config 请求配置对象
      return config
    }, function (error) {
      // 如果请求失败(此时请求还没有发出去)就会进入这里
      // Do something with request error
      return Promise.reject(error)
    })
    

    此时考虑如何获取 用户Token:

    Nuxt.js 允许您在运行Vue.js应用程序之前执行js插件。这在您需要使用自己的库或第三方模块时特别有用。

    我们可以通过 插件 获取到处理之后的store上下文对象:plugins/request.js

    import axios from 'axios'
    
    // 创建请求对象
    const request = axios.create({
      baseURL: 'https://conduit.productionready.io/'
    })
    
    // 通过插件机制获取到上下文对象(query、params、req、res、app、store...)
    export default (context) => {
      console.log(context)
    }
    

    注册插件:nuxt.config.js

    module.exports = {
      ...
      
      // 注册插件
      plugins: [
        '~/plugins/request.js'
      ]
    }
    

    在这里插入图片描述

    plugins/request.js

    /**
     * 基于 axios 封装的请求模块
     */
    
    import axios from 'axios'
    
    // 创建请求对象
    export const request = axios.create({
      baseURL: 'https://conduit.productionready.io/'
    })
    
    // 通过插件机制获取到上下文对象(query、params、req、res、app、store...)
    // 插件导出函数必须作为 default 成员
    export default ({ store }) => {
      // 请求拦截器
      // Add a request interceptor
      // 任何请求都要经过请求拦截器
      // 我们可以在请求拦截器中做一些公共的业务处理,例如统一设置 Token
      // config 包括本次请求的请求地址、方法、参数等等
      request.interceptors.request.use(function (config) {
        // 请求就会经过这里(正确)
        // Do something before request is sent
        const { user } = store.state
    
        if (user && user.token){
          config.headers.Authorization = `Token ${user.token}`
        }
    
        // 返回 config 请求配置对象
        return config
      }, function (error) {
        // 如果请求失败(此时请求还没有发出去)就会进入这里
        // Do something with request error
        return Promise.reject(error)
      })
    }
    

    更改请求地址:api/[article.js, tag.js, user.js]

    import { request } from '@/plugins/request'
    

    api/article.js

    // 获取关注的用户文章列表
    export const getFeedArticles = params => {
      return request({
        method: 'GET',
        url: '/api/articles/feed',
        // Authorization: Token jwt.token.here
        // headers: {
        //   // 注意数据格式:Token空格数据Token
        //   // 先手动写死,自动处理后续介绍
        //   Authorization: `Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
        //     .eyJpZCI6MTMzMjY4LCJ1c2VybmFtZSI6InNoaWd1YW5naGFpIiwiZXhwIjoxNjE1MjgyMzcxfQ
        //     ._QB6VDwPXLFSa30IScJ1q5Q_1zk5FXB99OYAKU3qMW0`
        // },
        params
      })
    }
    

    最后删除utils/request.js文件,此时仍然可以访问Your Feed
    在这里插入图片描述

    文章发布时间格式化处理

    预期效果:

    2021-01-08T09:43:43.952Z -> January 8, 2021

    dayjs:是一个轻量的处理时间和日期的 JavaScript 库

    安装Day.js

    npm install dayjs --save
    

    通过插件来扩展Vue的资源,封装为全局过滤器来使用:plugins/dayjs.js

    import Vue from 'vue'
    import dayjs from 'dayjs'
    
    // {{ 表达式 | 过滤器 }}
    Vue.filter('date', (value, format = 'YYYY-MM-DD HH:mm:ss') => {
      return dayjs(value).format(format)
    })
    

    注册插件:nuxt.config.js

    plugins: [
      ...
      '~/plugins/dayjs.js'
    ]
    

    使用插件:pages/home/index.vue

    <span class="date">{{ article.createdAt | date }}</span>
    

    在这里插入图片描述

    参考 文档 修改为我们预期的格式:

    <span class="date">{{ article.createdAt | date('MMMM DD, YYYY') }}</span>
    

    在这里插入图片描述

    文章点赞

    最后我们来处理一下文章点赞的功能:

    在这里插入图片描述
    添加点赞:

    请求方法:POST

    请求地址:/api/articles/:slug/favorite

    删除点赞:

    请求方法:DELETE

    请求地址:/api/articles/:slug/favorite

    封装点赞功能:api/article.js

    // 添加点赞
    export const addFavorite = slug => {
      return request({
        method: 'POST',
        url: `/api/articles/${slug}/favorite`
      })
    }
    
    // 取消点赞
    export const deleteFavorite = slug => {
      return request({
        method: 'DELETE',
        url: `/api/articles/${slug}/favorite`
      })
    }
    

    pages/home/index.vue

    <button class="btn btn-outline-primary btn-sm pull-xs-right"
      :class="{
        active: article.favorited
      }"
      @click="onFavorite(article)">
      <i class="ion-heart"></i> {{ article.favoritesCount }}
    </button>
    
    import { 
      ...
      addFavorite,
      deleteFavorite
    } from '@/api/article'
    
    export default {
      methods: {
        async onFavorite (article) {
          if (article.favorited) {
            // 取消点赞
            await deleteFavorite(article.slug)
            article.favorited = false
            article.favoritesCount -= 1
          } else {
            // 添加点赞
            await addFavorite(article.slug)
            article.favorited = true
            article.favoritesCount += 1
          }
        }
      }
    }
    

    在这里插入图片描述

    但是这里还有一个小问题:如果网络比较慢,用户频繁点击按钮,可能会导致期间来回处理导致出现错误。

    因此我们应该在请求期间禁用此按钮:

    async asyncData ({ query, store }) {
      ...
      
      // 默认未禁用
      articles.forEach(article => article.favoriteDisabled = false)
    },
    ...
    methods: {
      async onFavorite (article) {
        article.favoriteDisabled = true
        if (article.favorited) {
          // 取消点赞
          await deleteFavorite(article.slug)
          article.favorited = false
          article.favoritesCount -= 1
        } else {
          // 添加点赞
          await addFavorite(article.slug)
          article.favorited = true
          article.favoritesCount += 1
        }
        article.favoriteDisabled = false
      }
    }
    
    <button class="btn btn-outline-primary btn-sm pull-xs-right"
      :class="{
        active: article.favorited
      }"
      @click="onFavorite(article)"
      :disabled="article.favoriteDisabled">
      <i class="ion-heart"></i> {{ article.favoritesCount }}
    </button>
    

    至此,首页部分就以实现完毕

    展开全文
  • 通过Jenkins发布一个VUE项目到远程服务器 配置 1.Jenkins新建Item 2.新建一个任务 3.任务/项目描述 4.源码配置 Credentials添加 4.配置构建环境 5.构建后操作(SSH 服务器配置请看第6步) 6.SSH服务器配置 最...

    Jenkins自动化部署VUE项目

    前言

    通过Jenkins发布一个VUE项目到远程服务器

    配置

    1.Jenkins新建Item
    在这里插入图片描述
    2.新建一个任务
    在这里插入图片描述
    3.任务/项目描述
    在这里插入图片描述
    4.源码配置
    在这里插入图片描述
    Credentials添加
    在这里插入图片描述
    4.配置构建环境
    在这里插入图片描述
    5.构建后操作(SSH 服务器配置请看第6步)
    在这里插入图片描述6.SSH服务器配置
    在这里插入图片描述
    在这里插入图片描述最下面,新增
    在这里插入图片描述
    在这里插入图片描述保存即可
    6.项目构建
    在这里插入图片描述
    7.服务器项目路径
    在这里插入图片描述
    8.通过nginx的conf配置对项目的代理
    在这里插入图片描述
    9.重启nginx即可访问
    sbin下面 ./nignx -s reload
    在这里插入图片描述

    展开全文
  • 基于RBAC模型权限控制的中小型应用的基础开发平台,前拆分,替代采用django + django-rest-framework,前端采用vue + ElementUI,移动端采用uniapp + uView(可发布h5和小程序)。 JWT认证,可使用simple_history...
  • Vue.js用于前端相关任务 所有那些美丽的风格都在香草CSS中 Socket.io的所有实时功能 产品特点 实时投票 实时评论 查看热门民意调查,近期民意调查 发布和管理您的民意调查 未来推荐 匿名投票 ip地址而不是电子邮件...
  • Laravel减轻了许多Web项目中使用的常见任务,从而减轻了开发过程中的痛苦,例如: 。 。 用于和存储的多个后端。 富有表现力,直观的 。 数据库不可知。 。 。 Laravel易于访问,功能强大,并提供大型,强大的应用...
  • 基于springboot + vue + elementui的办公自动化系统设计(前端代码在oa文件夹里) 系统主要功能: 1,统一的信息发布平台:公告栏,公司活动,项目进度,公司周报 2,统一的文件管理平台:收文管理,发文管理。文件...
  • 前言 基于开源项目 ,扩展开发添加新业务功能 平台简介 前端采用Vue,Element UI。 初步采用Spring Boot,...定时任务:在线(添加,修改,删除)任务调度包含执行结果日志。 代码生成:前代码代码的生成(java,h
  • win,linux,mac均已发布,再接下来要整RSS订阅功能,这是个大项目了。。。。 2021/02/23 1. Add 手机登录增加新加坡,立陶宛区号 2. Add 离线任务显示状态码 3. Fix 离线任务超过1998条时返回的离线任务顺序错乱的...
  • 全程干货满满,让你在掌握 Vue 3 源码后具有实战开发能力,轻松搞定开发任务与面试。 从官方宣布 Vue3 开发就开始关注,一直到 2020 年 9 月 18 日正式版发布才去深入了解它,这一次的版本简直就是 “颠覆” 来形容...
  • HQChart使用教程73-使用Vue3.0创建HQChart图形序预备知识获取dom元素mountedmethods成员变量结束语demo源码App.vue交流QQ群: 950092318HQChart代码地址个人爱好(模型/摄影) 序 听说Vue3.0发布了, 群里的很多小伙伴...
  • gulp 进入开发模式,同时打开 watch 和 server任务 gulp build 编译压缩代码 分支说明 master 主分支,正式发布的代码才会进入master分支 build 包含全部编译后代码的分支,和 master 分支同步,但是会包含 ...
  • 基于go cron的可视化调度轻量级级调度框架,支持DAG任务依赖,支持bash命令,前端及进行编译完成(基于packr2)后仅一个二进制文件,轻松部署 地址 环境 初步 去1.13+ -静态文件打包 定时调度器 前端 Vue 使用 直接...
  • 一年前2.0还没发布的时候阅读过vue 1.x的源码,对vue的原理有了解,项目开发中遇到的所有问题我都有信心能解决掉</li><li>调研了我们团队的成员,大部分都使用过vue,对vue多少都有过开发...
  • <p>vue.js 采用数据劫持结合发布-订阅模式,通过 Object.defineproperty 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发响应的监听回调 <h2>2. computed 的实现原理 <p>computed 本质是一个惰性...
  • arena_platform-源码

    2021-04-12 15:41:06
    Spug是一款使用Python+Flask+Vue+Element组件开发的开源运维管理系统,系统前后端分离,帮助中小型企业完成主机、任务发布部署、配置文件、监控、报警等管理。 Demo演示地址: Demo账号密码:<
  • vue接入腾讯实时音视频trtc-js-sdk(web版)

    万次阅读 多人点赞 2020-02-18 12:34:18
    随着疫情的发生,音视频实时通话的需求,与日剧增,公司也比较关注,也发布了这方面的需求,接到任务,平时也没做过,想着平时微信用的比较多,对腾讯的即时通讯也是比较认可的,就尝试去腾讯云找是否有这方面的sdk...
  • 该系统支持文字图片,视频的发布,拥有多种交互模式,点赞,评论,关注,收藏功能,存在主题,社区等模式。该系统运用了单页,Websocket,Vue,Vant等技术和框架,更好的体验。 技术栈 PHP7.3 旋风4.5 EasySwoole...
  • bot是作为Taskcluster任务运行的Python脚本,报告在分析器任务中发现的问题, backend是Django网络API,用于存储机器人检测到的问题, frontend是一个管理前端(在Vue.js中),显示有关分析和问题的详细信息, ...
  • 发布新选择器相关的任务,问题和讨论可通过进行跟踪。 入门 运行以下命令以使代码启动并在您的计算机上运行: # installs dependencies $ npm install # Builds and serves assets with hot-reload $ npm run ...
  • 由于最近公司项目太忙,没来得及整理说明文档,等过完元旦我便开始陆续整理发布说明文档;有网友私信让我建一个群大家一起合力把这个框架完善。确实,这款框架本身就是开源框架,既然正主没有维护了,那我们就一起...
  • │ │ ├─mate-starter-gray -- 封装灰度发布基础模块 │ │ ├─mate-starter-elasticsearch -- 封装ElasticSearch模块 │ │ ├─mate-starter-oss -- 封装oss存储基础模块,支持阿里云、七牛云、minio等 │ │ ├...
  • Vue 入门系列 25 篇,已完结。 微信小程序入门系列 4 篇,已完结。 React Native 入门系列 2 篇,已完结。 Node.js 入门系列 30 篇,已完结。 Express 入门系列 6 篇,已完结。 rc-form 源码解读 1 篇,已完结。 ...
  • 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 系统接口:根据业务代码自动生成相关的api接口文档。 服务监控:监视当前系统...
  • 基于SpringCloud(Hoxton.SR7) + SpringBoot(2.2.9.RELEASE) 的 SaaS 型微服务快速开发平台,具备用户管理、资源权限管理、网关统一鉴权、Xss 防跨站攻击、自动代码生成、多存储系统、分布式事务、分布式定时任务等多...

空空如也

空空如也

1 2 3
收藏数 44
精华内容 17
热门标签
关键字:

vue任务发布源码

vue 订阅