环境

IDE: WebStorm 2019.1.4
系统: Mac OS X 10.15.4
VueJs: 2.6.11
Vue-cli: 4.2.2

前言

  最近一直在忙毕设,前端终于还是对我这个Java小后端下手了o(╥﹏╥)o 可算明白前端大佬们有多不容易。 项目需要用到VueJs,于是在看了半天vue文档后写个小Demo。

效果图

开干

第一步,创建项目环境

WebStorm新建Project -> EmptyProject

终端下使用"vue create"创建vue脚手架工程(不同版本命令可能不同)

项目名称不能含有大写字母

选择default

终端cd到vue-cli文件夹下,运行"npm run serve",vue-cli3.0版本以下,应该默认是"npm run dev",详见"package.json"

点击链接

第二步,敲哩个敲

好了,开始敲代码o( ̄︶ ̄)o

新建组件文件

components 文件夹右键 -> new -> Vue component -> IntroductionPanel。
为什么是"Introduction"? 因为这是用来引导用户注册的。

接着修改 App.vue 文件的 <template><script> 节点,把原来的组件删了,把自定义的 IntroductionPanel 放进来。

<template>
  <IntroductionPanel></IntroductionPanel>
</template>

<script>
import IntroductionPanel from "./components/IntroductionPanel"

export default {
  name: 'App',
  components: {
    IntroductionPanel
  }
}
</script>

当然也可以直接修改 main.js 编辑应用的入口

编写代码

一、 在 IntroductionPanel.vue 文件的 <template> 节点下创建一个 <div> 用来装载所有的组件。

<template>
        <div class="introduction introduction-panel">

        </div>
</template>

二、 在 introduction-panel 下创建 introduction-wrapper 用来装载上面的两根绳子以及下面的面板;创建 introduction-trigger 充当右边的绳索开关。

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper">

        </div>>
        <div class="introduction introduction-trigger">

        </div>
    </div>
</template>

三、把上面的两根绳子做出来,这两根绳子实际上是一个 div 的两边。

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper">
            <div class="introduction rope"></div>
        </div>
        <div class="introduction introduction-trigger">

        </div>
    </div>
</template>

IntroductionPanel.vue<style scoped> 节点下,给绳子添加样式。

/*牵引绳*/
.introduction.rope{
    width: 200px;
    height: 100px;
    border-left: 5px rgba(0,129,198,.8) solid;
    border-right: 5px rgba(0,129,198,.8) solid;
    box-shadow: 0px 0px 5px 0px rgba(13,148,225,.8), 0px 0px 5px 0px rgba(13,148,225,.8) inset;
}

四、创建面板 introduction-bar

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper">
            <div class="introduction rope"></div>
            <div class="introduction introduction-bar"></div>
        </div>
        <div class="introduction introduction-trigger">

        </div>
    </div>
</template>
/*内容面板*/
.introduction.introduction-bar{
    width: 500px;
    height: 600px;
    color: rgba(13,148,225,.9);/*内容颜色,蓝色加透明*/
    border-radius: 5px;/*圆角*/
    background-color: rgba(254, 253, 255, 0.9);/*背景色,白色加透明*/
    box-shadow: 0 7px 25px rgba(0, 0, 0, .3);/*阴影*/
}

五、此时左边部分已经完成

需要进行优化,给这两个元素设置 margin: 0 auto; 并给父元素设置 text-align: center 使得这两个元素保持居中。


/*左侧部分*/
.introduction.introduction-wrapper{
    width: 100%;
    text-align: center;
}

/*牵引绳*/
.introduction.rope{
    width: 200px;
    height: 100px;
    border-left: 5px rgba(0,129,198,.8) solid;
    border-right: 5px rgba(0,129,198,.8) solid;
    box-shadow: 0px 0px 5px 0px rgba(13,148,225,.8), 0px 0px 5px 0px rgba(13,148,225,.8) inset;
    margin: 0 auto;
}

/*内容面板*/
.introduction.introduction-bar{
    width: 500px;
    height: 600px;
    margin: 0 auto;
    color: rgba(13,148,225,.9);/*内容颜色,蓝色加透明*/
    border-radius: 5px;/*圆角*/
    background-color: rgba(254, 253, 255, 0.9);/*背景色,白色加透明*/
    box-shadow: 0 7px 25px rgba(0, 0, 0, .3);/*阴影*/
}

