vue.js 之 webpack 学习2(九)

在普通页面中使用 render 方法渲染组件

传统的组件渲染方式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!--h1 标签内容可以显示-->
        <h1>哈哈</h1>
        <login></login>
    </div>

    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        // 定义一个字面量组件
        var login = {
            template: '<h1>登录组件</h1>'
        }
        var vm = new Vue({
            el: '#app',
            data: [],
            components: {	// 挂挂载
                login
            }
            
        })
    </script>
</body>

</html>

render 方法渲染组件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!--h1 标签内容不会显示,会被 render 渲染的结果覆盖-->
        <h1>哈哈</h1>		
    </div>

    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        var login = {
            template: '<h1>登录组件</h1>'
        }
        var vm = new Vue({
            el: '#app',
            data: [],
            render: function(createElement) {
                // createElement 是一个方法,调用它可以把指定的组件模板,渲染为 HTML 结构
                return createElement(login)
            }
            
        })
    </script>
</body>

</html>

两者区别

  • 传统:不会替换 el 所在 HTML 标签
  • render:会替换 el 所在的 HTML 标签,若 el 中还有其他 HTML 元素也会被替换,一个页面有且只能有一个 render 方法

使用 webpack 构建 vue 项目完整步骤

需求

  • 初始化项目构建
  • webpack 打包项目,实时更新,运行时能直接定位到相应路径
  • 安装 vue

项目结构

ProjectName:.
├─dist/				// webpack 打包后生成
├─node_modules/		// 包文件都存放在这里面
├─src				// 资源文件
│  └─index.html		// 首页
│  └─login.vue		// 组件
│  └─main.js		// 入口文件
├─package.json		// npm init 生成,可查看已安装的依赖包
├─package-lock.json
├─webpack.config.js		// webpack 配置文件

1、初始化项目:

mkdir ProjectName
cd ProjectName

// 初始化时需要你指定项目相关信息,如:名称、版本、作者、测试命令等,完了最终生成一个 package.json 文件
npm init

2、安装 webpack,对项目进行打包:

npm i webpack --save-dev
npm i webpack-cli --save-dev

项目根目录新建 webpack.config.js 配置文件:

var path = require('path')

module.exports = {
    entry: path.join(__dirname, './src/main.js'), //入口文件
    output: {
        // 输出选项
        path: path.join(__dirname, './dist'),   // 输出路径
        filename: 'bundle.js',  // 指定输出文件名称
    },
}

配置文件中指定入口文件,打包输出路径和最终打包成的 js 文件,执行 webpack 命令即可进行打包,会生成一个 dist/ 目录。

3、安装 webpack-dev-server 实时更新:

为了不每次更新 main.js 文件都要重启项目,安装 webpack-dev-server 进行实时打包编译。

// 安装
npm i webpack-dev-server --save-dev

// package.json 中添加启动命令
{
  "name": "day05",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --open --port 3000 --hot"       // 新增
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "jquery": "^3.4.1",
    "webpack-dev-server": "^3.10.3"
  },
  "devDependencies": {
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11"
  }
}

4、配置启动页面:

按照上述操作启动项目,项目自动打开浏览器运行在 3000 端口,但是它并不能直接定位到 index.html 页面,需要手动输入 /src 路由才能定位,为此可以配置启动页面,直接定位到 index.html,省去手动添加路由的麻烦。

// 安装
npm i html-webpack-plugin --save-dev

配置启动页面,更新 webpack.config.js

var path = require('path')

var htmlWebpackPlugin = require('html-webpack-plugin');		// 新增

module.exports = {
    entry: path.join(__dirname, './src/main.js'),   // 入口文件
    output: {
        // 指定输出项
        path: path.join(__dirname, './dist'),   // 输出路径
        filename: 'bundle.js'   // 输出文件名称
    },
    plugins: [
        // 新增
        new htmlWebpackPlugin({
            template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
            filename: 'index.html'  // 设置生成内存页面名称
        })
    ],
}

5、使用 vue

安装 vue 相关包

cnpm i vue -S
cnpm i vue-loader vue-template-compiler -D		// 解析 .vue 结尾的组件

导入 vue 包和组件 main.js

import Vue from '../node_modules/vue/dist/vue.js'	// 导入 vue 包

import login from './login.vue'		// 导入 login.vue 组件

var vm = new Vue({
    el: '#app',
    data: {
        msg: '123',
    },
    
    // 渲染 login.vue 组件
    render: function(createElements) {
        return createElements(login)
    }
})

配置 vue-loader 解析规则,使 webpack 能够渲染 .vue 组件,更新 webpack.config.js

var path = require('path')
var VueLoaderPlugin = require('vue-loader/lib/plugin'); // 新增

