HTML5技术

在没有DOM操作的日子里,我是怎么熬过来的(中) - 闰土少年

字号+ 作者:H5之家 来源:H5之家 2017-11-30 13:05 我要评论( )

前言 继上篇推送之后,在掘金、segmentfault、简书、博客园等平台上迅速收到了不俗的反馈,大部分网友都留言说感同身受,还有不少网友追问中篇何时更新。于是,闰土顺应呼声,在这个凛冽的寒冬早晨,将中篇热文滚烫呈上。 搬好小板凳,接下来,正文从这开始

 

前言

 

继上篇推送之后,在掘金、segmentfault、简书、博客园等平台上迅速收到了不俗的反馈,大部分网友都留言说感同身受,还有不少网友追问中篇何时更新。于是,闰土顺应呼声,在这个凛冽的寒冬早晨,将中篇热文滚烫呈上。

 

搬好小板凳,接下来,正文从这开始~

 

在上篇的众多留言中,有位网友的评论比较具有代表性,摘出来供大家一阅:

 

“ 同感啊楼主 比如做tab的时候,以前jq就是切换一下class,现在vue是切换数据,再根据数据显示class,这弯绕的啊 ”

 

当然,有评论就有回复,请看下面这位网友是怎么回复他的:

 

“ 哪里绕弯了,只要记着数据驱动dom,习惯就好,这种模式才比较适合页面dom变化渲染,只是之前被jq带的根生蒂固 ”

 

有时候写文章,不一定仅仅是为了分享自己的工作经验,而是还想看看网友是怎么看待这个话题的,从而衍生出一系列的对话,以及思想碰撞。

 

在这里,闰土有句话想送给刚从JQ转变思路过来的同行们:

 

MVVM时代,数据映像了DOM世界,一切以数据为核心,正如同数学可以描述世界一样,你只需要考虑数据或者状态即可。

 

所以,只要你充分理解了上面这句话,恭喜你,你已经从直接操作DOM的时代毫无压力的过渡到了MVVM时代!

 

话不多说,先来看看MVVM项目的工程目录:

 

 

当然你可以通过vue官网提供的vue-cli脚手架工具,来快速搭建项目结构。如果有不懂脚手架作用的老铁,可以参照下图,这就有点类似于工地上的脚手架,可以帮助工人们快速搭建该建筑的结构模型(话糙理不糙,说明问题即可

)。

 

 

项目结构搭建完毕后,就可以npm install 来安装项目依赖了。通常这个阶段,可能会比较漫长,建议用国内淘宝的镜像cnpm。

 

也是在这期间,经常有同学在安装某依赖模块时,会碰到命令行报错,说是node或者npm版本过低等问题。假如你果真碰到这个类似的问题,可以考虑先将项目中的node_modules删除掉,然后重新cnpm install安装项目所需的依赖。通常这个情况,就会迎刃而解(不要问为什么,这可能是个偏方

)。

 

然后,你就可以大步流星地去执行以下操作了:

 

#开启本地开发服务器,监控项目文件的变化,实时构建并自动刷新浏览器,浏览器访问 :8081

npm run dev

 

#使用生产环境配置构建项目,构建好的文件会输出到 "dist" 目录,

npm run build

 

#运行构建服务器,可以查看构建的页面

npm run build-server

 

#运行单元测试

npm run unit

 

当你可以正常运行这个项目之后,接下来我们就该聊聊项目里的各个文件了。

 

俗话说,在js里面一切皆对象,那么vue里面,则是一切皆组件,能用组件实现的,终将被组件实现。

 

说到组件,在项目中,你可能会看到公司前辈写的组件代码,都是以 .vue 为后缀的文件,打开后你会发现它的整体结构分三层,分别定义了三个 tag标签,template,script,style。然后对应的代码在自己的标签里面各司其职,所有需要的html、css、javascript都在里面。

 

组件看完之后,我们移步到webpack的配置文件,也就是webpack.config.js文件,内容大概如下:

 