这时可以发现两个元素已经居中,但是上面的 div 露出了上下两条边,不好看,需要调整这两个元素的高度。

/*内容面板*/
.introduction.introduction-bar{
    width: 500px;
    height: 600px;
    margin: 0 auto;
    color: rgba(13,148,225,.9);/*内容颜色,蓝色加透明*/
    top: -5px;
    position: relative;
    border-radius: 5px;/*圆角*/
    background-color: rgba(254, 253, 255, 0.9);/*背景色,白色加透明*/
    box-shadow: 0 7px 25px rgba(0, 0, 0, .3);/*阴影*/
}

效果如下:

绳子的上面暂不处理

六、下面开始做右边的开关 introduction-trigger

introduction-trigger 包括上面的绳子以及下面的绳结(忽略绳结上的箭头):

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper">
            <div class="introduction rope"></div>
            <div class="introduction introduction-bar"></div>
        </div>
        <div class="introduction introduction-trigger">
            <div class="introduction trigger-rope"></div>
            <div class="introduction trigger-point">

            </div>
        </div>
    </div>
</template>
/*开关整体*/
.introduction.introduction-trigger{
    left: 80%;
}

/*开关的绳子*/
.introduction.trigger-rope{
    position: relative;
    width: 5px;
    height: 300px;
    margin: 0 auto;
    background-color: rgba(0,129,198,.8);
    box-shadow: 0px 0px 5px 0px rgba(13,148,225,.8);
}

/*开关的绳结*/
.introduction.trigger-point{
    margin: 0 auto;
    position: relative;
    width: 25px;
    height: 60px;
    background-color: rgba(0,129,198,.9);
    box-shadow: 0px 0px 5px 0px rgba(13,148,225,.8);
    border-radius: 5px;
    text-align: center;
    cursor: pointer;
}

如上,开关的位置不正确,需要修改下 introduction-wrapperintroduction-trigger 的样式

/*开关整体*/
.introduction.introduction-trigger{
    left: 80%;
    position: absolute;
}
/*左侧部分*/
.introduction.introduction-wrapper{
    width: 100%;
    position: absolute;
    text-align: center;
}

七、这时页面框架已经完成了,接下来就是给元素添加动效。
编辑 <script>

<script>
    export default {
        name: "IntroductionPanel",
        data() {
            return {
                introduction_active: false
            }
        },
        methods: {
            changeActiveStatus(){
                this.introduction_active = !this.introduction_active;
            }
        }
    }
</script>

给组件添加状态 introdution_active 和 改变状态的方法 changeActiveStatus(), 不需要用到 Vuex
然后给元素绑定动态 Class

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper" v-bind:class="{'active':introduction_active}">
            <div class="introduction rope"></div>
            <div class="introduction introduction-bar"></div>
        </div>
        <div class="introduction introduction-trigger" v-bind:class="{'active':introduction_active}">
            <div class="introduction trigger-rope"></div>
            <div class="introduction trigger-point" @click="changeActiveStatus()">

            </div>
        </div>
    </div>
</template><template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper" v-bind:class="{'active':introduction_active}">
            <div class="introduction rope"></div>
            <div class="introduction introduction-bar"></div>
        </div>
        <div class="introduction introduction-trigger" v-bind:class="{'active':introduction_active}">
            <div class="introduction trigger-rope"></div>
            <div class="introduction trigger-point" @click="changeActiveStatus()">

            </div>
        </div>
    </div>
</template>

接下来设置元素动效前后的状态,让CSS实现动画效果,这是补间动画,AE、Flash都可以玩一哈。

/*左侧部分*/
.introduction.introduction-wrapper{
    width: 100%;
    position: absolute;
    top: -1000px;/*左侧部分一开始应该在浏览器上方,在视野之外*/
    text-align: center;
}

/*左侧变换后的位置*/
.introduction.introduction-wrapper.active{
    top: -5px;/*-5是为了遮住绳子的div的上面部分*/
}