var htmlWebpackPlugin = require('html-webpack-plugin');		

module.exports = {
    entry: path.join(__dirname, './src/main.js'),   // 入口文件
    output: {
        // 指定输出项
        path: path.join(__dirname, './dist'),   // 输出路径
        filename: 'bundle.js'   // 输出文件名称
    },
    plugins: [
        new VueLoaderPlugin(), 	// 新增
        new htmlWebpackPlugin({
            template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
            filename: 'index.html'  // 设置生成内存页面名称
        })
    ],
    module: {
        rules: [	// 配置 .vue 正则匹配规则,使其能够解析 .vue 结尾的文件
            { test: /\.vue$/, use: 'vue-loader' }		// 新增
        ]
    }
}

login.vue

<template>
    <div>
        <h1>登录组件</h1>
    </div>
</template>

<script>

</script>

<script>

</script>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>webpack 中使用 vue</h1>
        <p>{{ msg }}</p>

        <login></login>
    </div>
</body>
</html>

运行 npm run dev 启动项目,会自动访问:http://127.0.0.1:3000

参考文章

  • https://www.cnblogs.com/yaogengzhu/p/10050823.html

webpack 中使用 vue

普通网页中使用 vue

在普通网页中使用 vue,大抵分为以下几步:

  • 通过 script 导入 vue.js
  • 创建一个 id 为 app 的 div 容器
  • 再通过 new Vue 得到一个 vm 实例

webpack 中使用 vue

1、安装 vue 包:cnpm i vue -S

2、导入 vue.js 包文件:

安装的 vue 包并不完整,而是 runtime-only 的包,该包比 vue.js 要小,缺失了部分 vue 的功能;对于 vue 中的 {{}} 模板语法、以及组件渲染等都不能实现,因此需要导入完整的 vue.js 包和安装第三方 loader 来解析以 .vue 结尾的组件。

导入完整的包

新安装的 vue 包文件都在 node_modules/vue/dist/ 目录下,要想导入具有完整功能的 vue.js 包,有两种方法:

  • main.js 中直接导入完整路径的 vue.js
// main.js  入口文件

// 原本的导入方式,只会导入 runtime-only 残缺的 vue 包,不推荐使用
impoet Vue from 'vue'	

// 推荐使用
import Vue from '../node_modules/vue/dist/vue.js'
  • webpack.config.js 添加 resolve 节点,指定 alias 别名
// webpack.config.js

module.exports = {
  ....
  resolve: {
    alias: { // 修改 Vue 被导入时候的包的路径
      "vue$": "vue/dist/vue.js"
    }
  }
}

webpack 中使用 vue 组件

webpack 中不能使用传统网页的方式,在 vm 实例中挂载 components 组件,而是需要单独定义 .vue 结尾的组件,具体步骤如下:

安装 vue 相关包

cnpm i vue -S
cnpm i vue-loader vue-template-compiler -D		// 解析 .vue 结尾的组件

1、新建 src/login.vue 组件:

<template>
  <div>
    <h1>这是登录组件,使用 .vue 文件定义出来的 --- {{msg}}</h1>
  </div>
</template>

<script>

</script>

<style>

</style>

以这种方式定义的组件,分为三部分:

  • template:组件元素部分
  • script:逻辑结构部分
  • style:样式部分

2、入口文件中导入 vue 包和组件 main.js

import Vue from '../node_modules/vue/dist/vue.js'

// 导入 login.vue 组件
import login from './login.vue'

var vm = new Vue({
    el: '#app',
    data: {
        msg: '123'
    },
    //components: {
    //    login
    //},
    
    // 渲染组件
    render: function(createElements) {
        return createElements(login)
    },
    
    // 精简写法
    // render: c => c(login)
})

3、配置匹配规则:

配置 vue-loader 解析规则,使 webpack 能够渲染 .vue 组件,更新 webpack.config.js

var path = require('path')
var VueLoaderPlugin = require('vue-loader/lib/plugin'); // 新增

var htmlWebpackPlugin = require('html-webpack-plugin');		

module.exports = {
    entry: path.join(__dirname, './src/main.js'),   // 入口文件
    output: {
        // 指定输出项
        path: path.join(__dirname, './dist'),   // 输出路径
        filename: 'bundle.js'   // 输出文件名称
    },
    plugins: [
        new VueLoaderPlugin(), 	// 新增
        new htmlWebpackPlugin({
            template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
            filename: 'index.html'  // 设置生成内存页面名称
        })
    ],
    module: {
        rules: [	// 配置 .vue 正则匹配规则,使其能够解析 .vue 结尾的文件
            { test: /\.vue$/, use: 'vue-loader' }		// 新增
        ]
    }
}