module.exports = {

    entry: {

        'index': './vue/index/main.js',

    },

    output: {

        path: './public/bulid',

        filename: '[filename].js' // 可以多点切入

    },

    module: {

        loaders: [

            {

              test: /\.vue$/,

              exclude: /node_modules/,

              loader: vue.withLoaders({

                  js: 'babel?optional[]=runtime'

              })

            },

            { test: /\.scss$/, loader: 'style!css!sass },

            { test: /\.css$/, loader: "style!css" },

            { test: /\.js$/, loader: 'babel-loader' }

        ]

    },

    resolve: { // 解决 npm 的依赖问题

        modulesDirectories: ['node_modules'],

        extensions: ['', '.js', '.json']

    },

}

 

我对 webpack 的最初信仰就是,它非常的智能化,可以将一切的资源(包括html css javascript image)用 import 和 require 模块化引入,并对资源进行预处理,最终被打包成一个js文件解释执行。

 

接下来我想谈谈vue的生命周期和钩子函数。

 

每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。

 

说的直白一点,分别对应的四组钩子函数就是:

 

beforeCreate 、created; // 创建前、创建完成

beforeMount 、mounted;// 挂载前、挂载完成

beforeUpdate 、updated; // 更新前、更新完成

beforeDestory 、destoryed。// 销毁前、销毁完成

 

这里闰土在网上找到一个很好的例子:

 

<!DOCTYPE html>

<html>

<head>

    <title>Vue生命周期</title>

    <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>

</head>

<body>

<div>

     <p>{{ message }}</p>

</div>

<script type="text/javascript">

  var app = new Vue({

      el: '#app',

      data: {

          message : "闰土少年"

      },

       beforeCreate: function () {

                console.group('beforeCreate 创建前状态 >>>>>>>>>>');

               console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined

               console.log("%c%s", "color:red","data   : " + this.$data); //undefined

               console.log("%c%s", "color:red","message: " + this.message)

        },

        created: function () {

            console.group('created 创建完毕状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el); //undefined

               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化

               console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        },

        beforeMount: function () {

            console.group('beforeMount 挂载前状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化

               console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        },

        mounted: function () {

            console.group('mounted 挂载结束状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化

               console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        },

        beforeUpdate: function () {

            console.group('beforeUpdate 更新前状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el);

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data);

               console.log("%c%s", "color:red","message: " + this.message);

        },

        updated: function () {

            console.group('updated 更新完成状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el);

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data);

               console.log("%c%s", "color:red","message: " + this.message);

        },

        beforeDestroy: function () {

            console.group('beforeDestroy 销毁前状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el);

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data);

               console.log("%c%s", "color:red","message: " + this.message);

        },

        destroyed: function () {

            console.group('destroyed 销毁完成状态 >>>>>>>>>>');

            console.log("%c%s", "color:red","el     : " + this.$el);

            console.log(this.$el);

               console.log("%c%s", "color:red","data   : " + this.$data);

               console.log("%c%s", "color:red","message: " + this.message)

        }

    })

</script>

</body>

</html>

 

最后在chrome的console控制台打印效果如下图:

 

 

在上图中大家可以看到,在beforeMount挂载前, $el里面还是{{ message }},这就是Virtual DOM(虚拟dom)技术的应用,上来二话不说,先把坑位占了,等后面mounted挂载的时候,再把值渲染进去。

 

最后,我们再聊聊前后端分离,并行开发的事情。

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 有没有必要参加IT培训 - 永志

    有没有必要参加IT培训 - 永志

    2017-11-26 14:08

  • ASP.NET没有魔法——ASP.NET MVC IoC - 7m鱼

    ASP.NET没有魔法——ASP.NET MVC IoC - 7m鱼

    2017-10-21 11:06

  • 使用 Newtonsoft.Json 操作 JSON 字符串 - 溪边静禅

    使用 Newtonsoft.Json 操作 JSON 字符串 - 溪边静禅

    2017-10-21 09:00

  • 【H5案例分享】Dr.魏的这波操作我赌你破解不了! - petercat

    【H5案例分享】Dr.魏的这波操作我赌你破解不了! - petercat

    2017-10-20 11:07

网友点评