一 指令

  • 解释:指令 (Directives) 是带有 v- 前缀的特殊属性
  • 作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

 

    v-text

  • 解释:更新元素的 textContent

        <h1 v-text="msg"></h1>

    

    v-html

  • 解释:更新元素的 innerHTML

        <h1 v-html="msg"></h1>

         

    v-bind

  • 作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
  • 语法:v-bind:title="msg"
  • 简写::title="msg"

 

    v-on

  • 作用:绑定事件
  • 语法:v-on:click="say" or v-on:click="say('参数', $event)"
  • 简写:@click="say"
  • 说明:绑定的事件从methods中获取

 

    事件修饰符

  • .stop 阻止冒泡,调用 event.stopPropagation()
  • .prevent 阻止默认事件,调用 event.preventDefault()
  • .capture 添加事件侦听器时使用事件捕获模式
  • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
  • .once 事件只触发一次

 

    v-model

  • 作用:在表单元素上创建双向数据绑定
  • 说明:监听用户的输入事件以更新数据

 

    v-for

  • 作用:基于源数据多次渲染元素或模板块

 

    key属性

  • 推荐:使用 v-for 的时候提供 key 属性,以获得性能提升。
  • 说明:使用 key,VUE会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

 

    样式处理 -class和style

  • 说明:这两个都是HTML元素的属性,使用v-bind,只需要通过表达式计算出字符串结果即可
  • 表达式的类型:字符串、数组、对象
  • 语法:

<!-- 1 --> <div v-bind:class="{ active: true }"></div> ===> <div class="active"></div>

 

v-if 和 v-show

  • 条件渲染
  • v-if:根据表达式的值的真假条件,销毁或重建元素
  • v-show:根据表达式之真假值,切换元素的 display CSS 属性

 

    不同点:

1 . v-if 当值为 true时,显示div ,

        当值为false时,改元素消失,代码也会消失,

        相当于将代码删除了,当在为true时,页面会重新渲染div; 

        支持加在<template>标签上

    

        而v-show 控制的隐藏出现,

        只是将css属性设为了display:none 或block;

       不支持加在<template>标签上

    

2.v-if 后还有 v-else 和 v-else-if 条件渲染,

    这里需要注意的是v-else 必须紧跟 v-if 或v-else-if 

 

3.v-if是真真正正的条件渲染;

  然而他是惰性的,

  在初始值是false的时候,他就什么都不做,

  在为真的时候才会开始局部变异 

 

      相比之下v-show则是更简单一下,仅仅是css上的切换 

      所以,v-if有更高的切换消耗,

      而v-show有更高的初始渲染消耗;

      因此,如果是频繁切换,就用v-show

      在条件很难改变,比如某个模块在用户a出显示,就用v-if

    

        提升用户体验:v-cloak

  • 这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
  • 防止刷新页面,网速慢的情况下出现{{ message }}等数据格式

<div v-cloak>   {{ message }} </div>

 

提升性能:v-pre

  • 说明:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

    <span v-pre>{{ this will not be compiled }}</span>

    

    提升性能:v-once

  • 说明:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

    <span v-once>This will never change: {{msg}}</span>

    

二.组件

    全局

    全局组件注册方式:Vue.component(组件名,{方法})

    注意:

    全局组件必须写在Vue实例创建之前,才在该根元素下面生效;

    模板里面第一级只能有一个标签,不能并行;

    data里面this指的是window,在methods里面this才是Vue实例

    局部

    局部组件注册方式,直接在Vue实例里面注册

        new Vue({

  el: '#app',

  router,

  components: { App },

  template: '<App/>'

})

 

注意:

    属性名为components,s千万别忘了;

    data里面this指的是window,在methods里面this才是Vue实例

    

      组件的属性以及用法和意义

    data:data必须是一个函数 返回一个唯一的对象,不要和其他组件共用一个对象进行返回!!!每一个实例的data属性都是独立的,不会相互影响了

    

         watch

    首先确认 watch是一个对象,一定要当成对象来用。 

    对象就有键,有值。 

    键:就是你要监控的那个家伙,比如说$route,这个就是要监控路由的变化。或者是     data中的某个变量。 

    值可以是函数:就是当你监控的家伙变化时,需要执行的函数,这个函数有两个形     参,第一个是当前值,第二个是变化后的值。 

    值也可以是函数名:不过这个函数名要用单引号来包裹。 

    第三种情况厉害了。 

    值是包括选项的对象:选项包括有三个。

              第一个handler:其值是一个回调函数。即监听到变化时应该执行的函数。

  1. 第二个是deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。)
  2. 第三个是immediate:其值是true或false;确认是否以当前的初始值执行handler的函数。

 

    

        computed

        做筛选功能,与watch的用法相似,也是键值,键就是data里面的数据名称,值是一个函  数,用来操作步骤。

 