4、在页面中使用组件 index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!-- 这是容器 -->
  <div id="app">
    <p>{{msg}}</p>

    <login></login>

  </div>
</body>

</html>

注意

1、若在运行时出现: Cannot find module 'webpack/lib/node/NodeTemplatePlugin',可尝试删除 node_modules/ 目录,再重新安装依赖包:npm install --save-dev

2、若运行时出现:webpackvue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin,可尝试在 webpack.config.js 中添加 VueLoaderPlugin()

参考文章

  • https://www.cnblogs.com/yaogengzhu/p/10050823.html

export 和 export default 暴露成员

所谓暴露成员,就是将 A 中某个对象暴露给 B 或其他页面调用的一个过程。

Node 暴露成员的方式:

module.exports = {}
// 在Node中 使用 var 名称 = require('模块标识符')
// module.exports 和 exports 来暴露成员

ES6 中,使用 export 和 export default 来暴露成员:

var info = {
    name: 'rose',
    age: 18
}

export default info
export var title = '小星星'

两者区别

  • export default
    • 可以使用任意变量来接收
    • 一个模块中,只允许向外暴露一次
    • 一个模块中可以同时使用 export default 和 export 来向外暴露成员
  • export
    • 只能以 {} 来接收成员,多个成员,中间以逗号分隔,可以只接收其中一个(按需导出)
    • 接收的成员的变量必须与成员名一致,接收时可以给成员其别名,使用 as

示例

1、新建 src/test.js

var info = {
    name: 'rose',
    age: 18
}

export default info

export var title = "小星星"
export var subject = "哈哈"

2、入口文件中接收成员 main.js

import Vue from '../node_modules/vue/dist/vue.js'

import login from './login.vue'

// 导入(接收成员)
import info, {title, subject as sb} from './test.js'

var vm = new Vue({
    el: '#app',
    data: {
        msg: '123',
    },
    render: function(createElements) {
        return createElements(login)
    }
})

// 打印输出
console.log(info, title, sb)

注意:webpack 中使用 .vue 组件是通过 export default 来暴露成员的

<template>
    <div>
        <h1>登录组件</h1>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                msg: "123"
            };
        },
        methods: {
            show() {
                console.log("调用 show() 方法")
            }
        }
    }
</script>
    
<script>

</script>

webpack 中使用 vue-router 路由

vue-router 官网

项目结构

ProjectName:.
├─dist/				
├─node_modules/		
├─main				
│  └─Account.vue	
│  └─GoodList.vue	
├─src				
│  └─index.html		
│  └─login.vue	
│  └─App.vue	
│  └─main.js		
├─package.json		
├─package-lock.json
├─webpack.config.js		

1、安装:cnpm i vue-router -S

2、新建组件:

项目根目录,创建 App.vue

<template>
    <div>
        <h1>首页</h1>
    </div>
</template>

<script>
   
</script>
    
<script>

</script>

项目根目录创建 main/ 目录,main/ 中创建两个组件:Account.vue、GoodList.vue

// Account.vue
<template>
  <div>
    <h1>这是 Account 组件</h1>
  </div>
</template>


<script>
</script>

<style>

</style>


// GoodList.vue
<template>
  <div>
    <h1>这是 GoodList 组件</h1>
  </div>
</template>


<script>
</script>

<style>

</style>

3、使用路由来定位相关组件 main.js

import Vue from '../node_modules/vue/dist/vue.js'

// 1、导入路由包
import VueRouter from 'vue-router'

// 2、手动安装 VueRouter
Vue.use(VueRouter)

// import login from './login.vue'
import app from './App.vue'

// 导入相应组件
import account from './main/Account.vue'
import goodlist from './main/GoodList.vue'


// 3、创建路由对象
var router = new VueRouter({
    routes: [
        { path: '/account', component: account },
        { path: '/goodlist', component: goodlist },
    ]
})


var vm = new Vue({
    el: '#app',
    data: {
        msg: '123',
    },
    render: function(createElements) {
        return createElements(app)
    },
    router  // 4、将路由挂载到 vm 实例上
})

4、监听 Account.vue 和 GoodList.vue 组件路由,更新 App.vue

<template>
    <div>
        <h1>首页</h1>

        <router-link to="/account">Account</router-link>
        <router-link to="/goodlist">Goodslist</router-link>

        <router-view></router-view>
    </div>
</template>

<script>
   
</script>
    
<script>

</script>

App 组件我们将其定位为首页,是通过 vm 实例的 render 渲染出来的;而 Account.vue 和 GoodList.vue 组件是通过路由匹配监听到的,就不能直接通过 render 渲染,而是要将其放在 App.vue 组件中去渲染显示。

webpack 中使用 children 子路由

项目结构

