个人学习笔记整合

学习笔记

2020-12-02 学习笔记

var和let的区别

var是全局变量;
可以重复声明;
有变量提升默认值为undefined;
不存在暂时性死区;

{
	var i=9
}
console.log(i) //  9

let是块级变量;
不可以重复声明,会报错;
没有变量提升,会报错;
存在暂时性死区,即声明变量时,区块中对这些声明变量形成封闭作用域,凡是在声明之前使用变量就会报错;

{
	let i=9
}
console.log(i) //Uncaught ReferenceError: i is not defined

分析代码执行结果
var a=123;
if(true){
	a='zsh';
	let a;
}

会报错,a变量声明两次,在let声明后在循环内形成暂时性死区,即在声明之前使用变量a会报错

补全代码
var person={
	name:'zs',
	age:12
}
let str=`                         `;
结果呈现:用户的姓名为 ,年龄是
result.innerHTML=str;

补充代码为

let str=`用户的姓名为${person.name},年龄是${person.age}`
将下面字符串改用模板字符串实现
$("#result").append(
	"He is <b>"+person.name+"</b>"+"and we wish to 
know his"+person.age+".That is all"  )

答:

$("#result").append(`
	He is <b>${person.name}</b>and we wish to know 
	his ${person.age}.That is all
	`)
下面程序输出的结果是
let object = { first: 'Bill', lasts: 'Gates' };
let { first: firstName, last: lastName } = object;
console.log(firstName+'\t'+lastName);

Bill undefined
key值发生了改变object中的key值为lasts下面的key值变成了last 所以解构得到的不是Gates,而是undefined

下列程序执行f()函数运行的结果是
var tmp = new Date();
function f(){
  console.log(tmp);
	  if (false){
	    var tmp = "hello world";
	  }
}
f() 

undefined
函数内部变量tmp声明覆盖了外层tmp声明,内部变量输出在声明之前,所以输出默认值undefined

对比以下两道程序输出的值相同吗
//A程序:
	var a = [];
	for (let i = 0; i < 10; i++) {
	  a[i] = function () {
	    console.log(i);
	  };
	}
	a[8](); 
	a[9](); 

//B程序
	var a = [];
	for (var i = 0; i < 10; i++) {
	  a[i] = function () {
	    console.log(i);
	  };
	}
	a[8](); 
	a[9](); 

不同
A程序i为块级变量当调用函数并赋值的时候根据当前下标值进行输出
B程序i为全局变量无论当前下标值为何值,输出值均是i的跳出循环的值
A:// 8 9
B:// 10 10

2020-12-05 学习笔记

下面程序的执行结果是什么?请分析原因?
function f({ x = 10 } = {}, { y } = { y: 10 }) {
	console.log( x + " " + y +"\n");
}
结果:
f(); // 10 10  
f( undefined, undefined ); // 10 10  
f( {}, undefined ); // 10 10  
f( {}, {} ); // 10 undefined  
f( undefined, {} ); // 10 undefined  
f( { x: 2 }, { y: 3 } ); // 2 3

原因:f()运用了es6的解构语法
形参x声明并且赋值,所以无论实参的值为null还是undefined,x均为10,若实参赋值为2,那么x赋值为2。
形参y声明未赋值,所以实参的值undefined,y为10,实参为null,y为默认值undefined,若实参赋值为3,那么y赋值也为3,

Array.from方法的作用是什么

Array.from 是为了将类数组和对象转化为数组

Array.of和使用Array()或new Array()构建数组实例有什么区别

Array.of() 相当于扩展了 new Array();

例如:创建长度为 1 的数组,值为 10
var arr=Array.of(10);
下面程序执行结果是什么?
function push(array, ...items) {
	items.forEach(function(item) {
		array.push(item);
		console.log(item);
	});
}
var a = [1,2];
push(a, 1, 2, 3)

//1 2 3
items内包含1,2,3依次压入数组a每压入一个值就打印一个值

下面程序执行结果是什么?
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(6, 2, 3, 4, 5)

[6,[2,3,4,5]]
…tail将head变量对应的6之后的参数形成一个数组

node是什么?

Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

2020-12-07 学习笔记

编写程序使用ES6定义 Person类,包括类实例属性(name,age),实例方法say()该方法

返回name和age字符串

答:
class Person{
  constructor(name,age){
    this.name=name;
    this.age=age;
    this.say=function(){
      return [name,age];
    }
  }
}
var p=new Person('jack',12)
p.say()
下面程序执行结果为:
var p=new Person();
console.log(p.__proto__===Person.prototype)

答:true 二者在同一条原型链上

下面程序正确吗?错在哪里?如何改正?
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
class ColorPoint extends Point {
  constructor(x, y, color) {
  	this.color = color; // ReferenceError
  	super(x, y);
  }
}
var cp=new ColorPoint(10,20,'red');

答:
将super(x, y); 和 this.color = color; 互换位置,this要写在super()后面

下面程序执行结果为?
class Parent {
  static myMethod(msg) {
    console.log('static', msg);
  }
  myMethod(msg) {
    console.log('instance', msg);
  }
}
class Child extends Parent {
  static myMethod(msg) {
    super.myMethod(msg);
  }
  myMethod(msg) {
    super.myMethod(msg);
  }
}
Child.myMethod(1); 
var child = new Child();
child.myMethod(2); 

答:
// static 1
// instance 2
静态函数只能由构造函数自身调用,非静态函数可以使用实例对象调用

利用class重新定义Cat,并让它从已有的Animal继承,然后新增一个方法say(),返回字符串’Hello, xxx!’
class Animal {
    constructor(name) {
        this.name = name;
    }
}
答:
class Cat extends Animal{
  constructor(name){
    super(name)
  }
  say(){
    console.log('hello,xxx')
  }
}
var c=new Cat('jack')
console.log(c.say())
接上面程序分析下面代码执行结果为
var kitty = new Cat('Kitty');
var doraemon = new Cat('哆啦A梦');
if ((new Cat('x') instanceof Animal) && kitty && kitty.name === 'Kitty' && kitty.say &&
 typeof kitty.say === 'function' && kitty.say() === 'Hello,Kitty!'  && 
kitty.say === doraemon.say) {
         console.log('测试通过!');
} else {
        console.log('测试失败!');
}

答:测试失败

下面程序执行结果为
(typeof (new (class { class () {} })));

答:new 方法构造的是一个类

2020-12-09 学习笔记

node是什么?

个人认为Node.js是一个服务端JavaScript运行平台

这是其他平台的定义,觉得很不错[转自菜鸟教程

Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

Node.js和java/php的区别

转自菜鸟教程

PHP

  • Rasmus Lerdorf在1994年创造出了PHP。它是由安装在web服务器(Apache、Ngix)上的组件运行的。PHP代码可以和HTML混合到一块。 对于初学者就能很快写出很有价值的代码,这并不需要太多的练习。 这让PHP变得越来越流行, 现在全球百分之八十的服务器上都在运行着PHP。全球四分之一的网站都在用的一个内容管理系统–WordPress,就是用PHP写的。
  • PHP 有办法开发桌面应用和命令行工具,但是你不会使用他们。本质上,PHP 是一个服务端技术,他很擅长该领域,但是很少延伸到这之外。
  • PHP 跟其他多数服务端语言采用阻塞执行的模型。 当你执行一个命令,比如从数据库取数据,那么必须等这个指令执行完成后,才会执行下面的内容。

Node.js

  • Ryan Dahl在2009年创造了Node.js。它是基于Google的V8 JavaScript解释引擎(在Chrome浏览器里它负责执行客户端的JavaScript代码)。与其它语言不同的是Node.js内置了处理网络请求和响应的函数库,所以你不需要单独的服务器(Apache、Ngix)或者其他依赖。Node.js虽然很新但是很快就获得了极大的追捧。
  • 若干年前,JavaScript 被认为限制很多,有一些边缘技术,但是他的主战场还是浏览器。Node.js 已经改变了这一感觉并井喷出了很多 JavaScript 项目,你可以在任何地方使用 JavaScript:浏览器,服务器,终端,桌面甚至嵌入式系统,这使得 JavaScript 无处不在。
  • Node.js 通常不会等的。 取而代之的是, 你需要提供一个回调函数,这个函数当指令执行完后会被调用一次。

2020-12-14 学习笔记

简述前端模块化发展史

简单的js脚本引入=>更换为object封装=>闭包封装=>node和npm

node作为后端语言,没有模块化加载机制是运转不起来的,node 最先选择 commonJS 作为它的模块加载方案,因为COMMONJS用于是服务端的,不能直接用于浏览器,于是出现了适用于浏览器的AMD规范,CMD规范,AMD的存在的一些问题不被COMMONJS社区认同,最后独立运作,当然RequireJS也确实也大火了一段时间,后来CMD的产物seajs开发出来。到现在来看这两个产物估计是已经过时了,当然还有在用的,毕竟后来的webpack es6的发展势不可挡,webpakc对三种规范完全支持

实现模块化流程
  • 创建项目文件夹 demoProject
md demoProject
  • 初始化项目
npm init -y
  • 下载
yarn add babel-cli -dev  
yarn add babel-preset-es2015 -dev

新建 .babelrc 文件

{
	"presets":["es2015"],
	"plugins":[]
}
  • 创建src文件夹书写es6语法文件
    a.js
export export var a="这是a文件";

b.js

export var b="这是b文件";

main.js

import {a} from './a.js';
import {b} from './b.js';
console.log(a,b)
  • 在项目文件夹下的 ./node_modules/.bin 文件夹执行
babel ../../src -d ../../dist
  • 在项目文件夹下的dist文件夹下执行
node main.js

便可以实现在main.js文件中对于a.js和b.js文件夹模块的调用

2020-12-16 学习笔记

同步和异步区别?

同步:上一步执行完后下一步才能得到执行。
异步:将比较复杂的任务制作成任务线程,以任务线程实现,不用等上一句执行完,下一句也可以执行。

总而言之:同步就是程序自上而下运行,而异步就是不用等待上面的运行完后再运行下面的操作。异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。

判断文件夹下文件状态
fs.readdir(__dirname,(err,files)=>{
	if(err) throw err;
	console.log(files);
	for(let i in files){
		fs.stat(__dirname,(err,stats)=>{
			if(stats.isFile()){
				console.log(files[i]+"是文件");
				return;
			}
			console.log(files[i]+"是目录")
		})
	}
})
实现静态资源读取
  1. 创建demo文件夹作为测试文件夹
  2. 在demo文件夹下,创建www文件夹存储静态文件夹,在静态文件夹内创建两个不同的项目文件夹
    └─www
        ├─jd
        └─taobao
            ├─css
            ├─image
            └─js
    
  3. jd文件夹下存123.html文件
    taobao文件夹下存储index.html
  4. 在demo文件夹下,创建readFile.js文件作为静态文件读取主文件
const http=require('http');
const fs=require('fs');
const path=require('path');
const common=require('./common');//见下面common.js

http.createServer((req, res)=>{
	//req.url 获取请求地址 /favicon.ico地址是自动请求的
	if (req.url=='/favicon.ico')return;
	//a.startsWith(b) 字符串以b开始的 
	if (req.url.startsWith('/taobao')) {
		common.demo(req,res)
	}else if (req.url.startsWith('/jd')){
		console.log(req.url)
		common.demo(req,res)
	}
	
}).listen('8989');
console.log('http://127.0.0.1:8989/');

创建common模块文件执行www文件夹读取,common.js

const fs=require('fs');
const path=require('path');
module.exports.demo=function (req,res){
	fs.readFile(path.join(__dirname,'www',req.url),(err,data)=>{
		if(err)throw err;
		res.writeHead(200,{'Content-type':'text/pkain;charset=utf-8'})
		res.end(data)
	});
}

http://127.0.0.1:8989/后添加www文件夹下的分支文件夹内的文件即可得出相应文件夹内的静态文件。
例如:http://127.0.0.1:8989/taobao/index.html

2020-12-21 学习笔记

(简易)封装加减乘除模块
  1. 创建项目文件夹cul,并在项目文件夹下创建node_modules文件夹
  2. 在node_modules文件夹下创建模块文件夹calculation
  3. 在模块文件夹下创建index.js模块文件
    module.exports=class calculation{
    	constructor(x,y){
    		this.x=x,
    		this.y=y
    	}
    	add(x,y){
    		let sum=this.x+this.y;
    		return sum
    	}
    	subtract(x,y){
    		let difference=this.x-this.y;
    		return difference
    	}
    	multiply(x,y){
    		let product=this.x*this.y;
    		return product
    	}
    	divide(x,y){
    		let merchant=this.x/this.y;
    		return merchant
    	}
    }
    

模拟进行模块引用,在项目文件夹下创建cul.js引用文件

const cul=require('calculation')

let v=new cul(3,4)
console.log(v.add())
console.log(v.subtract())
console.log(v.multiply())
console.log(v.divide())

并且在当前项目文件夹下运行cmd命令

node cul.js     

便可以调用模块进行运算

get和post区别

转自 Laravel社区vinhson
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

  1. GET与POST都有自己的语义,不能随便混用。
  2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
  3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
node实现登录和注册

创建项目文件夹demo
在demo下,创建form表单文件夹,form文件夹下文件如下

├─css
	└─index.css
├─image
├─js
├─index.html
├─get.html
└─post.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<title></title>
	<meta charset="UTF-8">
	<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
	<a href="get.html">登录</a>
	<a href="post.html">注册</a>
</body>
</html>

index.css

p{
	background: red;
}

get.html

<!DOCTYPE html>
<html>
<head>
	<title>登录</title>
	<meta charset="UTF-8">
</head>
<body>
	<p>登陆页面</p><a href="./index.html">返回主界面</a>
	<form action="http://localhost:8989/submit" method="get">
		<input type="text" name="username" placeholder="用户名"><br>
		<input type="text" name="password" placeholder="密码"><br>
		<input type="submit" value="登录">
	</form>
</body>
</html>```
post.html
```html
<!DOCTYPE html>
<html>
<head>
	<title>注册</title>
	<meta charset="UTF-8">
</head>
<body>
	<p>注册页面</p><a href="./index.html">返回主界面</a>
	<form action="http://localhost:8989/submit" method="post">
		<input type="text" name="user" placeholder="用户名"><br>
		<input type="password" name="pass" placeholder="密码"><br>
		<input type="submit" value="注册">
	</form>
</body>
</html>

在项目文件夹下创建node_modules文件夹
并在该文件夹下创建readFile文件夹
在readFile文件夹下创建index.js文件读取模块文件

const fs=require('fs');
const path=require('path');
module.exports=function (p,req,res){
	fs.readFile(path.join(p,req.url),(err,data)=>{
		if(err)throw err;
		res.end(data)
	});
}

在项目文件夹下创建主文件main.js

const http=require('http');
const fs=require('fs');
const path=require('path');
const url=require('url');
const querystring=require('querystring')
//引入读文件的模块 
const readfile=require('readFile');

http.createServer((req, res)=>{
	if (req.url=='/favicon.ico')return;
	if (req.url.startsWith('/form')) {
		readfile(__dirname,req,res)
	}else if(req.url.startsWith('/submit')){
		if(req.url.startsWith('/submit?username')){
			//get方法
			res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'})
			let ps= url.parse(req.url,true).query;
			console.log(ps)
			res.end(`姓名:${ps.username},密码:${ps.password}`)
		}else{
			//post方法
			res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'})
			let allData= '';
			req.on('data',(chunk)=>{
				allData+=chunk;
			})
			req.on('end',()=>{
				console.log(querystring.parse(allData));
				let asd=querystring.parse(allData)
				console.log(asd)
				res.end(`姓名:${asd.user},密码:${asd.pass}`);
			});
		}
	}else{
		res.end('404')
	}
	
}).listen('8989');
console.log('http://127.0.0.1:8989/form/index.html');

2020-12-23 学习笔记

node登录注册(express,ajax)

创建项目文件夹demo,目录文件夹,书写文件位置如下

demo
 ├─node_modules
 ├─express.js
 └─www
     └─jd
     	├─post.html
        ├─index.html
        ├─css
        	└─index.css
        └─js
        	└─jquery-1.11.3.js

主页面文件index.html

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<meta charset="UTF-8">
	<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
	<h1>登录页面</h1>
	<input type="text" placeholder="用户名"><br>
	<input type="password" placeholder="密码"><br>
	<button>登录</button><a href="./post.html">未注册请注册</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script type="text/javascript">
	var url="http://localhost:8989/submit?"
	$('button').click(()=>{		
		$.ajax({
			url:url,
			method:"get",
			data:{
				username:$('input[type="text"]').val(),
				password:$('input[type="password"]').val()
			},
			success:function(res){
				console.log(res)
				location.href=`${url}username=${res.username}&password=${res.password}`//页面跳转
			}
		})
	})
</script>
</html>

post注册页面post.html

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<h1>注册界面</h1>
	<input type="text" name="user" placeholder="用户名"><br>
	<input type="password" name="pwd" placeholder="密码"><br>
	<button>注册</button>
	<a href="./index.html">已注册请登录</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script type="text/javascript">
	var url="http://localhost:8989/submit?"
	$('button').click(()=>{		
		$.ajax({
			url:url,
			method:"post",
			data:{
				username:$('input[type="text"]').val(),
				password:$('input[type="password"]').val()
			},
			success:function(res){
				console.log(res)
				location.href=`${url}username=${res.username}&password=${res.password}`//页面跳转
			}
		})
	})
</script>
</html>

js主文件express.js,运行该文件,根据控制台地址登录,即可运行该网站,实现登录注册效果

const express=require('express');
const path=require('path');
const bodyparser=require('body-parser')

//WEB框架实例化
var app=express()
app.use(bodyparser.urlencoded({extended:true}))  //路由解码

app.use(express.static(path.join(__dirname,"www","jd")))
.post("/submit",function(req,res) {
	// post请求需要依赖专门的模块
	// 1. npm install body-parser -S;
	// 2. 在页面中引入
	// 3. 在post请求的第二个参数加上刚刚解析body-parser得到的参数。
	res.json(req.body)
})
.get("/submit",function(req,res) {
	res.json(req.query)
})

.use("/",(req,res)=>{
	res.send("404")
})
//监听端口
app.listen('8989',function(err) {
    if (err)throw err;
    console.log("http://localhost:8989")
})

2020-12-26 学习笔记

关系型数据库有哪些,非关系型数据库有哪些?两者区别?

**关系型数据库:**Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL

**非关系型数据库:**NoSql、Cloudant、MongoDb、redis、HBase
关系型数据天然就是表格式的,因此存储在数据表的行和列中;数据表可以彼此关联协作存储,也很容易提取数据。而非关系型数据不适合存储在数据表的行和列中,而是大块组合在一起;非关系型数据通常存储在数据集中,就像文档、键值对或者图结构。

整理一份数据库操作手册。只需要指令即可

show dbs //显示现有数据库

use mydb //建立数据库

db.stu.insert({name:‘www’,age:‘30’})

  • 在数据库中创建表格
  • 格式: db.数据库名称.insert(添加内容)**

use mydb //使用数据库

show tables //显示数据库表格

精确查找

.count()加在find()后面,可返回值符合标准的数量

db.stu.find() //显示数据库表格内容每一个对象都会生成id

db.stu.find({name:‘www’})

  • //在小括号内可添加查询条件,增加条件可直接添加,
  • 例如:db.stu.find({name:‘www’})

db.stu.findOne({name:‘www’})//只返回一个对象

db.stu.find($or:[{name:‘www’},{age:‘30’}])

  • find括号内添加多个条件,格式如下:
  • $or:[条件一,条件二]

db.stu.find({name:{$in:[‘www’,‘age’]}})

  • 查找所有满足$in后条件的均显示
  • {查找对象:{$in:[条件一,条件二]}}

db.stu.find({name:/www/})
db.stu.find({name:/^w/})

  • 可使用正则语法
范围查找

db.stu.find({age:{$gte:50,lte:100}})

  • find括号内增加查找范围
  • {查找条件:{$gte:下限值,lte:上限值}}
更改指令

db.stu.update({name:‘www’},{$set:{age:999}})

  • update()为更改指令,只更新一条指令
  • update(查找条件,{$set:{条件对象内对应变量 : 条件对象内修改的值}},false,true)
  • 第三个参数默认为false无操作,若为true时,查找条件不存在则进行添加
  • 第四个参数默认为false,只更新一条指令,若为true则全部更新
删除指令

db.stu.remove({name:‘www’})

  • 删除符合条件项

db.stu.remove({})

  • remove括号内为 {} 删除所有

2020-12-28 学习笔记

增删改查mongodb封装

用到的包文件 expresspathMD5mongodb

前端页面 – index.html

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<meta charset="UTF-8">
	<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
	<h1>用户页面</h1>
	<form action="http://localhost:8989/adddata">
		<input type="text" name="name" placeholder="用户名"><br>
		<input type="text" name="hobby" placeholder="爱好"><br>
		<button>注册(增)</button>
	</form>
	<form action="http://localhost:8989/selectdata">
		<input type="text" name="name" placeholder="用户名"><br>
		<input type="text" name="hobby" placeholder="爱好"><br>
		<button>登录(查)</button>
	</form>
	<form action="http://localhost:8989/selectalldata">
		<button>查询整个数据库数据</button>
	</form>
	<form action="http://localhost:8989/removedata">
		<input type="text" name="name" placeholder="用户名"><br>
		<input type="text" name="hobby" placeholder="爱好"><br>
		<button>注销(删)</button>
	</form>
	<form action="http://localhost:8989/changedata">
		<input type="text" name="name" placeholder="用户名"><br>
		<input type="text" name="hobby" placeholder="爱好"><br>
		<input type="text" name="newhobby" placeholder="新爱好"><br>
		<button>更改爱好(改)</button>
	</form>
</body>
</html>

封装模块包 – mongodb.js

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";

function _connect(callback){
   MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
      if (err) throw err;
      callback(db)
   });
}
//查询(登录)
exports.findAll=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename). find(data).toArray(function(err, result) { 
			// 返回集合中所有数据
			if (err) throw err;
			db.close();
			callback(result)
		});
	})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		if (data instanceof Array) {
			data=data
		}else{
			data=[data]
		}
		dbo.collection(tablename).insertMany(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    console.log(result);
		    db.close();
		    callback(result)
		});
	})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).deleteOne(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    console.log(result);
		    db.close();
		    callback(result)
		});
	})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).updateMany(olddata,data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    console.log(result);
		    db.close();
		    callback(result)
		});
	})
}
const express=require('express');
const path=require('path');
const bodyparser=require('body-parser');
const md5=require("md5");
//mongodb模块
const mdb = require('./mongodb.js');

