1. Webpack集成Bootstrap

1.1 下载bootstrap3

npm i bootstrap3 -S

4. Webpack集成各种库_Vue

1.2 在index.js中引入bootstrap3

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

$(function() {

});

1.3 在index.html中使用bootstrap3中的样式

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

良辰美景奈何天,赏心乐事谁家院</h3>

<button class="btn btn-primary">Click me</button>

</body>

</html>

查看效果

4. Webpack集成各种库_html_02

2. Webpack集成Vue2.6

2.1 下载vue

npm i vue@2.6.12 -S

4. Webpack集成各种库_html_03

2.2 在index.js中引入vue

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

$(function() {

let app = new Vue({

el: "#app",

data: {

光年之外"

}

});

});

2.3 修改index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<div id="app">

{{msg}}

</div>

</body>

</html>

2.4 查看结果

启动webpack-dev-server,可以看到浏览器控制台报错了:

4. Webpack集成各种库_bootstrap_04

这是因为,我们在index.js中引入的vue资源,默认引入的是只能运行vue的环境,并不是开发vue的环境,如下图所示,默认引入的是runtime环境的资源:

4. Webpack集成各种库_html_05

为了解决这个问题,我们可以直接引入vue.min.js,如下:

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

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

$(function() {

let app = new Vue({

el: "#app",

data: {

光年之外"

}

});

});

查看效果

4. Webpack集成各种库_bootstrap_06

然而这种解决方法不优雅,下面使用一种更优雅的方式来解决这个问题,在webpack.config.js中加入以下配置来为vue定义别名:

4. Webpack集成各种库_html_07

修改webpack.config.js之后,要重启webpack-dev-server服务,然后在index.js中,引入vue资源:

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue' // 又改回 'vue' 这种写法了

$(function() {

let app = new Vue({

el: "#app",

data: {

光年之外"

}

});

});

查看效果

4. Webpack集成各种库_bootstrap_08

至此,Vue已经成功被webpack打包了。下面测试一下Vue中的组件开发。

2.5 在index.html中添加组件模板

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<div id="app">

</div>

<template id="t1">

<div>

原来姹紫嫣红开遍,似这般都付与断井颓垣。良辰美景奈何天,赏心乐事谁家院!

朝飞暮卷,云霞翠轩;雨丝风片,烟波画船——锦屏人忒看的这韶光贱!

</div>

</template>

</body>

</html>

2.6 在src/index.js中定义并注册组件

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

$(function() {

let myComponent = {

template: "#t1"

}

let app = new Vue({

el: "#app",

components: {

myComponent

}

});

});

查看效果

4. Webpack集成各种库_Vue_09

子组件也有自己的属性和方法,但是子组件和父组件,不能直接相互访问对方的属性和方法!

/*

以下引入了jquery资源,并且起了个名字叫 $

此后,在js代码中,但凡想使用jquery,就直接用 $ 就可以了

后面的资源路径,如果没有以 “.” 开头,则默认总是从node_modules开始寻找资源

后面的资源路径,如果确有以 “.” 开头,则就从当前路径开始寻找资源

*/

import $ from 'jquery'

import obj from '../data.json'

import './all.css'

import printMe from './print.js'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

/*

中接收一个函数,该函数就是一个回调函数,

该回调函数,会在页面加载完毕以后执行。

*/

$(function () {

let foo= {

"template": "#t1",

data() {

return {

刘德华",

"age": 62

}

},

methods: {

f2() {

console.log("zi.f2...");

}

}

}

let app = new Vue({

"el": "#app",

data: {

光年之外~~~"

},

methods: {

f1() {

console.log("fu.f1...");

}

},

注册子组件,注册到当前的app组件中,所以形成了父子组件的关系

是父组件, component是子组件

components: {

等价于 "foo": foo

}

})

})

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

父组件 -->

<div id="app">

{{msg}} <br>

点我</button>

<foo></foo>

</div>

子组件 -->

<template id="t1">

<div>

点点</button>

</div>

</template>