/*开关整体*/
.introduction.introduction-trigger{
    top: 0px;/*开关一开始的高度*/
    left: 80%;
    position: absolute;
}

/*开关整体变换后的高度*/
.introduction.introduction-trigger.active{
    top: -150px;/*往浏览器上方走,相当于缩短。也可以设置仅开关上方的绳子变短*/
}

效果如下:

  可以看出效果十分生硬,这时可以使用贝塞尔曲线或者关键帧进行优化,关键帧比较麻烦,所以这里用的是贝塞尔曲线。
  神器——https://cubic-bezier.com/#.37,1.44,.57,.77 ,用这个网站可以直观地生成合适的贝塞尔曲线的函数。

  如上是网站的界面,函数的参数分别为坐标系上红球的x轴坐标、y轴坐标和蓝绿球的x轴坐标和y轴坐标。坐标系横轴为时间,纵轴为动画的 progress, 直译过来是进程、进展的意思,映射到平移上就是指移动的点到原点的偏移量。
  动图中两个方块是项目中用到的动画与线性动画的对比。动画后面具有弹跳的效果,在左上角坐标系上表现为后段往下的凹陷。动画的整体效果是元素离原点的距离越来越远,到后段反而离近一点点,然后又远离,直至到达终点。线的斜率反映运动的加速度。
  获取到合适的贝塞尔函数后应用到项目中:

.introduction{
    transition: 0.3s cubic-bezier(.37,1.44,.57,.77);
}

八、最后给绳结添加箭头指示以及提示。

<template>
    <div class="introduction introduction-panel">
        <div class="introduction introduction-wrapper" v-bind:class="{'active':introduction_active}">
            <div class="introduction rope"></div>
            <div class="introduction introduction-bar"></div>
        </div>
        <div class="introduction introduction-trigger" v-bind:class="{'active':introduction_active}">
            <div class="introduction trigger-rope"></div>
            <div class="introduction trigger-point" @click="changeActiveStatus()" v-bind:class="{'active':introduction_active}">
                <div class="arrow arrow-down"></div>
                <div class="arrow arrow-down"></div>
                <div class="arrow arrow-down"></div>
            </div>
        </div>
    </div>
</template>
/*未激活的绳结需要设置底部padding,以抵消箭头旋转后产生的上下偏移*/
.introduction.trigger-point:not(.active){
    padding-bottom: 8px;
}

/*绳结下方的提示,未激活时显示*/
.introduction.trigger-point:not(.active):before{
    content: '点击查看帮助';
    color: rgba(13,148,225,.8);
    width: 100px;
    position: absolute;
    left: 50%;
    top:100%;
    transform: translateX(-50%);
}

/*绳结激活后,绳结上的箭头旋转*/
.introduction.trigger-point.active > .arrow-down{
    transform: rotate(225deg);
}

/*div的两条边邻边*/
.arrow {
    border: solid #ffffff;
    border-width: 0 3px 3px 0;
    display: inline-block;
    padding: 5px;
    margin: 0 auto;
}

/*div旋转形成箭头*/
.arrow-down {
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
}

九、成品
相关文件