const app=express();
app.use(bodyparser.urlencoded({extended:true}))//路由解码

app.use(express.static(path.join(__dirname,"www","form")))
//增
.get("/adddata",(req,res)=>{
   let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
   mdb.add("mydb","stu",mydata,(r)=>res.json(r.ops))
})
//查
.use("/selectdata",(req,res)=>{
   let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
   mdb.findAll("mydb","stu",mydata,(r)=>res.send(r))
})
//查数据库
.use("/selectalldata",(req,res)=>{
   mdb.findAll("mydb","stu",{},(r)=>res.send(r))
})
//删
.use("/removedata",(req,res)=>{
   let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
   mdb.remove("mydb","stu",mydata,(r)=>res.send(r))
})
//改
.use("/changedata",(req,res)=>{
   let olddata={name:req.query.name,hobby:md5(req.query.hobby)};
   let mydata={$set:{hobby:md5(req.query.newhobby)}};
   mdb.change("mydb","stu",olddata,mydata,(r)=>res.send(r))
})
app.listen("8989")

2020-12-30 学习笔记

商品增删改查

用到的包文件 expressMD5mongodbcookie-parser

注册页面- index.html

<!DOCTYPE html>
<html>
<head>
	<title>注册页面</title>
</head>
<body>
	<input type="text" placeholder="请输入用户名"><br>
	<input type="password" placeholder="请输入密码"><br>
	<button>注册</button><a href="./login.html">已注册请点击登录</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
	$('button').click(()=>{
		$.ajax({
			url:"http://localhost:8989/msg",
			data:{
				name:$('input:eq(0)').val(),
				pwd:$('input:eq(1)').val()
			},
			success:function(res){
				console.log(res);
				location.href="http://localhost:8989/login.html"
			}
		})
	})
