Vue 学习记录03 组件化/模块化/webpack开发

2019/11/15 Vuejs
  • content

1. 组件化开发

1.1. 父子组件的访问

  • 父访问子组件:children/refs

    • children 返回数组

        <div id="app">
            <cpn></cpn>
            <button @click="btnClick">调用子组件</button>
        </div>
      		
        <template id="cpn">
            <div>
                <p></p>
            </div>
        </template>
        <script src="../js/vue.js"></script>
      		
        <script>
          const app = new Vue({
            el: '#app',
            data: {
              message: ' 你好!'
            },
              methods: {
              btnClick() {
                // 1. $children 返回的是数组
                console.log(this.$children[0].title);
                this.$children[0].showMessage();
              }
              },
              components: {
              cpn: {
                template: "#cpn",
                  data(){
                  return {
                    title: "我是子组件"
                  }
                  },
                  methods: {
                  showMessage(){
                    console.log('打印子组件');
                  }
                  }
              }
              }
          })
        </script>
      
    • refs 必须要在组件中指定ref=xxx

      <cpn ref="aaaa"></cpn>
    	
      ...
    		        
      console.log(this.$refs['aaaa'].title);
      this.$refs['aaaa'].showMessage()
    
  • 子访问父组件:parent/root (不经常使用)

      <script>
        const app = new Vue({
          el: '#app',
          data: {
            message: ' 你好!'
          },
            components: {
            cpn: {
              template: "#cpn",
                data(){
                return {
                  title: '我是子组件啊'
                }
                },
                components: {
                ccpn: {
                  template: "#ccpn",
                    methods: {
                    btnClick(){
                      console.log(this.$parent.title);
                      console.log(this.$root.message);
                    }
                    }
    	
                }
                }
            }
            }
        })
      </script>
    

1.2. slot 的使用

  • 基本使用

      <template id="cpn">
          <div>
              <h2>我是子组件</h2>
              <slot><button>按钮</button></slot><!--插槽标签 slot-->
          </div>
      </template>
    
  • 具名插槽

      <div id="app">
          <cpn>
              <button slot="right">按钮</button>
          </cpn>
      </div>
      <template id="cpn">
          <div>
              <slot name="left">左边</slot>
              <slot name="center">中间</slot>
              <slot name="right">右边</slot>
          </div>
      </template>
    
  • 编译的作用域

      <div id="app">
          <cpn v-show="isShow"></cpn>
      </div>
    

    在此时 isShow调用的是父组件的isShow

  • 作用域插槽

      <div id="app">
          <npc></npc>
          <npc>
              <!--		目的是获取子组件的sLanguages-->
              <template slot-scope="slot">
                  <span v-for="item in slot.data"> </span>
              </template>
          </npc>
          <npc>
              <!--		目的是获取子组件的sLanguages-->
              <template slot-scope="slot">
                  <span> </span>
              </template>
          </npc>
      </div>
    	
      <template id="npc">
          <div>
              <!--		自定义标签data,传递sLanguages数据-->
              <slot :data="sLanguages">
                  <ul>
                      <li v-for="item in sLanguages"></li>
                  </ul>
              </slot>
          </div>
      </template>
    	
      <script src="../js/vue.js"></script>
    	
      <script>
        const app = new Vue({
          el: '#app',
          data: {
            message: ' 你好!'
          },
          components: {
            npc: {
              template: "#npc",
              data() {
                return {
                  sLanguages: ['JavaScript', 'Java', 'Python', 'C++', 'Go']
                }
              }
            },
          }
        })
      </script>
    

2. 模块化开发

2.1. 为什么使用模块化

  • 简单写js代码带来的问题

  • 闭包引起代码不可复用性

  • 自己实现了简单的模块化

  • AMD/CMD/CommonJS

2.2. ES6在模块化中的使用

  • export
  • import