</body>

</html>

面试题:

Vue父子组件如何访问对方的属性和方法?

子组件如何访问父组件的属性:通过props属性。

子组件如何访问父组件的方法:通过 this.$emit()触发自定义事件

父组件如何访问子组件的属性:在子组件上添加一个ref属性,假设ref=xx, this.$refs.xx.属性

父组件如何访问子组件的方法:在子组件上添加一个ref属性,假设ref=xx, this.$refs.xx.方法

3. Webpack集成VueRouter

3.1 下载vue-router

npm i vue-router@3.5.3 -S

4. Webpack集成各种库_Vue_10

3.2 制作组件模板

在index.html中制作组件模板

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<div id="app">

<router-view></router-view>

</div>

<template id="t1">

<div>

<pre>

原来姹紫嫣红开遍,似这般都付与断井颓垣。良辰美景奈何天,赏心乐事谁家院!

朝飞暮卷,云霞翠轩;雨丝风片,烟波画船——锦屏人忒看的这韶光贱!

</pre>

</div>

</template>

</body>

</html>

3.2 导入路由模块

在index.js中导入路由模块,并使用

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

import VueRouter from 'vue-router'

Vue.use(VueRouter)

$(function() {

let myComponent = {

template: "#t1"

}

let router = new VueRouter({

routes: [

{ component: myComponent, path: '/myComponent'}

]

});

let app = new Vue({

el: "#app",

router

});

});

查看效果

4. Webpack集成各种库_html_11

4. 组件化开发

4.1 创建组件文件

在src目录下创建components目录,在其中创建App.vue

<template>

<div>

危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。

</div>

</template>

<script>

export default {

}

</script>

<style scoped>

</style>

4.2 修改index.html

不用再在index.html编写任何组件的模板了,毕竟组件已经提取出来成为单独的文件了:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<div id="app">

<router-view></router-view>

</div>

</body>

</html>

4.3 引入App.vue

在src/index.js中引入App.vue,并使用

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

import VueRouter from 'vue-router'

Vue.use(VueRouter)

// 引入App组件

import App from './components/App.vue'

$(function() {

let router = new VueRouter({

routes: [

注册App组件到路由中

{ component: App, path: '/App'}

]

});

let app = new Vue({

el: "#app",

使用路由

router

});

});

(在webpack-dev-server开启的情况下)保存index.js时,会发现有报错信息:

4. Webpack集成各种库_bootstrap_12

这是因为webpack默认无法打包vue资源。为了让webpack能够打包vue资源,需要下载 vue-loader 和 vue-template-compiler。

4.4 让Webpack能打包Vue文件资源

npm i vue-loader@15.9.5 vue-template-compiler@2.6.12 -D

注意vue-template-compiler要与vue的版本一致,都是2.6.12

4. Webpack集成各种库_bootstrap_13

修改webpack.config.js中的module:

4. Webpack集成各种库_bootstrap_14

此时重新启动webpack-dev-server,还是会报错:

4. Webpack集成各种库_html_15

这是因为vue-loader从15+版本以后,配置方法有了变化,为了解决以上的问题,还需要在webpack.config.js中配置一个Plugin:

4. Webpack集成各种库_html_16

再次启动webpack-dev-server,发现没有报错:

4. Webpack集成各种库_bootstrap_17

查看效果:

4. Webpack集成各种库_Vue_18

4.5 优化

实际开发中,index.html中的<div id="app"></div>元素中不会编写任何内容,就连<router-view></router-view>元素也不用写,这个div通常会被App.vue这个组件重新渲染(代替)。

改写index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge">

<meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

这里只留下div,其中的 router-view元素已经被删除了 -->

<div id="app">

</div>

</body>

</html>

改写index.js

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

import VueRouter from 'vue-router'

Vue.use(VueRouter)

import App from './components/App.vue'