</script>
</html>

登录页面 – login.html

<!DOCTYPE html>
<html>
<head>
	<title>登陆页面</title>
</head>
<body>
	<input type="text" placeholder="请输入用户名"><br>
	<input type="password" placeholder="请输入密码"><br>
	<button onclick="login()">登录</button>
	<button onclick="del()">注销</button>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
	$.ajax({
		url:"http://localhost:8989/z",
		success:function(res){
			console.log(res)
			if(res!=""){
				$('input:eq(0)').val(res.name)
				$('input:eq(1)').val(res.pwd)
				location.href="http://localhost:8989/shop.html"
			}
			
		}
	})
	//登录
	function login() {
		$.ajax({
			url:"http://localhost:8989/log",
			data:{
				name:$('input:eq(0)').val(),
				pwd:$('input:eq(1)').val()
			},
			success:function(res){
				console.log(res)
				if(res!="未注册"){
					location.href="http://localhost:8989/shop.html"
				}
			}
		})
	}
	//注销
	function del(){
		$.ajax({
			url:"http://localhost:8989/removedata",
			data:{
				name:$('input:eq(0)').val(),
				pwd:$('input:eq(1)').val()
			},
			success:function(res){
				console.log(res)
			}
		})
	}
</script>
</html>

商品页面 – shop.html