3. webpack

  1. 安装

    shell script npm install webpack

  2. 基本使用

    指定入口文件main.js和导出文件bundle.js

     webpack ./src/main.js ./dist/bundle.js
    

    在入口文件中,导入相关包,支持多种模块导入方式:

     // ES6 模块化规范
     import * as mathUtils from "./mathUtils"
        
     console.log(mathUtils.addPlus(1, 2, 3, 4));
     console.log(mathUtils.add(2, 3));
     console.log(mathUtils.mul(2, 3));
        
     // common.js 模块化规范
     const {name, age, height} = require("./info");
     console.log(name);
     console.log(age);
     console.log(height);
    
  3. 初始化项目目录

    ```shell script $ npm init
    This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. ….. ….. # 指定包的名称,不可以是中文 Press ^C at any time to quit. package name: (02-webpack的配置) Sorry, name can only contain URL-friendly characters. package name: (02-webpack的配置) meetwebpack # 指定版本 version: (1.0.0) # 描述 description: # 入口文件 entry point: (webpack.config.js) index.js # 测试命令 test command: # git 仓库 git repository: # 关键字 keywords: # 作者 author: # 许可 license: (ISC) About to write to /Users/lei/WebstormProjects/LearnVuejs-v2/01-webpack的使用/02-webpack的配置/package.json:

    { “name”: “meetwebpack”, “version”: “1.0.0”, “description”: “1. 安装”, “main”: “index.js”, “scripts”: { “test”: “echo "Error: no test specified" && exit 1” }, “author”: “”, “license”: “ISC” }

    Is this OK? (yes)

    ```

    直行完后,会生成 package.json文件

  4. 定义 webpack.config.js 配置文件

    定义 webpack配置文件webpack.config.js,在使用webpack命令时,会自动读取文件配置

     // 导入node 包的path, 要提前直行 npm init初始化
     const path = require('path');
        
     module.exports = {
       // 定义入口
       entry: './src/main.js',
       // 定义出口
       output: {
         // 动态获取路径
         path: path.resolve(__dirname, 'dist'),
         filename: 'bundle.js'
       }
     };
    

    定义完成后,直行 webpack 可以不用指定 入口文件 与导出文件路径,因为在配置文件中已经定义好了

  5. 利用npm run build打包

    package.json中添加 build命令映射

    ...
     "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
     "build": "webpack"
     },
    ...
    
  6. 在本地安装webpack

    npm install webpack@3.6.0 --save-dev
    

    安装完成后,本地会生成 node_modules library root 目录

    package.json中会多出

     "devDependencies": {
     "webpack": "^3.6.0"
     }
    

    这时候使用npm run build会优先使用局部的

  7. 什么是loader ?

    loader 用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

    加载 css 模块时,需要安装 css / style loader

    ```shell script npm install –save-dev css-loader npm install –save-dev style-loader npm install –save-dev less-loader less

       
    加载图片
       
    ```shell script
    #当加载图片小于limit时,会编译成base64字符串形势
    npm install --save-dev url-loader 
    #当加载图片大于limit时,需要使用file-loader模块进行加载
    npm install --save-dev file-loader
    
  8. 将ES6 相关内容 转换成ES5

    shell script npm install babel-loader babel-core babel-preset-es2015

  9. 解析Vue文件

    注意: vue-loader版本

    shell script # 安装vue loader npm install vue-loader vue-template-compiler --save-dev

  10. plugin使用

    • html-webpack-plugin

      功能: 可以自动生成 index.html 文件

      安装:

      ```shell script npm install html-webpack-plugin –save-dev

            
        配置: 
              
        在 `webpack.config.js`配置中添加:
              
        ```javascript
        const htmlWebpackPlugin = require('html-webpack-plugin');
        plugins: [
            new htmlWebpackPlugin({
              //index.html 为模板文件
              template: 'index.html'
            })
          ]
      
    • BannerPlugin

      功能: 打包时声明版权信息

      安装:

      ```shell script npm install webpack –save-dev

            
        配置:
      		    
        ```javascript
        const webpack = require('webpack');
      		
        plugins: [
            new htmlWebpackPlugin({
            template: 'index.html'
        }),
        new webpack.BannerPlugin('最终版权归xxx所有')
        ]
      
    • uglifyJsPlugin

      功能: 压缩js代码

      安装:

      ```shell script npm install uglifyjs-webpack-plugin@1.1.1 –save-dev

         
        配置:
      
       ```javascript
        const uglifyJsPlugin = require('uglifyjs-webpack-plugin')
             
       module.exports = {
        ...
       plugins: [
         new uglifyJsPlugin()
       ]
       }
      
  11. npm搭建本地服务

    功能:

    安装本地http服务,将html结果缓存到内存中,避免开发过程中每次修改都需要手动build 才能看的结果

    安装:

    ```shell script npm install –save-dev webpack-dev-server@2.9.1

    
    配置:
        
    `webpack.config.js`:
    ```javascript
    // 导入node 包的path, 要提前直行 npm init初始化
    const path = require('path');
    const htmlWebpackPlugin = require('html-webpack-plugin');
    const webpack = require('webpack');
    const uglifyJsPlugin = require('uglifyjs-webpack-plugin');
        
    ...
        
      devServer: {
        // 目标目录
        contentBase: './dist',
        //页面实时刷新
        inline: true
      }
        
    };
    

    package.json:

      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack",
        "dev": "webpack-dev-server"
      },    
    

    配置之后,可以直接直行 npm run dev

  12. 配置分离

    • 功能:

      区别在开发与生产环境不同的webpack配置,生成两套对应的配置文件

    • 安装:

      npm install webpack-merge

    • 说明:

      可以通过webpack-merge 动态合并配置文件

      创建base.config.jsprod.config.jsdev.config.js 分别用于基础配置、生产配置、开发配置

      将共同功能添加到base.config.js中,生产需要的添加到prod.config.js中,只有开发需要的添加到dev.config.js中。

    • 配置:

      base.config.js 里面为通用配置

      prod.config.js:

        // 导入node 包的path, 要提前直行 npm init初始化
        const uglifyJsPlugin = require('uglifyjs-webpack-plugin');
        const webpackMerge = require('webpack-merge');
        const baseConfig = require('./base.config');
      		
        module.exports = webpackMerge(baseConfig,{
          plugins: [
            new uglifyJsPlugin()
          ]
        });
      

      dev.config.js:

        // 导入node 包的path, 要提前直行 npm init初始化
        const webpackMerge = require('webpack-merge');
        const baseConfig = require('./base.config');
      		
      		
        module.exports = webpackMerge(baseConfig, {
          devServer: {
            // 目标目录
            contentBase: './dist',
            //页面实时刷新
            inline: true
          }
        });
      

      package.json:

        "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack --config ./build/prod.config.js",
        "dev": "webpack-dev-server --config ./build/dev.config.js"
        },
      

Search

    Table of Contents