Vue.js(第五天)
父子组件之间的传值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<com1 v-bind:parentmsg = 'msg' @func = "getMsgFromSon"></com1>
</div>
<template id="tmp1">
<div>
<h1>这是子元素 --- {{parentmsg}}</h1>
<input type="button" value="向父组件传递消息" @click="sendMsg" />
</div>
</template>
<script type="text/javascript">
var com1 = {
template: '#tmp1',
data(){
return{
msg: '给你一些钱,去挥霍吧!'
}
},
props:['parentmsg'],
methods:{
sendMsg(){
this.$emit('func',this.msg);
}
}
}
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
msg: '这是父组件中的数据,爸爸有100块钱,你要不,儿子!',
msgFromSon:''
},
methods:{
getMsgFromSon(data){
this.msgFromSon = data
console.log(this.msgFromSon)
}
},
components:{
com1
}
})
</script>
</body>
</html>
父组件向子组件传值
- 在父组件的data中:msg: ‘这是父组件中的数据,爸爸有100块钱,你要不,儿子!’,
- 然后:
- 再将:props:[‘parentmsg’],
- 最后再子组件中:
这是子元素 — {{parentmsg}}
子组件向父组件传值
-
首先在子组件中的data中:msg: ‘给你一些钱,去挥霍吧!’
-
在父组件中data:msgFromSon:’’
-
在子组件中:<input type=“button” value=“向父组件传递消息” @click=“sendMsg” /> 触发sendMsg方法
-
然后在:<com1 @func = “getMsgFromSon”>
- sendMsg(){ this.$emit(‘func’,this.msg); }
-
getMsgFromSon(data){ this.msgFromSon = data<br />console.log(this.msgFromSon)}
-
通过这几步,可以将子组件的值传递给父组件。
路由的基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
<!-- 1.导入包 -->
<script src="./lib/vue-routerv3.1.5.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<router-link to="login">登录</router-link>
<router-link to="register">注册</router-link>
<!-- 容器 -->
<router-view></router-view>
</div>
<script type="text/javascript">
// 2.创建子组件
var login = {
template:'<h3>这是登陆子组件,这个组件是 巴伯本 开发的</h3>'
}
var register = {
template:'<h3>这是登陆子组件,这个组件是 奔波霸 开发的</h3>'
}
// 3.创建一个路由对象
var router = new VueRouter({
routes:[ // 路由规则数组
{path:'',component:login},
{path:'/login',component:login},
{path:'/register',component:register}
]
})
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
// router:router
router
})
</script>
</body>
</html>
- 路由对象的匹配。31行
- 路由对象的注册。50行
名称案例
methods方法实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 分析: -->
<!-- 1. 我们要监听文本框数据的改变,这样才能知到 什么时候去拼接 出一个fullname -->
<!-- 2. 如何监听文本框的数据改变呢??? -->
<input type="text" v-model="firstname" @keyup="getFullname"/> +
<input type="text" v-model="lastname" @keyup="getFullname"/> =
<input type="text" v-model="fullname"/>
</div>
<script type="text/javascript">
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
firstname: '',
lastname: '',
fullname: ''
},
methods:{
getFullname(){
this.fullname = this.firstname + '-' + this.lastname
}
}
})
</script>
</body>
</html>
- 通过@keyup监听键盘
- 通过v-model="firstname"进行数据的双向绑定
- 通过methods方法实现字符串的叠加
- this.fullname = this.firstname + ‘-’ + this.lastname
watch监视数据的变化
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="firstname"/> +
<input type="text" v-model="lastname" /> =
<input type="text" v-model="fullname"/>
</div>
<script type="text/javascript">
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
firstname: '',
lastname: '',
fullname: ''
},
methods:{
},
watch:{ // 使用这个属性,可以监视data 中指定的数据变化,然后触发这个 watch 中对应的 function 处理函数
firstname: function(newVal,oldVal){
// 这儿上边的firstname 可以加引号,也可以不加引号。只要在firstname 中没有加‘-’都可以不加引号。
this.fullname = newVal + '-' + this.lastname
},
"lastname": function(newVal){
this.fullname = this.firstname + '-' + newVal
}
}
})
</script>
</body>
</html>
- 使用这个属性,可以监视data 中指定的数据变化,然后触发这个 watch 中对应的 function 处理函数
- 这儿上边的firstname 可以加引号,也可以不加引号。只要在firstname 中没有加‘-’都可以不加引号。
- watch可以监听好多变化,比如路由的变化。
- watch可以监听并且保留前后的变化。(newVal,oldVal)
watch监听路由的变化
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
<!-- 1.导入包 -->
<script src="./lib/vue-routerv3.1.5.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<router-link to="login">登录</router-link>
<router-link to="register">注册</router-link>
<!-- 容器 -->
<router-view></router-view>
</div>
<script type="text/javascript">
// 2.创建子组件
var login = {
template:'<h3>这是登陆子组件,这个组件是 巴伯本 开发的</h3>'
}
var register = {
template:'<h3>这是登陆子组件,这个组件是 奔波霸 开发的</h3>'
}
// 3.创建一个路由对象
var router = new VueRouter({
routes:[ // 路由规则数组
{path:'',component:login},
{path:'/login',component:login},
{path:'/register',component:register}
]
})
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
// router:router
router,
watch:{
// this.$route.path
'$route.path': function(newVal,oldVal){
// console.log(newVal + ' --- ' + oldVal)
if (newVal == '/login') {
console.log('欢迎进入登陆页面!')
} else if (newVal == '/register'){
console.log('欢迎进入注册页面!')
}
}
}
})
</script>
</body>
</html>
- 路由的监听通过’ r o u t e . p a t h ′ 实 现 , 也 就 是 t h i s . route.path' 实现,也就是this. route.path′实现,也就是this.route.path
computed计算属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="lib/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 分析: -->
<!-- 1. 我们要监听文本框数据的改变,这样才能知到 什么时候去拼接 出一个fullname -->
<!-- 2. 如何监听文本框的数据改变呢??? -->
<input type="text" v-model="firstname" /> +
<input type="text" v-model="middlename" /> +
<input type="text" v-model="lastname" /> =
<input type="text" v-model="fullname"/>
<p>{{fullname}}</p>
<p>{{fullname}}</p>
<p>{{fullname}}</p>
<p>{{fullname}}</p>
</div>
<script type="text/javascript">
//创建Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
firstname: '',
lastname: '',
middlename: ''
},
methods:{
},
computed:{
// 在computed 中共,可以定义一个些属性,这些属性叫做计算属性,计算属性的本质就是一个方法,只不过,我们在使用这些计算属性的时候,是把他们的名称当作属性直接来使用的,并不会吧计算属性当作方法去调用。
// 注意1:计算属性,在引用的时候,一定不要加() 去调用,直接把他当作 普通 属性去使用就好!
// 注意2:只要计算属性,这个function 内部,所用到的任何data 中的数据发生了变化,就会重新计算这个属性的值。
// 注意3:计算属性的求值结果,会被缓存起来,方便下次使用;如果计算属性方法中,所以来的任何数据都没有发生变化,则不会重新对计算结果求值。
'fullname': function(){
console.log('ok')
return this.firstname + '-' + this.middlename + '-' + this.lastname
}
}
})
</script>
</body>
</html>
- 在computed 中,可以定义一个些属性,这些属性叫做计算属性,计算属性的本质就是一个方法,只不过,我们在使用这些计算属性的时候,是把他们的名称当作属性直接来使用的,并不会吧计算属性当作方法去调用。
- 注意1:计算属性,在引用的时候,一定不要加() 去调用,直接把他当作 普通 属性去使用就好!
- 注意2:只要计算属性,这个function 内部,所用到的任何data 中的数据发生了变化,就会重新计算这个属性的值。
- 注意3:计算属性的求值结果,会被缓存起来,方便下次使用;如果计算属性方法中,所以来的任何数据都没有发生变化,则不会重新对计算结果求值。
网页中引入静态资源多了以后会引起什么问题???
- 网页加载速度慢,因为我们要发起很多二次请求
- 要处理错综复杂的依赖关系。
如何解决以上这两个问题:
- 合并、压缩、精灵图、图片的Base64编码
- 可以使用之前学过的requireJS、也可以使用webpack解决各个包之间复杂的依赖关系。
- 所有操作都是为了解决用户的体验,提高网页加载速度,解决二次请求。
webpack
什么是 ?
- webpack 是前端项目构建工具,它是基于Node.js 开发出来的一个前端工具。
- webpack 是基于整个项目进行构建的。
webpack
打包构建.
- webpack 能够处理JS文件的相互依赖关系;
- webpack 能够处理JS的兼容问题,把高级的、浏览器不能识别的语法,转为低级的浏览器可以识别的语法。
在文档主目录下新建一个
main.js
——这儿用来导入相关的js,css 文件
在文档主目录下新建一个 webpack.config.js
文件
- 这个配置文件,起始是一个JS文件,通过Node 中的操作模块,向外暴漏一个 配置对象
- 在这儿确定了打包的入口和出口地址。
- enter 确定了要打包的文件
- output 规定了打包好文件要输出到哪个文件中去,以及指定输出的文件的名称。
const path = require('path')
module.exports = {
mode:'development' ,// 设置mode
// mode 有两种模式 development 开发模式 production 生产模式
entry:
{
main:'./src/main.js', //入口,表示要使用的webpack 打包哪个文件
},
output:{// 输出文件相关配置
path:path.resolve(__dirname,'./dist'),// 指定 打包好的文件,输出到哪个目录中去
filename:'bundle.js'// 这是 指定输出的文件的名称
}
}
webpack
安装
- webpack 是基于node.js 运行的。
- webpack 安装前提条件是必须安装node.js。
- node.js 下载路径——node下载
- 通过
npm
全局安装-g
webpack - 安装命令:
cnpm i webpack -g
webpack
初始化
npm init -y
- 在这儿会在文档的主目录下新建一个
package.json
webpack
处理js类文件
-
webpack 默认只能打包处理 JS 文件,无法处理非 JS 文件。
-
需要导入哪类 JS 文件,只需要通过控制台导入相关的 JS 文件即可!
-
导入JS
cnpm i 【js文件名】 -d
-
cnpm 得通过 npm 安装.
-
npm 是node.js版本中自带的.
-
通过
npm
导入之后,在 main.js 中通过import $ from 'JS文件名'
引入。
直接进行文件打包
- 运行的命令格式: 【webpack 要打包的文件的路径 打包好的输出文件路径 】 但是这个是webpack3 中的。
webpack .\src\main.js-o .\dist\bundle.js --mode=development
这是webpack4 中的。
经过以上处理之后就可以直接使用 命令:webpack
直接进行打包
- 当我们在,控制台名直接输入webpack 做了以下几步:
- 首先,webpack发现,我们并没有通过命令的形式,给它指定入口和出口
- webpack 就会去项目的根目录中,查找一个叫‘webpack.config.js’的配置文件
- 当找到配置文件之后,webpack 会去解析执行这个配置文件,当解析执行完后,就得到了配置文件中导出的配置文件对象。
- 当webpack 拿到配置对象后,就拿到了配置文件中指定的入口和出口,然后进行打包构建。
webpack
处理CSS文件
使用 import 语法,导入css 样式表
import './CSS/index.css'
import './CSS/index.less'
import './CSS/index.scss'
注意: webpack ,默认只能打包处理 JS 类型的文件,无法处理其他的非 JS 类型的文件;
如果非要处理非 JS 类型的文件,我们需要手动安装一些合适的第三方 loader 加载器;
1. 如果想要打包处理 css 文件,需要安装 `npm i style-loader css-loader -D`
2. 打开 webpack.config.js 这个配置文件,在里面新增一个配置节点,叫做 module ,它是一个对象;
在这个 modlue 对象身上,有个 rules 属性,这个 rules 数组;这个数组中,存放了所有第三方文件的
匹配和处理规则。
module.exports = {
module:{ // 这个节点,用于配置所有的第三方模块加载器。
rules:[ // 所有第三方模块的匹配规则
{test:/\.css$/,use:['style-loader','css-loader']}, // 配置处理 .css 问文件的第三方loader 规则
{test:/\.less$/,use:['style-loader','css-loader','less-loader']}, // 配置处理 .less 文件的第三方包 loader 规则
{test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}, // 配置处理 .scss 文件的第三方loader 规则
]
}
}
使用 webpack-dev-server
工具,来实现自动打包编译的功能
在package.json
中实现
- 运行
npm i webpack-dev-server -D
把这个工具安装到项目的本地开发环境依赖 - 安装完毕后,这个工具的用法个webpack 命令完全一样!
- 由于,我们是在项目中本地安装的 webpack-dev-server ,所以无法把它当作脚本命令在powershell终端中直接运行;(只有那些安装到全局 -g 的工具们,才能在终端中正常运行)。
- 注意: webpack-dev-server这个工具,如果想要正常运行,要求,在本地项目中,必须安装webpack
- webpack-dev-server 帮我们打包生成的 bundle.js 文件,并没有存放在实际的物理磁盘中,而是直接托管到了电脑的内存中,多以,我们在项目根目录中,根本找不到打包好的
bundle.js
; - 我们可以认为 webpack-dev-server 把打包好的文件,以一种虚拟的形式,托管到了我们项目中的根目录中,虽然我们看不到它,但是,我们可以认为,和
dist
src
node_modules
平级,有一个看不见的文件,叫做bundle.js - 在
package.json
中的script
中添加这个就可以开启自动打包"dev2": "webpack-dev-server --open --port 3000 --contentBase src --hot"
--open
自动打开浏览器--port 300
启动的时候的运行端口contentBase src
指定托管的目录--hot
启用热更新
- 启动 webpack-dev-server:
npm run dev
在webpack.config.js
中配置dev-server
const webpack = require('webpack')
// 启用热更新的第 2 步
module.exports = {
devServer:{ // 这是配置dev-server 命令参数的第二种形式,相对来说这种方式麻烦一些
// --open --port 3000 --contentBase src --hot
open:true,// 自动打开浏览器
port:3000,// 这只启动的时候的运行端口。
contentBase:'src',// 指定托管的根目录
hot:true // 启用热更新 de 第一步
},
plugins:[ //配置插件的节点
new webpack.HotModuleReplacementPlugin() // new 一个热更新的模块对象,这是启用哦那个热更新的第三步
]
}
使用html-webpack-plugin
插件
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins:[ //配置插件的节点
new htmlWebpackPlugin({ // 创建一个在内存中生成的HTML页面插件。
template:path.join(__dirname,'./src/index.html'), // 指定模板页面,将来会根据指定的页面路径,去生成内存中的页面
filename: 'index.html' // 指定生成的页面的名称
})
],
}
npm i html-webpack-plugin -d
- 导入在内存中生成HTML 页面中的插件
- 只要是插件,都一定要放到 plugins 节点中去
- 这个插件的两个作用:
- 自动在内存中根据指定页面生成一个页面生成一个内存中的页面。
- 自动把打包好的 bundle.js 追加到页面中去。
- 这么处理之后,在html中就不需要
<script src="/bundle.js"></script>