<!DOCTYPE html>
<html>
<head>
	<title>商品页面</title>
	<style type="text/css">
		.write_name{
			width:40px;
		}
		.write_price{
			width:40px;
		}
	</style>
</head>
<body>
	<input type="text" class="proname" placeholder="输入商品名字">
	<input type="text" class="price" placeholder="输入商品价格">
	<button id="add">增加商品</button><button id="findOne">查询商品</button>
	<table>
		<thead>
			<tr>
				<td>商品名称</td>
				<td>商品价格</td>
				<td>编辑商品</td>
				<td>删除商品</td>
			</tr>
		</thead>
		<tbody></tbody>
	</table>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
	//查询
	(function(){
		$.ajax({
			url:"http://localhost:8989/find",
			data:{},
			success:function(res){
				console.log(res)
				for(let i in res){
					$('tbody').append(`
						<tr>
							<td>${res[i].proname}</td>
							<td>${res[i].proprice}</td>
							<td οnclick="change(this)">编辑</td>
							<td οnclick='del(this)'>删除</td>
						</tr>
					`)
				}
			}
		})
	})();
	$("#findOne").click(function(){
		$.ajax({
			url:"http://localhost:8989/findOne",
			data:{
				proname:$('.proname').val(),
				proprice:$('.proprice').val()
			},
			success:function(res){
				console.log(res)
				for(let i in res){
					$('tbody').html(`
						<tr>
							<td>${res[i].proname}</td>
							<td>${res[i].proprice}</td>
							<td οnclick="change(this)">编辑</td>
							<td οnclick='del(this)'>删除</td>
						</tr>
					`)
				}
			}
		})
	})
	//编辑
	var name="",price="";
	function change(a){
		console.log()
		name=$(a).siblings().eq(0).html();
		price=$(a).siblings().eq(1).html();
		$(a).siblings().eq(0).html(`
			<input type="text" class="write_name" value="${name}">
		`)
		$(a).siblings().eq(1).html(`
			<input type="text" class="write_price" value="${price}">
		`)
		$(a).attr({"onclick":"changeok(this)"}).html("确定")
	}
	function changeok(a){
		$.ajax({
			url:"http://localhost:8989/write",
			method:"get",
			data:{
				name:name,
				price:price,
				proname:$('.write_name').val(),
				proprice:$('.write_price').val()
			},
			success:function(res){
				console.log(res)
				$(a).siblings().eq(0).html(`${$('.write_name').val()}`)
				$(a).siblings().eq(1).html(`${$('.write_price').val()}`)
				$(a).attr({"onclick":"change(this)"}).html("编辑")
			}
		})
	}
	//删除
	function del(a){
		$.ajax({
			url:"http://localhost:8989/del",
			data:{
				proname:$(a).siblings().eq(0).html()
			},
			success:function(res){
				$(a.parentNode).remove()
			}
		})
	}
	//添加
	$('#add').click(()=>{		
		$.ajax({
			url:"http://localhost:8989/add",
			method:"get",
			data:{
				proname:$('.proname').val(),
				proprice:$('.price').val()
			},
			success:function(res){
				console.log(res)
				if (res!=="均不能为空") {
					$('tbody').append(`
						<tr>
							<td>${res[0].proname}</td>
							<td>${res[0].proprice}</td>
							<td οnclick='change(this)'>编辑</td>
							<td οnclick='del(this)'>删除</td>
						</tr>
					`)
					$('.proname').val("");
					$('.price').val("");
				}else{
					alert(res)
				}
			}
		})
	})