组件的生命周期

生命周期钩子

组件状态

最佳实践

 

beforeCreate

实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据

常用于初始化非响应式变量

created

实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组

常用于简单的ajax请求,页面的初始化

beforeMount

在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数

mounted

实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问

常用于获取VNode信息和操作,ajax请求

beforeupdate

响应式数据更新时调用,发生在虚拟DOM打补丁之前

适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

updated

虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作

避免在这个钩子函数中操作数据,可能陷入死循环

beforeDestroy

实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例

常用于销毁定时器、解绑全局事件、销毁插件对象等操作

destroyed

实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

 

注意:

  1. created阶段的ajax请求与mounted请求的区别:前者页面视图未出现,如果请求信息过多,页面会长时间处于白屏状态
  2. mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染

        完毕,可以用 vm.$nextTick

  1. vue2.0之后主动调用$destroy()不会移除dom节点,作者不推荐直接destroy这种做法,如果实在需要这样用可以在这个生命周期钩子中手动移除dom节点

组件通讯

        父组件给子组件传值

        传   父组件用:变量名:"变量值"

        接    在子组件中定义props属性

            props:{

                变量名:变量的类型

            }

        用    在模板里{{变量名}}即可等到传过来的值

        子组件给父组件传值

        传   在子组件定义一个事件如@click="add" 

            然后 在methods中设置

            methods: {

                        add() {

                     用 this.$emit触发在父组件中定义好的自定义事件(例子中的increment)

                     name是子组件要传给父组件的值

                            this.$emit('increment',this.name)  

                        }

             }

        接    在父组件中定义好的子组件的标签上定义

            increment就是自定义事件,子组件就是触发的这个事件

            incrementTotal是触发自定义事件后发生的函数方法

            <Zi @increment="incrementTotal"></Zi>

            

             methods: {

                   incrementTotal (name) {

                  name就是子组件传过来的值,只要将他赋值给data里的变量,就可以在模板使用了

                            console.log(name)

                        }

                   }

            

        用    在模板里{{变量名}}即可等到传过来的值

        

非父子通信

        简单情况下我们可以通过使用一个空的Vue实例作为中央事件总线

        在main.js文件夹下建一个vue空实例

        let bus = new Vue()

        Vue.prototype.bus = bus

        

        在一个组件中定义this.bus.$emit('toChangeTitle','从首页来')

            toChangeTitle自定义事件名称,后面是要传的值

        

        在另一个组件中的接收

        mounted () {

                    this.bus.$on('toChangeTitle', function (title) {

                    toChangeTitle //前一个组件定义的自定义事件名

                    title //值 把他赋值给data里的变量就可以在模板中使用了

                             console.log(title)

                     })

          }

dom操作

        vue提供的ref属性以及this.$refs即可实现

        

        

        $refs

首先你的给子组件做标记。demo :<firstchild ref="one"></firstchild>

然后在父组件中,通过this.$refs.one就可以访问了这个自组件了,包括访问自组件的data里面的数据,调用它的函数

 

2)$children

        他返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作;

1 2 3

for(let i=0;i<this.$children.length;i++){     console.log(this.$children[i].msg);输出子组件的msg数据;  }

         2)$parent 与$children相似

        

        

路由

vue-router是专门针对于vue提供单页面路由创建的插件

 

什么单页面应用?

只有一个页面的应用,但是可以有多个路由地址。正常情况下只要是a链接,点击后都会向服务端发起请求

而单页面应用,

只有在第一次访问的时候,或者强制刷新的时候会向服务端发起请求,其他情况则不会

这是由于单页面路由利用前端页面的几个特性

1,hash 

hash可以改变url地址不会向后端发出请求,而且留有历史纪录,通过hashchang事件可以监听hash的改变

 

2,history

html5针对history api新增了,pushState, replaceState 方法进行url地址的改变,并且不会向服务端发起请求