$(function() {

let myComponent = {

template: "#t1"

}

let router = new VueRouter({

routes: [

{ component: App, path: '/App'}

]

});

let app = new Vue({

el: "#app",

函数的参数由Vue框架传入

该参数又是另外一个函数,参数的

名字可以自己随意指定,这里指定

为:createElement

render: function(createElement) {

函数接收一个组件作为参数

返回该组件的html表示形式

return createElement(App);

函数返回什么内容,那么什么内容就会把

中的<div id="app"></div>元素给替换掉!

},

router

});

});

查看效果:

4. Webpack集成各种库_html_19

4.6 简单开发

开发App.vue

<template>

<div>

小星星少儿托管平台 <br>

<router-view></router-view>

</div>

</template>

<script>

export default {

}

</script>

<style scoped>

</style>

开发Login.vue

<template>

<div>

username: <input type="text"> <br>

password: <input type="text"> <br>

登录</button>

注册</button>

</div>

</template>

<script>

export default {

methods: {

login() {

console.log('login...');

},

regUI() {

this.$router.push("/Reg");

}

}

}

</script>

<style scoped>

</style>

开发Reg.vue

<template>

<div>

username: <input type="text"> <br>

password: <input type="text"> <br>

confirm: <input type="text"> <br>

注册</button>

返回</button>

</div>

</template>

<script>

export default {

methods: {

reg() {

console.log('reg...');

},

loginUI() {

this.$router.push("/Login");

}

}

}

</script>

<style scoped>

</style>

开发index.js

4. Webpack集成各种库_Vue_20

测试:

4. Webpack集成各种库_html_21

4.7 抽离路由模块

目前index.js的内容,有点太杂乱了,下面我们把路由模块从index.js中抽离出来。

在src下创建router.js文件,内容如下:

import Vue from 'vue'

import VueRouter from 'vue-router'

Vue.use(VueRouter)

import Login from './components/Login.vue'

import Reg from './components/Reg.vue'

let router = new VueRouter({

routes: [

{ component: Login, path: '/'},

{ component: Login, path: '/Login'},

{ component: Reg, path: '/Reg'},

]

});

export default router

index.js的内容:

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

import router from './router.js'

import App from './components/App.vue'

$(function() {

let app = new Vue({

el: "#app",

render: function(createElement) {

return createElement(App);

},

router

});

});

注意,App.vue这个组件还是要留在index.js中的。

测试:

4. Webpack集成各种库_html_22

5. Webpack集成axios

5.1 下载axios

npm i axios@0.24.0 -S

4. Webpack集成各种库_html_23

5.2 导入axios

在index.js中导入axios

import $ from 'jquery'

import 'bootstrap3/dist/css/bootstrap.min.css'

import Vue from 'vue'

import router from './router.js'

import axios from 'axios'

// axios.defaults.baseURL = '配置请求前缀'

Vue.prototype.$axios = axios // 把axios挂载到Vue的原型上

import App from './components/App.vue'

$(function() {

let app = new Vue({

el: "#app",

render: function(createElement) {

return createElement(App);

},

router

});

});

5.3 使用

login() {

this.$axios.post("http://localhost:8080/users");

},

注意,使用axios发起ajax请求时,务必解决跨域问题,我们可以在后端解决跨域问题,如下:

4. Webpack集成各种库_html_24

axios的post等方法的第三个参数为配置对象,可以设置请求头的信息:

axios.post(url, data, config).then(...);

配置对象例子:

const config = {

headers: {

"Content-Type": "application/x-www-form-urlencoded",

},

};

用于发送name=andy&age=22形式的数据,类型是字符串

const config2 = {

headers: {

"Content-Type": "application/json",

},

};

用于发送json形式的数据,类型是字符串

const config = {

headers: {

"Content-Type": "multipart/form-data",

},

};

用于文件上传,要搭配FormData一起使用,如下:

// id为file的元素是一个文件域

const fileElement = document.querySelector("#file");

const file = fileElement.files[0];

const formData = new FormData();

formData.append("file", file);

formData.append("filename", "filename...");

axios.post("/test", formData, config).then((resp) => {

this.$message({

type: "success",

message: resp.data,

});

});