</script>
</html>

后端模块文件 – mongodb.js

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";

function _connect(callback){
   MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
      if (err) throw err;
      callback(db)
   });
}
//查询(登录)
exports.findAll=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).find(data).toArray(function(err, result) { 
			// 返回集合中所有数据
			if (err) throw err;
			console.log(result)
			db.close();
			callback(result)
		});
	})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		if (data instanceof Array) {
			data=data
		}else{
			data=[data]
		}
		dbo.collection(tablename).insertMany(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    console.log(result);
		    db.close();
		    callback(result)
		});
	})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).deleteOne(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    db.close();
		    callback(result)
		});
	})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).updateMany(olddata,data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    db.close();
		    callback(result)
		});
	})
}

后端主文件 – main.js

const express=require('express');
const path=require('path');
const bodyparser=require('body-parser');
const md5=require("md5");
//mongodb模块
const mdb = require('./mongodb.js');
//cookies包
const cookieParser=require('cookie-parser')

const app=express();
app.use(cookieParser())
app.use(bodyparser.urlencoded({extended:true}))//路由解码

app.use(express.static('./www/form/'))
//注册用户
.get('/msg',(req,res)=>{
	console.log(req.query)
	mdb.add("mydb","stu",req.query,(r)=>res.json(r.ops))
})
//检测是否登录过,若是直接跳转
.get('/z',(req,res)=>{
	//console.log(req.cookies.msg)
	if (req.cookies.msg) {
		res.send(req.cookies.msg)
	}else{
		res.send('')
	}
})
//登录并记录cookie
.get('/log',(req,res)=>{
	console.log(req.query)
	mdb.findAll("mydb","stu",req.query,(r)=>{
		if(r!=""){
			//书写cookie Pes.cookie( 'cookie名字’,值,{maxAge:设置cookie存在时间ms})
			res.cookie('msg',req.query,{maxAge:8400000,httpOnly:true})
			res.json(r); 
		}else{
			res.send("未注册")
		}

	})
	
})
//增加商品
.get('/add',(req,res)=>{
	if(req.query.proname!==""&&req.query.proprice!==""){
		mdb.add("mydb","shop",req.query,(r)=>res.json(r))
	}else{
		res.json("均不能为空")
	}
})
//扫描全部商品
.use('/find',(req,res)=>{
	mdb.findAll("mydb","shop",{},(r)=>res.json(r))
})
.use('/findOne',(req,res)=>{
	mdb.findAll("mydb","shop",req.query,(r)=>res.json(r))
})
//删除商品
.use('/del',(req,res)=>{
	console.log(req.query)
	mdb.remove("mydb","shop",req.query,(r)=>res.send(r))
})
//编辑商品
.get('/write',(req,res)=>{
	console.log(req.query.proname,req.query.proprice)
	console.log(req.query.name,req.query.price)
	let olddata={proname:req.query.name,proprice:req.query.price};
 	let mydata={$set:{proname:req.query.proname,proprice:req.query.proprice}};
	mdb.change("mydb","shop",olddata,mydata,(r)=>res.send(r.ops))
})
app.listen("8989")

