原创不易,转载请注明出处,谢谢!
第一部分:Vue基础语法——组件化开发——模块化开发——webpack
渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。
或者如果你希望将更多的业务逻辑使用Vue实现,那么Vue的核心库以及其生态系统。
比如Core+Vue-router+Vuex,也可以满足你各种各样的需求。
方式一:直接CDN
方式二:下载和引入
开发环境 https://vuejs.org/js/vue.js 生产环境 https://vuejs.org/js/vue.min.js |
后续通过webpack和CLI的使用,我们使用该方式。
{{message}}
- {{item}}
- {{movies[0]}}
- {{movies[1]}}
- {{movies[2]}}
- {{movies[3]}}
计数器:
{{count}}
el | 类型:string | HTMLElement(“|”是或的意思) 作用:决定之后Vue实例会管理哪一个DOM |
data | 类型:Object | Function 作用:Vue实例对应的数据对象 |
methods | 类型:{[key:string]:Function} 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。 |
方法 | 函数 | |
英文单词 | method | function |
定义 | 方法(method)是通过对象调用的javascript函数。也就是说,方法也是函数,只是比较特殊的函数。 | 函数(function)是一段代码,需要通过名字来进行调用。它能将一些数据(函数的参数)传递进去进行处理,然后返回一些数据(函数的返回值),也可以不返回数据。 |
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
Vue.prototype._init = function (options?: Object) {
......
}
"vue": {
"prefix": "vue", // 触发的关键字 输入vue按下tab键
"body": [
" ",
" ",
],
"description": "vue template"
}
{{message}}
{{message}},龙猫
{{firstName +' '+ lastName}}
{{firstName}}{{lastName}}
{{count*2}}
{{message}}
{{url}}
{{message}}
{{message}}
百度一下C
用法一:直接通过{}绑定一个类 Hello World |
用法二:也可以通过判断,传入多个值 Hello World |
用法三:和普通的类同时存在,并不冲突 注:如果isActive和isLine都为true,那么会有title/active/line三个类 Hello World |
用法四:如果过于复杂,可以放在一个methods或者computed中 注:classes是一个计算属性 Hello World |
{{message}}
{{message}}
:class="{active:isActive[index]}"方法:
- {{item}}
index==this.num?"active":''方法:
- {{item}}
{{message}}
{{message}}
{{firstName +' '+lastName}}
{{firstName}} {{lastName}}
{{getFullName()}}
{{fullName}}
{{getSumPrice()}}
{{SumPrice}}
{{fullName}}
get方法:{{fullName2}}
{{firstName}}{{lastName}}
{{getFullName()}}
{{getFullName()}}
{{getFullName()}}
{{getFullName()}}
{{fullName}}
{{fullName}}
{{fullName}}
{{fullName}}
var btns = document.querySelectorAll('button');
for(i=0;i
let name = 'why';
let age = 18;
let obj1 = {
name:name,
age:age,
eat:function(){
console.log("吃1");
}
}
console.log(obj1);
obj1.eat();
//ES6
let obj2 = {
name,age,
eat(){
console.log("吃2");
}
}
console.log(obj2);
obj2.eat();
如果方法中没有传递参数,可以省略括号(也可以不省略)
如果方法中有参数传递,必须加括号
如果方法中有多个参数:
优秀
良好
中等
差
{{resultMessage}}
{{message}}
{{message}}
- {{index+1}},{{item}}
- {{obj.name}}
- {{obj.age}}
- {{obj.height}}
- {{item}}
- {{key}}:{{item}}
- {{key}}:{{item}}--{{index}}
- {{index}},{{item}}
数组方法 | 是否响应式 | 作用 |
this.letter.push('sss') |
响应式 | 数组后边添加元素,可以做到响应式 |
this.letters.pop() |
响应式 | 删除数组最后一个 |
this.letters.shift() |
响应式 | 删除数组中的第一个 |
this.letters.unshift('aaa', 'bbb') |
响应式 | 在数组前边添加元素,可以传多个参数是因为是可变参数...str |
this.letter.sort() |
响应式 | 排序,响应式 |
this.letters.reverse() |
响应式 | 数组反转 |
this.letters.splice(2, 1, 'm ') |
响应式 | 可以做增删改,从第二个开始,删除1个,增加‘m’ |
this.letters[0] = 'bbbb' |
否 | 不能做到响应式,可以this.letters.splice(0, 1, 'bbbb');替代 |
Vue.set(this.letters, 0, 'bbbb') |
响应式 | vue的方法实现元素替换 |
- {{item}}
书籍名称
出版日期
价格
购买数量
操作
{{item.id}}
{{item.name}}
{{item.date}}
{{getFinallPrice(item.price)}}
{{item.count}}
总价格:{{sumPrice}}
{{getFinallPrice(item.price)}}
{{item.price | showPrice}}
{{item.count}}
...
methods:{
sub(index){
this.books[index].count--
},
add(index){
this.books[index].count++
},
}
两种方法 | DOM中区别 | 调用 |
computed | 总价为{{sumPrice}} |
会自动调用sumPrice方法 |
methods | 总价为{{sumPrice()}} |
也会自动调用sumPrice方法,但是不太合适 |
totalPrice() {
//计算总价的方法1:
// let totalprice = 0;
// for (item of this.bookList) {
// totalprice += item.price * item.count;
// }
// return totalprice
//计算总价的方法2(高级函数):
return this.bookList.reduce(function(preValue, book) {
return preValue + book.price * book.count
}, 0)
}
books
购物车为空
sumPrice(){
//1.普通的for循环
// let sumprice = 0;
// for(let i=0;i
编程范式 | 命令式编程 | 声明式编程 |
编程范式 | 面向对象编程 (第一公民:对象) |
函数式编程 (第一公民:函数) |
nums = [12 , 333 , 34 , 55 , 133 ] let new3Nums = nums.filter(function(n) { return n < 100 }) console.log(new3Nums) //打印[12 , 34 , 55 ] |
2.map的使用,一般用于数值操作,不过滤数值
let new4Nums = new3Nums.map(function(n) { return n * 2 }) console.log(new4Nums); //打印[24 , 68 , 110 ] |
3.reduce应用,用于数组求和:
let total2 = new4Nums.reduce(function(total, num) { return total + num; }) console.log(total2); //打印24+68+110的和 |
4.命令式和高级函数对比代码:
const nums = [10, 20, 44, 66, 888, 123, 55, 75, 111];
//1.取出所有小于100的数字
let newNums = [];
for (let n of nums) {
if (n < 100) {
newNums.push(n)
}
}
console.log(newNums);
//2.将所有小于100的数字进行转化:全部*2
let new2Nums = [];
for (let n of newNums) {
new2Nums.push(n * 2);
}
console.log(new2Nums);
//3.将所有num2Nums数字相加,得到最终结果
let total = 0
for (let n of new2Nums) {
total += n;
}
console.log(total);
//4.filter,根据条件筛选,不能改变值
let new3Nums = nums.filter(function(n) {
return n < 100
})
console.log(new3Nums);
//5.map,不做筛选,改变值
let new4Nums = new3Nums.map(function(n) {
return n * 2
})
console.log(new4Nums);
// 6.reduce
let total2 = new4Nums.reduce(function(total, num) {
return total + num;
})
console.log(total2);
//7.一行代码搞定,函数式编程
let total3 = nums.filter(function(n) {
return n < 100
}).map(function(n) {
return n * 2
}).reduce(function(total, num) {
return total + num;
})
console.log(total3);
//8.一行代码搞定——箭头函数
let total4 = nums.filter(n => n < 100).map(n => n * 2).reduce((total, num) => total + num);
console.log(total3);
1.双向绑定,可以接收和改变message:
message:{{message}}
2.单向绑定,只能接收不能改变message:
3.人为单向绑定,只改变不接收,2+3合起来就是v-model
4.手动双向绑定:
你选择的性别是:{{sex}}
单选框:
你选择的是:{{isAgree}}
......
data:{
sex:'男',
isAgree:false
},
多选框:
篮球
钢琴
跳舞
你的爱好是:{{hobbies}}
...
var app=new Vue({
el:'#app',
data:{
hobbies:[],
},
});
选择一个:
{{fruit}}
选择多个:
{{fruits}}
v-for:
{{hobbies}}
var app=new Vue({
el:'#app',
data:{
hobbies:[],
originHobbies:["篮球","钢琴","跳舞","瑜伽","游泳"],
},
});
1.修饰符lazy
{{message}}
2.修饰符number
{{typeof age}},{{age}}
3.trim去除空格
{{name}}
我是内容
我是内容1111
我是内容2222
我是内容
我是内容1111
我是内容2222
局部组件不能在这里使用:
语法糖省去了调用Vue.extend()带步骤,可以直接使用一个对象代替
模板分离2
我是内容2
{{title}}
{{con}}
{{count}}
- {{item}}
{{cmessage}}
{{cInfo.name}}
{{cInfo.age}}
{{cInfo.height}}
{{childMyMessage}}
传递过程:1,子组件中通过$emit()来触发事件,2,父组件中v-on来监听子组件事件
注:父组件中的方法不要写参数,默认在子组件模版中已经定义了,不能写cpnClick(item),只能写cpnClick
{{total}}
props:{{number1}}
data:{{dnumber1}}
props:{{number2}}
data:{{dnumber2}}
props:{{number1}}
data:{{dnumber1}}
props:{{number2}}
data:{{dnumber2}}
第一种(用得少) | 第二种(用的非常多) |
$children | $refs (refs:reference引用的意思) |
结果是个数组,下标志拿数据方式不太好,因为子组件数量可能会变化,下标的索引值会变 | 结果是个对象,可以给每个组件添加一个ref属性设置唯一性 |
我是子组件
我是子组件
span标签
我是组件标题
我是组件内容
标题
标题
左边
中间
右边
右边
我是标题
我是内容
{{slot.data.join('-')}}
- {{item}}
(function(){
var flag = true;
function sum(num1,num2){
return num1+num2
}
})()
var moduleA = (function(){
var obj = {};
var name = '小明';
var age = 18;
function sum(num1,num2){
return num1 + num2
}
var flag = true;
// if(flag){
// console.log(sum(10,20));
// }
obj.name = name;
obj.age = age;
obj.flag = flag;
obj.sum = sum;
obj.myFunction = function(value){
console.log(value)
}
return obj
})()
//a.js导出
module.exports = {
name:ws,
flag:true,
sum(a,b){
return a+b
}
}
//b.js导入,导入名字要和导出的名字一样
let {name, sum, flag} = require('./a.js');
//上边等同于下边
let mod = require('./a.js');
let name = mod.name;
let flag = mod.flag;
let sum = mod.sum;
//index.html
//
//
//
//aaa.js//小明
var name = 'xiaoming';
var age = 18;
var flag = true;
function sum(a , b){
return a+b
}
if(flag){
console.log(sum(11,2));
}
//bbb.js//小红
var name = 'xiaohong';
var age = 19;
var flag = false;
//ccc.js 报错,flag未定义
if(flag){
console.log('flag');
}
方法1,先定义变量、函数或class,再导出:export { flag,sum,Person}
方法2,直接导出:export var num1 = 100001; export function sum(a,b){return a+b}; export class Person{run(){console.log("在奔跑")}}
方法3,export default name; import myName from "./aaa.js",用于导入者自己可以修改名字,但是export default只能在一个js中使用一次
前两种导入方法一样:import {flag , sum,num1 , Person} from "./aaa.js"或import * as obj from "./aaa.js" 然后obj.flag可以取值
//index.html
//
//
//
//aaa.js
var name = 'xiaoming';
var age = 18;
var flag = true;
function sum(a , b){
return a+b
}
if(flag){
console.log(sum(11,2));
}
//1.导出方式一:
export{
flag,sum
}
//2.导出方式二:
export var num1 = 100001;
export var height = 1.88;
export class Person{
run(){
console.log("在奔跑");
}
}
//3.导出方式三:
var address = '北京市';
export default address;
//ccc.js
import {flag , sum} from "./aaa.js"
if(flag){
console.log('flag');
console.log(sum(111,222));
}
import {num1 , height ,Person} from "./aaa.js"
console.log(num1);
console.log(height);
let ws = new Person();
ws.run();
import myAdd from "./aaa.js"
console.log(myAdd);
import * as obj from "./aaa.js"
console.log(obj.height);
//index.html
//
//main.js
//1.common.js导入
let {sum ,mul} = require('./mathUtils.js');
console.log(sum(11,3));
console.log(mul(22,10));
//2.ES6导入
import {name , age , height} from './info';
console.log(name);
console.log(age);
console.log(height);
//mathUtils.js
function sum(num1,num2){
return num1 + num2
}
function mul(num1,num2){
return num1 * num2
}
//1.common.js导出
module.exports = {
sum,
mul
}
//info.js
//2.ES6导出
export const name = 'xiaoming';
export const age = 18;
export const height = 1.88;
//webpack.config.js文件
const path = require('path');//'path'是node的系统模块
module.exports = {
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
}
}
//package.js文件
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack" //本句加完之后,能用npm run build替代webpack命令
},
"author": "",
"license": "ISC"
}
——只要是在终端敲webpack,用的都是全局的,想使用本地的必须./node_modules/.bin/webpack
——所以定义"build":"webpack" 的好处是执行npm run build时,优先找本地的webpack
css-loader只负责加载,不负责解析,需要再安装style-loade(样式添加到dom中)
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '../dist/' //涉及到url的东西,都会再前边拼接dist/
},
module: {
rules: [{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
}, {
test: /\.less$/i,
loader: [
// compiles Less to CSS
"style-loader",
"css-loader",
"less-loader",
],
}, {
test: /\.(png|jpg|gif)$/i,
use: [{
loader: 'url-loader',
options: {
//当加载的图片小于limit时,会将图片编译成base64位字符串形式
//当加载的图片大于limit时,需要使用file-loader模块进行加载
limit: 8192,
},
}, ],
}
],
},
}
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
1.npm install vue --save
2.webpack.config.js配置:
resolve:{
//alias别名
alias:{
'vue$':'vue/dist/vue.esm.js' //这个指定的有compiler,默认用的是vue.runtime.js
}
}
3.npm install [email protected] [email protected] --save-dev
4.开始使用new Vue({})
4,npm run build
import Vue from 'vue';
// import { Cpn } from './vue/app.js'
const Cpn = {
template:`
{{message}}
{{name}}
`,
data(){
return{
message:'hello world',
name:'coderwhy'
}
},
methods:{
btnClick(){
console.log("btnClick");
}
}
};
//app.js
import Vue from 'vue';
import { Cpn } from './vue/app.js'
//下边这个Vue是一个根组件,运行只会template会替换el
new Vue({
el:'#app',
template:' ',
components:{
Cpn
}
})
//App.vue
{{message}}
{{name}}
1.安装 npm install html-webpack-plugin --save-dev
2. 配置webpack.config.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({template:'index.html'}),加了参数后,为了让原index.html的
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
// publicPath: '../dist/' //涉及到url的东西,都会再前边拼接dist/
},
module: {
rules: [{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.less$/i,
loader: [
// compiles Less to CSS
"style-loader",
"css-loader",
"less-loader",
],
}, {
test: /\.(png|jpg|gif)$/i,
use: [{
loader: 'url-loader',
options: {
//当加载的图片小于limit时,会将图片编译成base64位字符串形式
//当加载的图片大于limit时,需要使用file-loader模块进行加载
limit: 8192,
},
}, ],
},
{
test: /\.js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
],
},
resolve: {
// alias: 别名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new webpack.BannerPlugin('版权最终归龙猫所有'),
new HtmlWebpackPlugin({
template: 'index.html' //为了让原index.html的引进进来
})
]
}
09.(掌握)webpack-UglifyjsWebpackPlugin的使用(压缩js文件)
- npm install [email protected] --save-dev
- const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
- plugins: [ new UglifyjsWebpackPlugin() ]
10.(掌握)webpack-dev-server搭建本地服务器(npm run dev)
过程:
1.npm install --save-dev [email protected]
2.配置webpack.config.js:
devServer:{
contentBase:'./dist',
inline:true,
}
3.配置package.js的script:"dev":"webpack-dev-server",或者script:"dev":"webpack-dev-server --open"默认打开
4.运行npm run dev
11.(掌握)webpack配置文件的分离
- 需求:开发时和发布时依赖的配置文件不一样,后边脚手架用法哦了,提前了解
- 分离过程:
- 1.把webpack.config.js分离成base.config.js、prod.config.js、base.config.js
- 2.npm install [email protected] --save-dev
- 3.package.json配置:"build": "webpack --config ./build/prod.config.js" , "dev": "webpack-dev-server --open --config ./build/dev.config.js"
发布时base.config.js+prod.config.js => npm run build
开发时base.config.js+dev.config.js => npm run dev
//prod.config.js
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig,{
plugins:[
new UglifyjsWebpackPlugin()
]
})
//dev.config.js
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig,{
devServer:{
contentBase:'./dist',
inline:true,
}
})