注意,当我们使用axios传送一个FormData数据给后端时,此时的Content-Type请求头默认就是multipart/form-data

两个url是否同源,取决于以下3个部分: 协议、ip地址、端口号。

只要协议、ip地址、端口号都想用,才算作同源,有一个不相同,就算作不同源。

比如:

http://localhost:8080/1.html 和 http://localhost:8080/2.html 同源

http://localhost:8080/1.html 和 https://localhost:8080/1.html 不同源

http://127.0.01:8080/1.html 和 http://localhost:8080/1.html 不同源

http://localhost:8080/ 和 http://localhost:8888 不同源!

不同源的连个资源之间不能通信!

为了解决跨域问题,需要在后端添加配置:

@Configuration

public class MyWebMvcConfigurer implements WebMvcConfigurer {

/**

跨域配置

*

* @param registry

*/

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

允许任意客户端访问

允许客户端用任意方式请求

允许客户端发送的请求中可以包含任意请求头

}

}

6. Webpack集成Element-UI

Element-UI官方网址: https://element.eleme.cn/#/zh-CN

6.1 安装

npm i element-ui -S

4. Webpack集成各种库_html_25

6.2 Element-UI Hello World

创建一个Vue组件:ElementUI.vue,在其中编写Element-UI的组件

4. Webpack集成各种库_Vue_26

在router.js中引入ElementUI.vue,并注册到路由器对象中:

4. Webpack集成各种库_Vue_27

在index.js中引入ElementUI:

4. Webpack集成各种库_Vue_28

查看效果:

4. Webpack集成各种库_bootstrap_29

6.4 Element-UI 布局+布局容器

<template>

<div>

<el-row>

<el-col :span="12" :offset="6">

<el-container>

<el-header>Header</el-header>

<el-container>

<el-aside>Aside</el-aside>

<el-main>Main</el-main>

</el-container>

<el-footer>Footer</el-footer>

</el-container>

</el-col>

</el-row>

</div>

</template>

<script>

export default {

data() {

return {

visible: false,

};

},

};

</script>

<style scoped>

.el-header,

.el-footer {

background-color: #b3c0d1;

color: #333;

text-align: center;

line-height: 60px;

}

.el-aside {

background-color: #d3dce6;

color: #333;

text-align: center;

line-height: 560px;

}

.el-main {

background-color: #e9eef3;

color: #333;

text-align: center;

line-height: 560px;

}

</style>

效果:

4. Webpack集成各种库_bootstrap_30

更多Element-UI组件的使用,就直接参照官方文档吧。

7. Webpack集成Vuex

Vue中的父子组件之间不能直接相互访问对方的属性和方法,非要互相访问,可以按照以下的方式进行:

1. 子组件方法父组件的属性: props: ["abc"] <Zi :abc="父组件的属性名" ></Zi>

2. 子组件方法父组件的方法: this.$emit("haha") <Zi @haha="父组件的方法"></Zi>

3. 父组件方法子组件的属性: a.给子组件添加一个ref="foo", b. 在父组件的方法中:this.$refs.foo.子组件属性

4. 父组件方法子组件的方法: a.给子组件添加一个ref="foo", b. 在父组件的方法中:this.$refs.foo.子组件方法

我们已经知道,Vue中的父子组件之间不能直接相互访问对方的属性和方法。如果非要让父子组件之间能够访问对方的属性和方法,会很麻烦,尤其是嵌套多层的父子组件。如下:

4. Webpack集成各种库_html_31

为了简化父子组件之间相互访问难的问题,Vuex就应运而生了:

4. Webpack集成各种库_bootstrap_32

7.1 安装Vuex

npm i vuex@3.5.1 -s

4. Webpack集成各种库_Vue_33

7.2 store.js

在src下创建store.js

4. Webpack集成各种库_html_34

7.3 引入

在index.js中引入store.js,并使用:

4. Webpack集成各种库_bootstrap_35

在父组件中引入store之后,该父组件下的所有子组件就都能访问到store中的数据了