问题整理

在使用cookie-parser包时,调用cookie的时候注意res.json(r);放到最后一行避免报错

res.cookie('msg',req.query,{maxAge:8400000,httpOnly:true})
res.json(r); 

2021-01-04 学习笔记

分页功能

//扫描全部商品
.use('/find',(req,res)=>{
	let num=parseInt(req.query.num);
	console.log(req.query.type,num)
	if(req.query.type=="next"){
		num>=1?num=parseInt(num)*10+1:num=0;
	}else if(req.query.type=='prov'){
		num<=0?num=0:num=(parseInt(num)-2)*10+1;
	}
	mdb.findAll("mydb","shop",{},(r)=>{
		res.json(r)
	},{},num,10)
	
})
var back=2;
	function next(){
		console.log(num,back)
		if(num<back){
			$.ajax({
				url:"http://localhost:8989/find",
				data:{
					num:num,
					type:"next"
				},
				success:function(res){
					num=parseInt(num+=1)
					console.log(res.length)
					$('tbody').html("")
					for(var i in res){
						$('tbody').append(`
							<tr>
								<td>${res[i].proname}</td>
								<td>${res[i].proprice}</td>
								<td id="${res[i]._id}" onclick="change(this)">编辑</td>
								<td onclick='del(this)'>删除</td>
							</tr>
						`)
					}
					back++;
					res.length<10&&(back=num);
				}
			})
		}
	}
	function prov(){
		console.log(num)
		if(num>1){
			$.ajax({
				url:"http://localhost:8989/find",
				data:{
					num:num,
					type:"prov"
				},
				success:function(res){
					num=parseInt(num-=1)
					console.log(res,num)
					//if(res.length<10)return "第一页"
					$('tbody').html("")
					for(var i in res){
						$('tbody').append(`
							<tr>
								<td>${res[i].proname}</td>
								<td>${res[i].proprice}</td>
								<td id="${res[i]._id}" onclick="change(this)">编辑</td>
								<td onclick='del(this)'>删除</td>
							</tr>
						`)
					}
					res.length=10&&(back=num+1);
				}
			})
		}
	}

2021-01-09 学习笔记

聊天室

运用node中ejs,express,mongodb,socket.io配置聊天室
登录后进行会话

后端主文件chat.js

const express=require('express');
const app=express();
//mongodb模块
const mdb = require('./mongodb.js');
//配置socket.io
const http=require('http').Server(app);
const io=require('socket.io')(http);
//配置ejs
const ejs=require('ejs');
app.set('view engine','ejs');

//呈递静态资源
app.use(express.static('./www'))
app.use(express.static('./views'))

app.get('/',(req,res)=>{
	console.log(req.query)
	let user=req.query.name;
	res.render('index',{user:user});
})
app.get('/log',(req,res)=>{
	mdb.findAll("mydb","stu",req.query,(r)=>{
		console.log(r)
		if(r!=""){
			res.json(r);
		}else{
			res.send("未注册")
		}
	})
})
app.get('/chat',(req,res)=>{
	console.log(req.query,"chat")
	res.render('chat',{msg:req.query,user:req.query.name});
})
.get('/msg',(req,res)=>{
	console.log(req.query,"msg")
	/*mdb.add("mydb","talk",req.query,(r)=>{
		res.json(r.ops)
	})*/
})
//配置长连接
io.on('connection',(socket)=>{
	//接收客户端数据  on监听数据接收
	socket.on('chat',(msg)=>{
		//发送数据给客户端
		io.emit('send',msg)
		mdb.findAll("mydb","talk",{},(r)=>{
			console.log(r.ops)
		})
	})
})


//如果使用socket.io 不能使用app监听
http.listen('8989')

mongodb.js模块文件

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";

function _connect(callback){
   MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
      if (err) throw err;
      callback(db)
   });
}
//查询(登录)
// 查询封装的时候,考虑是否需要分页是否需要排序
// 需要书写函数参数的默认值,因为用户有可能不会书写
exports.findAll=function(dbname,tablename,data,callback,mysort={},myskip=0,mylimit=0){
	_connect(function(db){
		var dbo = db.db(dbname);
		// sort排序
	    // skip跳过多少条数据
	    // limit()限制取数据的数量
		dbo.collection(tablename).find(data).sort(mysort).skip(myskip).limit(mylimit).toArray(function(err, result) { 
			// 返回集合中所有数据
			if (err) throw err;
			db.close();
			callback(result)
		});
	})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		if (data instanceof Array) {
			data=data
		}else{
			data=[data]
		}
		dbo.collection(tablename).insertMany(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    //console.log(result);
		    db.close();
		    callback(result)
		});
	})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).deleteOne(data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    db.close();
		    callback(result)
		});
	})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
	_connect(function(db){
		var dbo = db.db(dbname);
		dbo.collection(tablename).updateMany(olddata,data,function(err, result) { 
		    // 返回集合中所有数据
		    if (err) throw err;
		    db.close();
		    callback(result)
		});
	})
}