新增了popstate事件监听url通过历史纪录,pushstate,replaceState方法改变url的监听

 

 

单页面应用的特点

改变url地址,

不会像后端发起请求,并且可以重新渲染页面,达到页面异步更新的效果,

而且会留有历史纪录

 

在vue中结合history,hash实现了路由跳转的封装,封装成了统一的跳转方法,统一的监听处理

同vue实例中mode选型可以对两种模式进行切换

 

什么是路由?

路由的概念本身是后端,后端通过定义路由,指定渲染的页面,浏览器通过url地址访问,服务端接收到请求,给客户端返回需要渲染的内容

一个url地址

 

 

vue-router如何使用

 

1,下载vue-router并且引入  import VueRouter from 'vue-router'

2,注册vue-router  vue.use(VueRouter)

3, 实例化vue-router   new VueRouter(配置)

4, 对实例进行配置

   配置选项:

   {

     mode: 'hash', // hash || history

     router: [

       {

         path: '', //路由地址 /user

         compoent: '',  路由对应需要渲染的组件,渲染到router-view对应的位置

         name: '', 指定路由名称

         meta: {}, 路由的其他配置参数可以是如何数据

         redirect: '', 重定向

         children: [

           {

             path: 'home'   // /user/home

           },

           {

             path: '/home'  // /home

           }

         ], //对应的子路由

       }

     ],  // 所有路由列表, 每一项是一个路由规则

   }

5, router-view 指定路由对应渲染的位置

6, 将router实例挂载到vue根实例上,在组件中就可以使用$router访问到router实例了

 

7,路由的跳转控制

  使用组件router-link   

  使用js方法 $router.push() 

              $router.replace()

              back() 

              go() ....

 

8, 路由的拦截

$router和$route的关系

$route为当前router跳转对象里面可以获取name、path、query、params等

$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法等

 

<router-link>中的to 和 :to 的区别

to是指直接跳转页面 <router-link to="aa>go</router-link">

:to是指跳转时候传参<router-link :to="{path:'tt',query:{'cc':'cc'}}">go </router-link>

 

路由传参

 params传参   <router-link :to="{name:'go',params:{'cc':'this is cc'}}">

 query传参   <router-link :to="{name:'go',query:{'cc':'this is cc'}}">

 

1、用法上的

  刚才已经说了,query要用path或者name都可以引入,params要只用用name来引入,接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name。

注意接收参数的时候,已经是$route而不是$router了哦!!

2、展示上的

query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示

3.调用方面

params一旦传参就必须调用,e而query,定以后可调可不调用

因为params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系

 

4.使用场景

params:/router1/:id ,/router1/123,/router1/789 ,这里的id叫做params

query:/router1?id=123 ,/router1?id=456 ,这里的id叫做query。

 

 

响应路由参数的变化

提醒一下,当使用路由参数时,例如从 /user/foo 导航到 user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch(监测变化) $route 对象:

 

命名视图