7.4 使用

创建Foo组件

4. Webpack集成各种库_bootstrap_36

创建Bar组件

4. Webpack集成各种库_Vue_37

在路由模块中引入:

4. Webpack集成各种库_Vue_38

查看效果:(测试时,必须在同一个窗口之内,否则Vuex中存储的状态无法共享)

4. Webpack集成各种库_bootstrap_39

7.5 改变需求

现在需要在Foo和Bar组件中,显示count属性的前后,加上“[ ]”,这需要使用Vuex对象中的getters。修改store.js

4. Webpack集成各种库_Vue_40

修改Foo.vue(Bar.vue也是这样改)

4. Webpack集成各种库_html_41

查看效果(必须在同一个页面中测试,否则无法共享Vuex对象中的数据)

4. Webpack集成各种库_html_42

8. Webpack集成zTree

zTree官网: http://www.treejs.cn/v3/main.php#_zTreeInfo

8.1 下载ztree

npm i ztree -s

8.2 引入

因为ztree是基于jQuery的,所以我们需要先导入jquery,再导入ztree

npm i jquery -s

import $ from 'jquery'

import 'ztree'

import 'ztree/css/zTreeStyle/zTreeStyle.css'

但是浏览器会报错,说ztree找不到jQuery:

4. Webpack集成各种库_bootstrap_43

这是因为,ztree依赖于jQuery,而我们在代码中 import $ from 'jquery' 是不够的,这仅仅只是解决了我们自己的代码对jQuery的依赖。

解决方案:针对于自己手动创建的前端项目,在webpack.config.js的顶部引入webpack插件

const webpack = require('webpack')

然后在plugins中配置:

plugins: [

new HtmlWebpackPlugin({

title: 'test...',

template: './index.html'

}),

new CleanWebpackPlugin(),

new VueLoaderPlugin(),

new webpack.ProvidePlugin({

$: 'jquery',

jquery: 'jquery',

jQuery: 'jquery',

'window.jQuery': 'jquery'

})

],

解决方案:针对于脚手架vue cli3,要在项目根目录下创建vue.config.js,配置内容如下:

const webpack = require('webpack')

module.exports = {

chainWebpack: config => {

config.plugin('provide').use(webpack.ProvidePlugin, [{

$: 'jquery',

jquery: 'jquery',

jQuery: 'jquery',

'window.jQuery': 'jquery'

}])

}

}

8.3 标准json构建ztree

demo1

<div>

<ul id="basicTree" class="ztree"></ul>

</div>

// 设置参数

let settings = {};

// 设置树的数据

let nodes = [

菜单一"},

菜单二"}

]

// 初始化树

$.fn.zTree.init($("#basicTree"), settings, nodes);

4. Webpack集成各种库_bootstrap_44

demo2

<ul id="basicTree" class="ztree"></ul>

// 设置参数

let settings = {};

// 设置树的数据

let nodes = [

菜单一"},

菜单二", children:[

菜单二-1"},

菜单二-2"},

菜单二-3"}

]}

]

// 初始化树

$.fn.zTree.init($("#basicTree"), settings, nodes);

4. Webpack集成各种库_bootstrap_45

8.4 简单数据构建ztree(推荐)

demo

<ul id="basicTree" class="ztree"></ul>

// 设置参数

let settings = {

data: {

simpleData: {

启用简单树

}

}

};

// 设置树的数据

let nodes = [

菜单一"},

菜单二"},

菜单一-1"},

菜单一-2"},

]

// 初始化树

$.fn.zTree.init($("#basicTree"), settings, nodes);

4. Webpack集成各种库_Vue_46

8.5 定制

可以手动指定idKey、pIdkey、name对应的json属性,如下:

// 设置参数

let settings = {

data: {

key: {

name: "pname"

},

simpleData: {

启用简单树

idKey: "pid",

pIdKey: "parent"

}

}

};

// 设置树的数据

let nodes = response.data.data;

// 初始化树

$.fn.zTree.init($("#basicTree"), settings, nodes);