VueJs一步步实现带感的帮助面板的更多相关文章

  1. Bootstrap历练实例:带列表组的面板

    带列表组的面板 我们可以在任何面板中包含列表组,通过在 <div> 元素中添加 .panel 和 .panel-default 类来创建面板,并在面板中添加列表组.您可以从 列表组 一章中 ...

  2. 教你调节Boom 3D的3D音效强度,让音乐更带感

    Boom 3D的专业3D环绕技术,让用户能全身心地沉浸在立体音效中.无论是聆听音乐,还是观赏电影,立体音效都能为人们带来更加真实的听觉感触. 那么,Boom 3D的3D环绕功能到底能给用户带来怎样的体 ...

  3. 魔幻特效,慢放世界,nova 3带你玩转抖音新技能

    无论是明暗相交的都市夜色, 还是鲜亮风景前的逆光美人: 无论是瞬息飘飞的叶片, 还是动如脱兔的稚子孩童…… 色彩与速度,精彩的每一刻, 华为摄影都尽在掌握! (华为手机摄影效果) 一直以来,华为的图形 ...

  4. 关于Behold the Kickmen (球员登场)

    音乐:『Boring,Boring——』作者浑厚的男中音响起,伴随着劲爆的动感音乐 非同正式却又无伤大雅的规则:足球场是圆形的,而且四周有反弹围墙 加强操作的一些设定: 踢踢人射门蓄力时,时间会静止, ...

  5. 基于 Vue.js 之 iView UI 框架非工程化实践记要 使用 Newtonsoft.Json 操作 JSON 字符串 基于.net core实现项目自动编译、并生成nuget包 webpack + vue 在dev和production模式下的小小区别 这样入门asp.net core 之 静态文件 这样入门asp.net core,如何

    基于 Vue.js 之 iView UI 框架非工程化实践记要   像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引 ...

  6. RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景?

    RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景? RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景? - 知乎 https://www ...

  7. ios项目里扒出来的json文件

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...

  8. 深入浅出NodeJS——数据通信,NET模块运行机制

    互联网的运作,最根本的驱动就是信息的交互,NodeJS 在数据交互这一块做的很带感,异步编程让人很惬意,关于 NodeJS 的数据通信,最基础的两个模块是 NET 和 HTTP,前者是基于 TCP 的 ...

  9. AngularJS中的表单验证

    AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 1.使用angularjs的表单验证 正则式验证 只需要配置一个正则 ...

随机推荐

  1. MongoDB数据库备份和恢复

    1.数据库备份 mogodbdump -h dbhost -d dbname -o dbdirectory -h: 服务器地址,也可以指定端口号 -d: 需要备份的数据库的名称 -o: 备份的数据库存 ...

  2. 利用Springmvc的AbstractXlsxView下载Excel文件

    设计一个模型,在针对多中数据类型进行拓展 public abstract class ExcelView extends AbstractXlsxView { public CellStyle cel ...

  3. GP工作室—需求分析

    团队作业第二次作业--需求分析 问题 答案 这个作业属于哪个课程 软件工程 这个作业要求在哪里 作业要求 团队名称 GP工作室 这个作业的目标 ① 团队项目的需求分析 ②团队项目的原型设计 团队队员介 ...

  4. 《前端之路》--- 重温 Koa2

    目录 一.简单介绍 二. 路由 三.请求数据 四. 静态资源加载 五. 静态资源加载 六. koa2加载模板引擎 七. koa2 中简单使用 mysql 数据库 八. koa2 中使用单元检测 九. ...

  5. 数据结构 二维数组-->稀疏数组-->二维数组

    稀疏数组基本概念: 稀疏数组应用场景: 当一个数组大部分的元素为"0",或者为同一个值的数组时,可以使用稀疏数组来保存该数组 处理方法: 1>记录数组一共有几行几列,有多少不 ...

  6. IIS 32位/64位 全局模式切换

    IIS7以上可以对单个应用程序池进行设置. IIS6需要用命令. 一.32位模式1.cscript %systemdrive%\inetpub\adminscripts\adsutil.vbs set ...

  7. mysql创建流水号

    mysql数据库创建流水号 CREATE TRIGGER saledetail_id BEFORE INSERT ON saledetail FOR EACH ROW BEGIN declare n ...

  8. 推荐一本学习Groovy的书籍Groovy程序设计!

    有朋友公司在用groovy开发,于是推荐我学习一下,搜到了这本书: 花了一个月时间读完了这本书!写的很棒,几乎没有废话,全书都是很重要的知识点和很好的讲解,确实像封面说的那样,使用的好可以提高开发效率 ...

  9. oracle问题之SYSTEM表空间不足 (二)

    杂症二.SYSTEM表空间不足报错 一.杂症: PLSQL登录,报错: ORA-00604: 递归 SQL 层  出现错误 ORA-01653: 表.无法通过(在表空间中)扩展 ORA-02002: ...

  10. jQuery使用ajax向node后台发送对象、数组参数

    引言 最近在使用jq,做一些小demo,但是突然发现jq使用ajax像后台(node)传递一个对象参数,但是后台却接收不了. 原因 后面了解到.jq会将一个对象解析成obj[key]: value这样 ...