有时同时(候想同级)展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar(侧导航) 和 main(主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。

<router-view class="view one"></router-view>   <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置(带上 s):

const router = new VueRouter({   routes: [     {       path: '/',       components: {         default: Foo,         a: Bar,         b: Baz       }     }   ] })

 

重定向

重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:

const router = new VueRouter({   routes: [     { path: '/a', redirect: '/b' }   ] })

重定向的目标也可以是一个命名的路由:

const router = new VueRouter({   routes: [     { path: '/a', redirect: { name: 'foo' }}   ] })

甚至是一个方法,动态返回重定向目标:

const router = new VueRouter({   routes: [     { path: '/a', redirect: to => {       // 方法接收 目标路由 作为参数       // return 重定向的 字符串路径/路径对象     }}   ] })

 

 

别名

『重定向』的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,那么『别名』又是什么呢?

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

上面对应的路由配置为:

const router = new VueRouter({   routes: [     { path: '/a', component: A, alias: '/b' }   ] })

『别名』的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

 

 

导航钩子

vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。

  • 全局钩子

const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => {     // do something      next(); }); router.afterEach((to, from, next) => {     console.log(to.path); });

每个钩子方法接收三个参数:

  • to: Route : 即将要进入的目标 [路由对象]
  • from: Route : 当前导航正要离开的路由
  • next: Function : 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的)。

next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from路由对应的地址。

next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

确保要调用 next方法,否则钩子就不会被 resolved。

  • 组件内的钩子

你可以在路由组件内直接定义以下路由导航钩子:

beforeRouteEnter beforeRouteUpdate (2.2 新增) beforeRouteLeave

const Foo = {   template: `...`,   beforeRouteEnter (to, from, next) {     // 在渲染该组件的对应路由被 confirm 前调用     // 不!能!获取组件实例 `this`     // 因为当钩子执行前,组件实例还没被创建   },   beforeRouteUpdate (to, from, next) {     // 在当前路由改变,但是该组件被复用时调用     // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,     // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。     // 可以访问组件实例 `this`   },   beforeRouteLeave (to, from, next) {     // 导航离开该组件的对应路由时调用     // 可以访问组件实例 `this`   } }

beforeRouteEnter 钩子 不能 访问 this,因为钩子在导航确认前被调用,因此即将登场的新组件还没被创建。

不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter (to, from, next) {   next(vm => {     // 通过 `vm` 访问组件实例   }) }

你可以 在 beforeRouteLeave 中直接访问 this。这个 leave 钩子通常用来禁止用户在还未保存修改前突然离开。可以通过 next(false) 来取消导航。

vuex

     原理:

    vuex的方案是,在vue中构建一个用于存储state、定义操作state方法的仓库(即store)。通过在多个(不一定是全部)组件中引用需要的state、调用“操作state的方法”来实现对给共享变量的处理。且由于各个组件对state是引用的,单个组件改变了某个state后,其他组件可以实时的响应变化。

使用

    1.下包

        cnpm install --save-dev vuex

    2.在项目src目录下创建vuex文件夹,再里创建store.js文件

    3.在store.js中

        引入vue和vuex

        import Vue from 'vue'

        mport Vuex from 'vuex'

        在入口文件引入vuex并将store添加到根结点上

    4.store.js中的基本结构是

        

        import Vue from 'vue'

        mport Vuex from 'vuex'

        

        Vue.use(Vuex)

        

        const state = {   //状态 在视图里面渲染的基本都放在state里

                list:[],

                num:0

            //存放共享组件

        }

        const getters = { //计算过滤操作

            state中的变量:(state)=>{

                return  state.变量名+一些列的操作

            }

        }

        const mutation = {  //同步改变状态

            add(state){

                state.num++

            } 

            //可以放一些改变state的方法

        }

        const actions ={    //异步改变状态 在视图中调用actions里的方法一般使用  

                                        this,$store.dispatch('方法名')

            方法名(context){    //这里的context是一个上下文对象  相当于当前的store    也可以直接                 

                                            使用{commit}

                context.commit('调用mutation里的方法',自由参数)

            }

        }

        

        

        export default new Vuex.store({

            state,

            mutations,

            actions,

            getters,

            

        })

        

        视图应用

            如果想把state里的数据映射在视图中,如liste:[]需要以下操作

            第一种:可以直接在组件中{{this.$store.state.list}}  //注意list是个数组需要循环

            第二种 可以在视图中引入mapState方法  

                    import  {mapState}  from 'Vuex'

                    然后在视图计算属性中

                    computed:{

                        ...mapState(['list'])    //es6的扩展符

                    }

                    然后在组件中直接使用    {{list}} //注意list是个数组需要循环

                    

               

             如果想把mutation里的方法想应用在视图中,如add需要以下操作

            第一种:可以直接在组件中事件的函数中“this.$store.commit("add",自由参)”  

            第二种 可以在视图中引入mapMutation方法  

                    import  {mapMutation}  from 'Vuex'

                然后在视图的方法中

                methods:{

                    ...mapMutation(['add'])

                }

                可以直接在组件中事件的函数中"add",自由参

            actions的应用与mutation类似

           getters的应用就是把state引进修改后return出去就好

        

        

    vuex与全局变量的区别

        vuex响应vue的规则  全局变量

        

      

vuex实现的作用:数据共享机制

    通过统一的数据中心store维护状态数据,每个组件进行更新的时候,通知数据中心 store。再由stroe将共享的状态,触发每一个调用它的组件的更新。

    vuex的工作流程

    1.在vue组件里面,通过dispatch来触发actions提交修改数据的操作。

    2.然后再通过actions的commit来触发mutations来修改数据。

    3.mutations接收到commit的请求,就会自动通过Mutate来修改state(数据中心里面的数据状态)里面的数据。

    4.最后由store触发每一个调用它的组件的更新

 

vuex

什么是状态?

当前样子,可以发生变化,开始的状态,结束的状态。

 

什么是状态管理?

让状态以一定形式定义,一定的形式改变,一定的形式获取,提供一个规则

 

Vuex 是什么?

是专门针对vue提供的状态管理模式。

它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能

 

为什么要用vuex?

为了更好的管理状态,在之前组件内部状态的应用中发现,每个组件的状态都是独立的,如果存在好多组件公用的状态通讯起来比较麻烦

vuex的出现,他是将所有数据状态集中式存储管理,变成了一个,在组件中以相应的规则去读取改变。

 

有什么能够替代vuex,但是为什么不用?

可以使用redux或者将数据定义在vue根实例中,或者定义全局变量

redux:他并不是针对vue专门做处理的,无法同步状态和视图之间的转换

vue根实例:因为vue根实例的定义是整个应用程序,而不是数据管理

全局变量:var store = {}, 没有规则,无法同步状态和视图之间的转换

vuex:专门针对vue开发的一套以集中式的存储管理整个状态树,并且以对应的规则进行数据的管理,而且还兼容vue的数据检测

 

 

vuex的核心概念

state: 唯一数据源, 定义在store中的state选项,在组件中可以通过this.$store.state读取,一半都写在计算属性中,可以通过mapState()函数生成计算属性

getters:相当于组件中的计算属性, 定义在store中getters选项中,在组件中通过$store.getters获取,一半都写在计算属性中,可以通过mapGetters()函数生成计算属性

getters: {

计算属性名称 (state, getters) => {

return 返回值

}

}

 

mutation: 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,

并且它会接受 state 作为第一个参数, 其他参数为第二个, 通过commit可以执行他

注意:Mutation 必须是同步函数

因为mutation中除了改变state之外还将state改变的过程快照记录了下来,如果在mutation中写异步逻辑的话就无法记录快照了

 

actions: 用来提交mutations,可以处理异步逻辑,但是不能直接修改state,只能通过commit('mutation')的形式改变state,actions函数接收一个context对象(类似于store实例)

 

 

1,webpack打包的配置,常见的loaders和plugins?

 

2webpack的基本配置有哪些?

Entry 配置模块的入口;

Output 配置如何输出最终想要的代码;

Module 配置处理模块的规则;

Resolve 配置寻找模块的规则;

Plugins 配置扩展插件;

DevServer 配置 DevServer;

 

3webpack 打包按需加载?

在 webpack 的构建环境中,要按需加载代码模块很简单,遵循 ES 标准的动态加载语法 dynamic-import 来编写代码即可,webpack 会自动处理使用该语法编写的模块:

需要我们在 webpack 配置中添加一个 output.chunkFilename 的配置:

output: {

  path: path.resolve(__dirname, 'dist'),

  filename: '[name].[hash:8].js',

  chunkFilename: '[name].[hash:8].js' // 指定分离出来的代码文件的名称

}

 

3,简单介绍下webpack的工作原理?

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;

开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;

确定入口:根据配置中的 entry 找出所有的入口文件;

编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;

完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;

输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;

输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

https://whjin.github.io/full-stack-development/posts/工作原理概括.html

 

 

4webpack配置开发环境和生产环境的区别?

日常的前端开发工作中,一般都会有两套构建环境:一套开发时使用,构建结果用于本地开发调试,不进行代码压缩,打印 debug 信息,包含 sourcemap 文件;另外一套构建后的结果是直接应用于线上的,即代码都是压缩后,运行时不打印 debug 信息,静态文件不包括 sourcemap 的。有的时候可能还需要多一套测试环境,在运行时直接进行请求 mock 等工作。

webpack 4.x版本在webpack配置中有mode选项可以直接配置production 或 development

webpack 3.x 一般是通过node命令传递环境变量,来控制不同环境下的构建行为

如:

{

  "scripts": {

    "build": "NODE_ENV=production webpack",

    "dev": "NODE_ENV=development webpack-dev-server"

  }

}

然后在 webpack.config.js 文件中可以通过 process.env.NODE_ENV 来获取命令传入的环境变量:

 

 

Logo

前往低代码交流专区

更多推荐