ProjectName:.
├─dist/				
├─node_modules/		
├─main				
│  └─Account.vue	
│  └─GoodList.vue	
├─sub			// 子组件相关		
│  └─login.vue	
│  └─register.vue	
├─src				
│  └─index.html		
│  └─login.vue	
│  └─App.vue	
│  └─main.js		
├─package.json		
├─package-lock.json
├─webpack.config.js	

1、创建 sub/ 目录,里面分别创建 login.vue、register.vue,分别作为 Account.vue 的子组件:

// 登陆组件
<template>
    <div>
        <h1>登录组件</h1>
    </div>
</template>

<script>
export default {
    
}
</script>

<style scoped>

</style>

// 注册组件
<template>
    <div>
        <h1>注册组件</h1>
    </div>
</template>

<script>
export default {
    
}
</script>

<style scoped>

</style>

2、main.js

import Vue from '../node_modules/vue/dist/vue.js'

// 1、导入路由包
import VueRouter from 'vue-router'

// 2、手动安装 VueRouter
Vue.use(VueRouter)

// import login from './login.vue'
import app from './App.vue'

// 导入相应组件
import account from './main/Account.vue'
import goodlist from './main/GoodList.vue'
import login from './sub/login.vue'
import register from './sub/register.vue'



// 3、创建路由对象
var router = new VueRouter({
    routes: [
        { 
            path: '/account', 
            component: account,
            children: [
                { path: '/login', component: login },
                { path: '/register', component: register }, 
            ] 
        },
        { path: '/goodlist', component: goodlist },
    ]
})


var vm = new Vue({
    el: '#app',
    data: {
        msg: '123',
    },
    render: function(createElements) {
        return createElements(app)
    },
    router  // 4、将路由挂载到 vm 实例上
})

3、Account.vue 中渲染 login、register 相关组件:

<template>
  <div>
    <h1>这是 Account 组件</h1>

    <router-link to="/login">登录</router-link>
    <router-link to="/register">注册</router-link>

    <router-view></router-view>
  </div>
</template>


<script>
</script>

<style>

</style>

组件中 style 中 lang 属性和 scoped 属性

若想定义的样式只影响当前组件,而不影响全局,可以在组建中给 style 标签定义 scoped 属性(样式作用域):

// 登陆组件
<template>
    <div>
        <h1>登录组件</h1>
    </div>
</template>

<script>
export default {
    
}
</script>

<style scoped>
    div {
        color: red;
    }
</style>

注意:需要安装:cnpm i style-loader css-loader --save-dev 处理 .css 文件

若想启用 scss 或 less,需要为 style 元素设置 lang 属性:

<style lang="scss" scoped>

body {
  div {
    font-style: italic;
  }
}
</style>

注意:需要安装:cnpm i less-loader less -Dcnpm i sass-loader node-sass --save-dev 处理 .less、.scss 文件

抽离路由模块

将路由相关逻辑从 main.js 中抽离出来,减少代码耦合性,更便于项目管理:

1、路由模块相关 router.js

// 1、导入路由包
import VueRouter from 'vue-router'

// 导入相应组件
import account from './main/Account.vue'
import goodlist from './main/GoodList.vue'
import login from './sub/login.vue'
import register from './sub/register.vue'


// 3、创建路由对象
var router = new VueRouter({
    routes: [
        { 
            path: '/account', 
            component: account,
            children: [
                { path: '/login', component: login },
                { path: '/register', component: register }, 
            ] 
        },
        { path: '/goodlist', component: goodlist },
    ]
})

// 向外暴露 router 对象
export default router

2、入口文件 main.js

import Vue from '../node_modules/vue/dist/vue.js'


// import login from './login.vue'
import app from './App.vue'

// 1、导入路由包
import VueRouter from 'vue-router'

// 2、手动安装 VueRouter
Vue.use(VueRouter)

// 导入路由对象
import router from './router.js'

var vm = new Vue({
    el: '#app',
    data: {
        msg: '123',
    },
    render: function(createElements) {
        return createElements(app)
    },
    router  // 4、将路由挂载到 vm 实例上
})

项目结构

ProjectName:.
├─dist/				
├─node_modules/		
├─main				
│  └─Account.vue	
│  └─GoodList.vue	
├─sub			// 子组件相关		
│  └─login.vue	
│  └─register.vue	
├─src				
│  └─index.html		
│  └─login.vue	
│  └─App.vue	
│  └─main.js	
│  └─router.js		// 路由	
├─package.json		
├─package-lock.json
├─webpack.config.js	

注意:router.js 应该向外暴露路由对象,main.js 接收路由对象并将其挂载到 vm 实例中,两者都需要导入路由包文件

posted @ 2020-09-03 22:47  Hubery_Jun  阅读(234)  评论(0编辑  收藏  举报