聊天室页面chat.ejs

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
	<h1>欢迎 <%=user %> 进入聊天室</h1>
	<input type="text">
	<button οnclick="talk()">发送</button>

	<ul>
			
	</ul>
	<script type="text/javascript" src="form/js/jquery-1.11.3.js"></script>
	<!-- 引人sotket.io框票自动去node_modules文件夹寻我 -->
	<script type="text/javascript" src="socket.io/socket.io.js"></script>
	<script type="text/javascript">
		//引入框架
		let socket=io();
		$('button').click(()=>{
			//发送数据socket.emit('发送的名字和后台接收保持一致',[数据})
			socket.emit('chat',{msg:$('input').val()})
		})
		socket.on('send',(msg)=>{
			console.log(msg)
			$("ul").append(`<p><%=user%>:${msg.msg}</p>`)
		})
		function talk() {
			$.ajax({
				url:"http://localhost:8989/msg",
				data:{
					msg:$('input:eq(0)').val()
				},
				success:function(res){
					console.log(res)
				}
			})
		}
	</script>
</body>
</html>

登陆页面index.ejs

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
	<% if(user){ %>
		<h1>欢迎<%= user %>登陆</h1>
	<% }else{ %>
		<h1>请登陆</h1>	
		<input type="text" placeholder="请输入用户名"><br>
		<input type="password" placeholder="请输入密码"><br>
		<button οnclick="login()">登录</button>
	<% } %>
</body>
<script type="text/javascript" src="form/js/jquery-1.11.3.js"></script>
<script type="text/javascript">
	//登录
	function login() {
		$.ajax({
			url:"http://localhost:8989/log",
			data:{
				name:$('input:eq(0)').val(),
				pwd:$('input:eq(1)').val()
			},
			success:function(res){
				console.log(res)
				if(res!="未注册"){
					location.href=`http://localhost:8989/chat?name=${res[0].name}`
				}
			}
		})
	}
</script>
</html>

20210123 学习笔记

vue.js简介

Vue.js 是一个轻巧、高性能、可组件化的 MVVM 库,拥有非常容易上手的 API;
Vue.js是一个构建数据驱动的 Web 界面的库。
而其中的MVVM指的是一种架构模式。通俗的来讲就是 视图 模型 和控制器的关系

<!-- 指的是MVVM中的(V)view视图 -->
<div id="app">
	{{msg}}
</div>
// new Vue指的是MVVM中的VM(viewModel控制器) 把视图和数据联系起来
new Vue({
	el:'#app',
	// data指的是MVVM中的M(model数据模型)
	data:{
		msg:'hello'
	}
})

vue.js使用

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
	</head>
	<body>
		<div id="app">
			{{msg}}
			{{list}}
		</div>

		<div id="box">
			{{msg}}
		</div>
		<!-- 第一步:引入框架 -->
		<script src="js/vue.js"></script>
		<script>
			new Vue({
				// el绑定元素不能是html/body。可以是标签名、类名、id名。一般使用的是id名(避免不必要的问题)。如果多个符合条件,只执行第一个符合条件的。
				// id名是唯一的,一个标签只能有一个id名 
				el:'#app',
				data:{
					// 数据的格式k:v,k:v
					msg:'hello vue',
					list:['a','b']
				}
			})

			// 可以实例化多个对象,不建议
			new Vue({
				// el绑定元素不能是html/body。可以是标签名、类名、id名。一般使用的是id名(避免不必要的问题)。如果多个符合条件,只执行第一个符合条件的。
				// id名是唯一的,一个标签只能有一个id名 
				el:'#box',
				data:{
					msg:'hello box'
				}
			})
		</script>
	</body>
</html>

vue插值表达式

在vue语法内部,可以使用{{}}称为插值表达式。表达式内部,可以放置变量或者表达式或者函数
注意
1、vue语法外部,使用不了插值表达式
2、{{放置的变量,只能是在data中声明过的,外部的数据不能使用}}

vue事件结构

事件的结构:v-on:事件类型="方法名()"
click mouseenter mouseleave focus blur

事件方法中的实参this指的是window对象,不再是当前标签
$event指的是事件相关的参数
$event.target可以获取当前标签

vue中有专门封装的获取标签的方法 给标签取ref值 this.$refs.标签的ref的值

<button ref="btn">按钮</button>
<script src="js/vue.js"></script>
<script>
new Vue({
	el:'#app',
	methods:{
		a(){
			this.$refs.app.style.background='red';
		}
	}
})
</script>

v-html和v-text

v-html和v-text都可以增加内容
v-html可以识别标签。有xss(可以通过html书写病毒,攻击网站)风险
v-text识别不了标签,把标签当做普通文本处理。可以使用{{}}代替

20210125 学习笔记

使用vue实现发微博效果(发布和删除效果)

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		#titlebox{
			display: inline-block;
			margin: 5px;
		}
		#msgbox{
			background: #eee;
		}
	</style>
</head>
<body>
	<div id="app">
		<div id="titlebox">
			<input type="text" ref="title" placeholder="输入博文标题"><br><br>
			<textarea cols="50" ref="massage" rows="5" placeholder="输入博文内容"></textarea><br>
			<button v-on:click="a">提交</button>
		</div>
		<div id="msgbox" v-for="(item,index) in msg">
			<p>{{item.title}}</p>
			<p>{{item.massage}}</p>
			<p v-on:click="del(index)">删除博文</p>
		</div>
	</div>
</body>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			msg:[]
		},
		methods:{
			a(){
				console.log(this.$refs.title.value,this.$refs.massage.value)
				this.msg.push({
					title:this.$refs.title.value,
					massage:this.$refs.massage.value,
				})
				console.log(this.msg)
			},
			del(a){
				this.msg.splice(a,1)
			}
		},
	})
</script>
</html>

