vue学习(4)–响应式数组、JavaScript高阶函数、v-model双向绑定
一、响应式数组
1 | btnClick() { |
二、JavaScript高阶函数
关于for循环
1、普通for循环
1 | let total = 0, |
2、for(let i in this.books)
1 | let total = 0, |
3、for(let item of this.books)
1 | let total = 0, |
编程范式:命令式范式/声明式范式
filter
对数组进行筛选
filter中回调函数有一个要求:必须返回boolean
返回true时,函数内部会自动将这次回调的n加入数组
返回false时,函数内部会过滤掉这次n
1 | let nums = [10,11,13,44,135,324,555] |
map
- 对数组统一操作
1 | let new2Nums = newNums.map(function(n){ |
reduce
- 对数组中所有内容进行汇总
1 | let new2Nums = [20, 10, 50, 20] |
再简单一些完成上述操作
1 | let total = nums.filter(function(n){ |
或者使用指向函数
1 | let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n), pre + n) |
三、v-model双向绑定
原理:实现表单元素和数据的双向绑定
1 | <input type="text" v-model="message"/> |
v-model相当于:
- v-bind绑定一个value元素
- v-on指令给当前元素绑定input事件
radio
1 | <label for="male"> |
chexbox
单选:大多用在那种同意协议注册那种
1 | <label for=""> |
多选:
1 | <input type="checkbox" value="1" v-model="count"/>1 |
正常使用时
1 | <label v-for="item in books"> |
v-model修饰符
lazy修饰符
- 默认情况下,v-model默认时在input事件中同步输入数据。一旦发生数据改变data中的数据就会自动改变
- lazy修饰符可以让数据在失去焦点或者回车的时候才会更新
number修饰符
- 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当作字符串类型进行处理
- 有时希望可以处理的是数字的时候就可以通过number修饰符将输入框中输入的内容自动转成数字类型
trim修饰符
- 如果输入的内容首位有很多空格,可以通过trim修饰符过滤内容左右两边的空格
vue学习(5)–组件化的基本使用、父子组件间的访问和传递数据
一、组件化的基本使用
创建组件构造器对象
1
2
3
4
5
6
7
8const cpnC = Vue.extend({
template: `
<div>
<h2>
标题
</h2>
</div>`
})``(模版字符串)是ES6中的新的定义字符串的语法,最大的特点就是可以换行
1
2
3
4
5
6>//使用''的话,换行要用+
const str = 'abc' +
'bcd'
>//使用``的话
const str = `abc
bcd`注册组件
1
Vue.component('my-cpn', cpnC)
使用组件
1
2
3<div id='app'>
<my-cpn></my-cpn>
</div>
整体代码
1 | <div id='app'> |
Vue.extend()
- 调用Vue.extend()创建的是一个组件构造器
- 通常在创建组件构造器时,传入template代表我们自定义组件的模版。
- 该模版就是使用到组件的地方,要显示的HTML代码
- 不过现在从vue2.x之后几乎不像这样写了
Vue.component()
- 调用Vue.component()是将刚才的组件构造器注册成一个组件,并且给它起一个组件的标签名称。
- 所以要传入两个参数:1、注册组件的标签名 2、组件构造器
组件还需要挂载在某个vue实例下才会生效
二、全局组件和局部组件
直接在script中写这个的就是全局组件
1 | Vue.component('my-cpn', cpnC) |
如果在vue实例下注册就是局部组件
1 | compotents: { |
父组件和子组件
1 | //子组件 |
组件的语法糖使用
省去了调用Vue.extend()的步骤,而是直接可以使用一个对象来代替。
- 全局组件创建注册语法糖:
1 | Vue.component('my-cpn', { |
- 局部组件创建注册语法糖:
1 | const app = new Vue({ |
若在script中写太多html代码不好看,可以将其分离:
1 | <script type="text/template" id="cpn"> |
组件不可以访问vue实例数据。vue组件应该有自己保存数据的地方。
组件数据存于data()中,data必须是一个函数,其返回一个对象,对象内部保存数据。
1
2
3
4
5
6
7
8 Vue.component('my-cpn', {
template: `#cpn`,
data() {
return {
title: 'abc'
}
}
})
三、父子组件之间传递数据
父传子:props
1 | <!-- Vue实例模版 --> |
props数据验证
1 | props: { |
子传父(自定义事件)
1 | <!-- 父组件模版 --> |
自定义事件的流程
- 在子组件中,通过$emit()来触发事件。
- 在父组件中,通过v-on来监听子组件事件
四、父子组件的访问
- 父组件访问子组件:
$children
或$refs
- 子组件访问父组件 :
$parent
父访问子
$children
:一般用于取出所有子组件的message状态。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
<button @click="btnClick">1212</button>
</div>
<template id="cpn">
<div>我是子组件</div>
</template>
<script src="vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!'
},
methods: {
btnClick() {
// 1、$children
console.log(this.$children);
console.log(this.$children[2].name);
}
},
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '子组件的name'
}
}
},
}
})
</script>$refs
=>对象类型, 默认是一个空对象1
2
3
4
5
6<cpn ref="aaa"></cpn>
btnClick() {
//2、$refs
console.log(this.$refs.aaa);
}
Vue学习(6)-插槽、模块化导入导出、webpack基础配置使用
一、插槽的基本使用
- 插槽的基本使用:
<slot></slot>
- 插槽的默认值:例
<slot><button>101</button></slot>
- 如果有多个值,同时放入到组件中进行替换时,一起作为替换元素。
1 | <div id="app"> |
具名插槽
可以有多个插槽,并且对专门的其中一个插槽进行修改时就需要用到具名插槽:
1 | <div id="app"> |
父组件模版的所有东西都会在父级作用域内编译;子组件模版的所有东西都会在子级作用域内编译。
插槽方面在新版本里使用v-slot,不过好像不经常用以后再补。。。
二、模块化的导入和导出
ES
使用
export
指令导出模块对外提供的接口,再通过import
命令来加载对应的模块先在HTML中引入两个js文件,并且类型设置module
1
<script src="main.js" type="module"></script>
想要导出时:
1 | let flag = ture; |
导入时:
1 | import {flag} from "导入信息原文件地址" |
某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而是让导入者可以自己来命名,那么就可以使用
export default
:
1 | export default function () { |
1 | import xxx from "./" |
export default
在同一个模块中不允许存在多个。
Commonjs
导出
1
2
3
4
5
6
7
8
9module.exports = {
flag: ture,
test(a, b) {
return a + b
},
demo(a, b) {
return a * b
}
}导入
1
2
3
4
5
6
7
8//CommonJs模块
let {test, demo, flag} = require('moduleA');
//等同于
let _mA = require('moduleA');
let test = _mA.test;
let demo = _mA.demo;
let flag = _mA.flag;
三、webpack
从本质上来说,webpack是一个现代的JavaScript应用的静态模块打包工具
webpack依赖node环境,node环境通过npm(node packages manager)工具来管理各种包
局部安装webpack
–save-dev是开发时依赖,项目打包后不需要继续使用的
1
2cd 对应目录
npm install webpack@3.6.0 --save-dev使用时在终端中输入:
1
webpack ./src/main.js ./dist/bundle.js
通过这样对模块化开发的js文件进行打包使得网页再使用js时直接调用打出来的包就可以,不用一个一个的导入。
文件和文件夹的解析:
- dist文件夹:用于存放之后打包的文件
- src文件夹:用于存放源码
- main.js:项目的入口文件。
- mathUtils.js:定义了一些数学工具函数,可以在其他地方引用使用。
- index.html:浏览器打开展示的首页html
- package.json:通过npm init生成的,npm包管理的文件。
webpack.config.js文件
为了每次使用webpack时不用写上入口和出口参数,就通过这个文件
1 | const path = require('path')//引用path |
这时直接在终端里输入webpack
即可打包。
package.json文件
如何生成该文件:在终端输入npm init
若是局部安装webpack的话就要到webpack路径下调用才行,不过可以通过package.json中定义启动。
1 | { |
这时只用在终端中输入npm run build
,即可调用局部webpack。
若package.json文件中有需要依赖的东西就在终端中输入
npm install
来下载
loaders
可以用来解析各种文件给webpack方便打包,因为webpack无法识别全部文件。
例如需要一起打包css文件
安装
npm install css-loader --save-dev
,npm install style-loader --save-dev
在webpack.config.js中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19module.exports = {
entry: '',
output: {
path: ,
filename: '',
},
module: {
rules: [
{
test: /\.css$/,
//css-loader只负责将css文件进行加载
//style-loader负责将钥匙添加到DOM中
//使用多个loader时,是从右向左的
use:['style-loader','css-loader']
}
]
}
}
更多见:https://www.webpackjs.com/
使用vue的配置过程
在终端中输入npm install vue --save
安装上vue
使用
1 | import Vue from 'vue' |
在打包时因为Vue不同版本的构建会报错,runtime-only和runtime-compiler的区别,因此要在webpack中的module.exports添加配置:
1 | resolve: { |
Vue学习(7)-plugin、Vue-Cli、箭头函数、vue-router准备
一、vue的使用方法
创建vue时,当template和el同时存在时,会将template中的东西替换el中的东西。
要对.vue文件进行封装处理就需要安装vue-loader和vue-template-compiler.
1 | npm install vue-loader vue-template-compiler --save-dev |
因为脚手架还没学到,现在这个形式好像是很接近脚手架的了。
App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31//模版样式
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">www</button>
</div>
</template>
//js代码
<script>
export default {
name: "App",
data() {
return {
message: 'hello world',
}
},
methods: {
btnClick() {
}
}
}
</script>
//css样式
<style scoped>
.title {
color: #4fc08d;
}
</style>main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14import Vue from "vue";
// import App from "./vue/app";
import App from "./vue/App";
// require("./css/back.css") commentJs的方式
import "./css/back.css";
new Vue({
el: "#app",
template: `<App/>`, //之后替换app中的东西
components: {
App
}
})Index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
二、plugin
认识plugin
- plugin是插件的意思,通常用于对某个现有框架进行扩展。webpack中的插件就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等。
- loader和plugin的区别:
- loader主要用于转换某些类型的模块,是一个转换器。
- plugin是插件,对webpack本身进行扩展,是个扩展器。
- 使用过程:
- 通过npm安装需要使用的plugins(内置过的不用再安)
- 在webpack.config.js中的plugins中配置插件。
添加版权的plugin
在webpack.config.js中添加
1 | const path = require('path'); |
即可在bundle.js开头添加声明。
不过应该不常用吧
打包html的plugin
因为发布时是发布dist里的文件,但是dist里没有index.html,因此需要将html也打包进去。
安装HtmlWebpackPlugin插件:
npm install html-webpack-plugin --save-dev
要使用时在webpack.config.js文件中进行修改
1
2
3
4
5
6
7
8const HtmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
new HtmlWebpackPlugin({
template: 'index.html' //打包的模版
})
]这时就会在dist文件中生成一个index.html
我在使用的时候出了点问题,安装htmlwebpackplugin安不上。可以这样解决:
- 清缓存:
npm cache clean --force
- 重新安装:
npm install html-webpack-plugin --save-dev
搭建本地服务器
便于加快开发进度,在浏览器中刷新自动更新,就是热加载功能。
安装
1
2npm install --save-dev webpack-dev-server@2.9.1
//因为和之前安的vue2.x版本相对应devserver作为webpack的一个选项,有以下属性可以设置:
- contentBase:为哪一个文件夹提供本地服务,默认根目录,在这要填./dist
- port:端口号(默认8080)
- inline:页面实时刷新
- historyApiFallback:在SPA页面中,依赖HTML5的history模式。
将webpack.config.js中添加:
1
2
3
4devServer: {
contentBase: './dist',
inline: true
}同时为了在方便使用,在package.json中添加
1
2
3
4"scripts": {
...
"dev": "webpack-dev-server --open"
},
三、Vue-CLI
runtime-compiler和runtime-only的区别
runtime-compiler:template -> ast(抽象语法树) -> render -> vitual dom -> UI
1
2
3
4
5new Vue({
el: '#app',
template: '<App/>',
components: {App}
})runtime-only:render -> vitual Dom -> UI
性能高,代码量少
1
2
3
4
5
6
7new Vue({
el: '#app',
render: h => h(App),
//render: function (h) {
// return h(App)
//}
})
Vue-cli3的创建
输入
vue create projectName
.browserslistrc =>浏览器相关支持情况 .babel.config.js =>ES语法转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
也可以使用`vue ui`来网页创建和管理
## 四、箭头函数
```js
//1、function
const aaa = function () {
}
//2、对象字面量中定义函数
const obj = {
bbb() {
}
}
//3、ES6中的箭头函数
const ccc = (参数列表) => {
}
//若一个参数时小括号可以省略
//返回值若只有一行时可以直接写
const ddd = (num1, num2) => num1 * num2
//箭头函数的this是一层一层往外找的
五、vue-router准备
页面url更新但页面不重新加载
1 | //将url压入栈结构 |
安装与配置
router/index.js
1 | //相关配置 |
1 | //4、在main.js中进行挂载 |
映射配置和展现
1 | //index.js |
1 | <template> |
或者想自己定义函数来跳转
1 | <template> |
动态路由
1 | //index.js |
1 | <router-link :to="'/user/'+userId">user</router-link> |
- 若要获取例如用户名或者商品id,对组件进行一定修改
1 | <div> |
路由懒加载
1 | const Home = () => import('../components/Home') |
路由的嵌套使用
创建子组件
在父组件中定义位置
1
2
3
4
5<div>
<h1>Home</h1>
<router-link to="/news">news</router-link>
<router-view></router-view>
</div>在路由中定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const HomeNews = () => import('../components/HomeNews')
const routes = [
{
path: '/',
name: 'Home',
component: Home,
children: [
{
//要让其默认显示news子组件时的默认路径
path: '',
redirect: 'news'
},
{
path: 'news',
component: HomeNews,
}
]
},
]