使用vue实现tab栏

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		#titlebox{
			display: inline-block;
			margin: 5px;
		}
		#msgbox{
			width: 300px;
			height: 200px;
			background: #eee;
		}
	</style>
</head>
<body>
	<div id="app">
		<div id="titlebox" v-for="(item,index) in title">
			<span v-on:click="a(index)">{{item}}</span>
		</div>
		<div id="msgbox">
			{{msg[num]}}
		</div>
	</div>
</body>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			num:0,
			title:['新闻','娱乐','科技'],
			msg:['新闻热点-----','娱乐热点++++++','科技热点/']
		},
		methods:{
			a(a){
				this.num=a
			},
		},
	})
</script>
</html>

computed和watch有何区别

computed

支持缓存,只有依赖数据发生改变,才会重新进行计算
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
如果computed属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

watch

不支持缓存,数据变化,直接触发;
watch支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
当一个属性发生变化时,需要执行对应的操作;一对多;
监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:

20210127 学习笔记

spa单页面开发

单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成了, 以后的每次请求, 仅仅是获取必要的数据.然后, 由页面中js解析获取的数据, 展示在页面中

vue实现spa的优势

  • 良好的交互体验
    因为是局部渲染,避免了不必要的跳转和重复渲染
  • 前后端分离提高开发效率
  • 减轻服务器的压力。
    服务器只需要提供数据,不需要管前端展示逻辑和页面合成
  • 共用一套后端程序代码。

实现分类页面

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no, viewport-fit=cover">
	<style>
		*{
			margin: 0px;
			padding: 0px;
			list-style: none;
		}
		/* 一般两边留白固定20px */
		header{
			height: 40px;
			background: lime;
		}
		section{
			height: calc(100vh - 40px - 40px);
			background: pink;
		}
		footer{
			position: fixed;
			bottom: 0px;
			left: 0px;
			height: 40px;
			width: 100%;
			background: lime;
		}
		.left{
			width: 20%;
			float: left;
			height: calc(100vh - 40px - 40px);
			overflow: scroll;
			text-align: center;
		}
		.right{
			width: 80%;
			float: right;
			height: calc(100vh - 40px - 40px);
			overflow: scroll;
		}
		footer li{
			width: 20%;
			float: left;
			background: red;
			height: 40px;
		}
		footer li:nth-of-type(2n){
			width: 20%;
			float: left;
			background: blue;
			height: 40px;
		}
	</style>
</head>
<body>
	<div id="app">
		<header></header>
		<section>
			<ul class="left">
				<li v-for="(item,index) in list" @click='msg=item.msg'>{{item.con}}</li>
			</ul>
			<div class="right">
				<component :is="msg"></component>
			</div>
		</section>
		<footer>
			<ul>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
		</footer>
	</div>
	<template id="man">
		<h1>男装</h1>
	</template>
	<template id="woman">
		<h1>女装</h1>
	</template>
	<template id="mshoes">
		<h1>男鞋</h1>
	</template>
	<template id="wshoes">
		<h1>女鞋</h1>
	</template>
</body>
<script src="js/vue.js"></script>
<script>


	new Vue({
		el:"#app",
		data:{
			msg:'man',
			list:[
				{
					con:"男装",
					msg:"man"
				},
				{
					con:"女装",
					msg:"woman"
				},
				{
					con:"男鞋",
					msg:"mshoes"
				},
				{
					con:"女鞋",
					msg:"wshoes"
				},
			],
			shoplist:['111T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','222T恤'],
		},
		components:{
			'man':{
				template:"#man"
			},
			'woman':{
				template:"#woman"
			},
			'mshoes':{
				template:"#mshoes"
			},
			'wshoes':{
				template:"#wshoes"
			}
		}
	})
</script>
</html>

20210130 学习笔记

子组件的值传递给父组件

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>练习</title>
</head>
<body>
	<!-- 子组件的值传递给父组件
		 1、 在子组件中定义方法/事件,方法/事件内部
		 	this.$emit('事件名',所需发送的数据(发送给父组件的数据))
		 2、 在占位符中   @事件名(在子组件定义的事件)='方法名(不加括号!需要在父组件中定义过)'
		 3、 在父组件中,定义接受数据的方法
		 4、 在子组件中,执行刚刚定义的事件方法
	 -->
	<div id="app">
		<v-header @send="get"></v-header>
		{{t.msg}}<br>
		<button @click="change">change</button>
	</div>


	<template id="header">
		<div>
			<h1>head</h1>
			<!-- 自动触发fn方法 -->
			{{fn()}}
		</div>
	</template>
</body>
<script src="js/vue.js"></script>
<script>
	var header={
		template:"#header",
		data(){
			return{
				msg:{
					msg:'this is son'
				},
			}
		},
		methods:{
			fn(){
				this.$emit('send',this.msg)
			}
		}
	}

	new Vue({
		el:"#app",
		data:{
			num:'this is father',
			t:'',
		},
		methods:{
			get(a){
				this.t=a
				console.log('send successful')
				console.log(a)
			},
			change(){
				this.t.msg+=1
			}
		},
		components:{
			'v-header':header
		}
	})
</script>
</html>

父组件的值传递给子组件

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>练习</title>
</head>
<body>
	<!-- 父组件的值传递给子组件
		 1、 占位符中 :a="fmsg" a子组件中需要接收的数据(自定义) fs父组件数据
		 2、 在子组件中定义属性 props 接受a   props:['a']
		 3、 在子组件中可以直接使用a
	 -->
	<div id="app">
		<!-- {{msg}} 报错  -->
		<v-header :a="num"></v-header>
	</div>


	<template id="header">
		<div>
			<h1>head</h1>
			<button @click='change'>按钮</button>
			{{a.num}}
		</div>
	</template>
</body>
<script src="js/vue.js"></script>
<script>
	var header={
		template:"#header",
		data(){
			return{
				msg:'this is son',
			}
		},
		watch:{
			
		},
		methods:{
			change(){
				this.a.num+=1
				//console.log(this.a)
			}
		},
		props:['a'],
	}

	new Vue({
		el:"#app",
		data:{
			num:{
				num:'this is father'
			}
		},
		components:{
			'v-header':header
		}
	})
</script>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值