Vue.js 2.0 基础知识 之 学习笔记

系列文章目录

提示:阅读本章之前,请先阅读目录



前言

Vue.js 2.0 最基础的内容,笔记

vue3: https://github.com/Panyue-genkiyo/vue3-learning
vue2依据脚手架:https://github.com/Panyue-genkiyo/vue-advance
vue基础不依赖脚手架:https://github.com/Panyue-genkiyo/vue-learning


初识Vue.js

我们通过引入Vue.js,就实现最简单的使用vue

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
Hello world!
<script type="text/javascript">
  Vue.config.productionTip = false;
</script>
</body>
</html>

在这里插入图片描述

通过设置,Vue.config.productionTip = false;
来控制,控制台的提示,这个提示,是指生产环境,最好使用生产版本的vue

在这里插入图片描述

在这里插入图片描述

实例化Vue,让Vue运行起来

通过new Vue()来实例化

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <h1>My Name: {{name}}</h1>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    // 实例化
    const x = new Vue({
      "el": "#root",
      "data": {
        "name": "smobee"
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

favicon图标加载问题

我是在Visual Studio Code 启动的,Open With Live Server,所以,就是带有端口号的访问页面
在这里插入图片描述

在这里插入图片描述
会报一个,找不到图标的错误提示,这个是浏览器默认的行为

我们可以通过按住Shift+刷新,强制刷新,就可以看到这个报错


如果,我们是直接以文件绝对路径访问,则不存在这个问题

在这里插入图片描述

在这里插入图片描述

Vue模板支持js表达式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <h1>My Name: {{name}}</h1>
    <h1>Now Time: {{Date.now()}}</h1>
    <h1>Add: {{1+1}}</h1>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    // 实例化
    const x = new Vue({
      "el": "#root",
      "data": {
        "name": "smobee"
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

一个Vue容器只会接管一个元素

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <h1>My Name: {{name}}</h1>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    // 实例化
    const x = new Vue({
      "el": "#root",
      "data": {
        "name": "smobee"
      }
    });
    const x1 = new Vue({
      "el": "#root",
      "data": {
        "name": "xmfboss"
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

一个元素只能被一个Vue接管

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
  <div class="root">
    <h1>My Name: {{name}}</h1>
  </div>
  <div class="root">
    <h1>My Name: {{name}}</h1>
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    // 实例化
    const x = new Vue({
      "el": ".root",
      "data": {
        "name": "smobee"
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

指令语法 v-bind: 和 简写 :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello</title>
  <script type="text/javascript" src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <h1>My Name: {{name}}</h1>
    <input type="text" v-bind:value="comment">
    <!-- 简写 -->
    <input type="text" :value="result">
  </div>
  <script type="text/javascript">
    Vue.config.productionTip = false;
    // 实例化
    const x = new Vue({
      "el": "#root",
      "data": {
        "name": "smobee",
        "comment": "hello, smobee",
        "result": 123456
      }
    });
  </script>
</body>
</html>

在这里插入图片描述

el的两种写法

const v = new Vue({
	// 这是第一种写法,注释掉了
	// el: "#root",
	data: {
		name: "test"
	}
})
// 这是第二种写法
v.$mount("#root")

data的两种写法

第一种
new Vue({
	el: "#root",
	data: {
		name: "hello"
	}
})
第二种
new Vue({
	el: "#root",
	data: function(){
		// 这里的this,是vue实例本身
		console.log(this)
		return {
			name: "hello"
		}
	}
})
第二种简写
new Vue({
	el: "#root",
	data(){
		// 这里的this,是vue实例本身
		console.log(this)
		return {
			name: "hello"
		}
	}
})
错误示范,如果使用箭头函数,this会是window实例
new Vue({
	el: "#root",
	data: () => {
		// 这里的this,是vue实例本身
		console.log(this)
		return {
			name: "hello"
		}
	}
})

MVVM模型

在这里插入图片描述

数据代理,Obeject.defindProperty

在这里插入图片描述

let number = 100;
let person = {
	name: "xiaofeng",
	sex: "man"
}
Object.defindProperty(person, 'age', {
	value: number,
	enumberable: true, // 控制是否可被遍历(枚举)
	writable: true, // 控制是否可被修改
	configurable: true, // 控制是否可被删除
	get: function() {
		console.log("有人正在读取我")
		return number
	},
	set(val){
		console.log("有人正在设置我的值是:", value)
	}
})


事件处理

在这里插入图片描述

<button v-on:click="onClickOpen">我是按钮1</button>
<button v-on:click="onClickClose("hello", $event)">我是按钮1</button>

const vm = new Vue({
	el: "#root",
	data: {
		name: "hello",
		onClickEdit() {
			console.log("其实我放到这里,也可以调用,只不过会使用数据代理的方式")
		}
	},
	methods: {
		onClickOpen(event) {
			console.log("这里的this就是vm本身", this === vm)
			console.log("这里的event,是元素本身", event)
			console.log("我可以输出按钮的文字", evnet.innertText)
		},
		onClickClose(str, evnet) {
			console.log("我传递了一个字符串", str)
			console.log("我可以把event传递进来", event)
		},
		onClickTest: (event) => {
			console.log("这里的event,箭头函数,是window对象", event)
		}
	}
})

修饰符

prevent:阻止默认事件
stop:阻止冒泡
once:只执行一次
capture:使用事件的捕获模式
self:只有event.target是自己的时候,才会触发
passive:事件的默认,立即执行,无需等待事件回调后执行

<a href="baidu.com" @click.prevent="open">prevent 只执行click事件</a>

<div @click="open">
	<p @click.stop="open">我是里面,阻止了冒泡,不会影响外面</p>
</div>

<div @click="open">
	<a href="baidu.com"  @click.stop.prevent="open">我是里面,阻止了冒泡,并组织默认事件</a>
</div>

<button @click.once="open">我只会被调用一次哦</butoon>

<div @click.self="open">
	只有event.target是外面的元素,才会触发click
	<p @click="open">我是里面</p>
</div>

scroll,是滚动条,响应事件,键盘上下滑动和鼠标滚轮,就会触发onClick事件
<ul @scroll="onClick">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

开启了passive之后,会先滚动滚动条,如果没有开启,会等onClick执行完后才会滚动滚动条
<ul @wheel.passive="onClick">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

onClick() {
	for (int i = 0; i < 100000; i++) {
		console.log(i)
	}
}

键盘事件

// keyup是指,按键按下并放开
<input type="text" @keyup="onClick"></input>
// keydown是指,按键按下就触发
<input type="text" @keydown="onClick"></input>

// 示例
<input type="text" @keyup.enter="onClick"></input>
<input type="text" @keyup.Enter="onClick"></input>
<input type="text" @keyup.esc="onClick"></input>
<input type="text" @keyup.space="onClick"></input>
<input type="text" @keyup.delete="onClick"></input>
<input type="text" @keyup.up="onClick"></input>
<input type="text" @keyup.down="onClick"></input>
<input type="text" @keyup.left="onClick"></input>
<input type="text" @keyup.right="onClick"></input>
// tab比较特殊,因为会移出焦点
<input type="text" @keydown.tap="onClick"></input>
// 两个单词组成的,要用-隔开
<input type="text" @keyup.caps-lock="onClick"></input>
// 系统按键,需要搭配第二键使用
<input type="text" @keyup.ctrl="onClick">同时按下ctrl+其他按键,并放开</input>
<input type="text" @keyup.alt="onClick"></input>
<input type="text" @keyup.shift="onClick"></input>
<input type="text" @keyup.meta="onClick">win键</input>
// 小提示,组合键的
<input type="text" @keyup.ctrl.y="onClick">同时按下ctrl+y,并放开</input>
// 还可以自定义名称
Vue.config.keyCodes.huichejian = 13

onClick(e) {
	// 输出当前按键的编码
	console.log(e.keyCode)
	if (e.keyCode === 13) {
		console.log("回车键")
	}
	console.log("当前输入框的value值", e.target.value)
}

计算属性

// 计算属性,更新数据的情况:
// 1. 首次加载
// 2. 依赖的数据发生了变化,计算属性也会重新计算一次
// 底层原理,是用了Object.defindProperty的getter和setter方法
<div>{{fullname}}</div>

const vm = Vue({
	el: "#root",
	data: {
		name: "A",
		name2: "B"
	},
	computed: {
		fullname: {
			get(){
				return this.name + this.name2
			},
			set(){
				console.log("有人想改我的值")
			}
		}
		// 简写,只实现get
		fullname() {
			return this.name + this.name2
		}
	}
})

计算属性和方法组合应用

<span>{{message}}</span>
<div @click="isValue = !isValue">测试</div>
<div @click="onChangeValue">测试</div>
<div @click="window.alert("我可以用此方法,调用window参数")">测试</div>

const vm = Vue({
	el: "#root",
	data: {
		isValue: true,
		window
	},
	computed: {
		message() {
			return isValue ? "A" : "B"
		}
	},
	methods: {
		onChangeValue() {
			this.isValue = !this.isValue
		}	
	}
})

watch监视器

const vm = Vue({
	el: "#root",
	data: {
		name: "123"
	},
	computed: {
		newName() {
			return this.name + '123'
		}
	},
	watch: {
		name: {
			// 第一次会自动调用一次
			immediate: true,
			handler(newValue, oldValue) {
				console.log("我被改变了", newValue, oldValue)
			}
		},
		newName: {
			// 我也可以同样监听计算属性
			immediate: true,
			handler(newValue, oldValue) {
				console.log("我被改变了", newValue, oldValue)
			}
		},
		// 简写
		newName(newValue, oldValue) {
			console.log("我被改变了", newValue, oldValue)
		}
	}
})
// 第二种写法
vm.$watch('name', {
	immediate: true,
	handler(newValue, oldValue) {
		console.log("我被改变了", newValue, oldValue)
	}
})

高级用法

const vm = Vue({
	el: "#root",
	data: {
		numbers: {
			a: 1,
			b: 2
		}
	},
	watch: {
		// 单独监听,a的变化
		'numbers.a': {
			handler() {
				console.log("我被更改了")
			}
		},
		// 使用深度监听器
		numbers: {
			deep: true,
			handler() {
				console.log("我被更改了")
			}
		}
	}
})

watch 异步函数

const vm = Vue({
	el: "#root",
	data: {
		name: "hello"
	},
	watch: {
		name() {
			// 等一秒钟再执行,这里使用箭头函数是因为,setTimeout是Vue帮我们调用js去运行的,异步的,所以箭头函数在调用的时候,就会自动去找外层的主体,就是name(),而外层的name()就是Vue管理的
			setTimeout(()=> {
				console.log("Hello 我执行了")
			}, 1000)
			// 如果是普通函数,那么,普通函数就是浏览器管理的
			setTimeout(fucntion(){
				console.log("Hello 我执行了")
			}, 1000)
		}
	}

})

class样式绑定

<div class="test-class" :class="newClass">单纯绑定</div>
<div class="test-class" :class="objectClass">通过对象绑定,true为开启</div>
<div class="test-class" :class="arrClass">数组绑定,有几个则绑定几个</div>

const vm = Vue({
	el: "#root",
	data: {
		newClass: "helloAClass",
		objectClass: {
			A: false,
			B: true,
			C: false
		},
		arrClass: ["a", "b", "c"]
	}

})

style样式绑定

<div class="test-class" :style="newStyle">单纯绑定</div>
<div class="test-class" :style="objectStyle">通过对象绑定,true为开启</div>
<div class="test-class" :style="arrStyle">数组绑定,有几个则绑定几个</div>

const vm = Vue({
	el: "#root",
	data: {
		newStyle: "font-size: 10px",
		objectStyle: {
			fontSize: "20px",
			color: "red"
		},
		objectStyle2: {
			fontSize: "20px",
			color: "red"
		},
		arrStyle: [objectStyle, objectStyle2]
	}

})

v-if和v-show

<div v-show="false"> 实际上,只是给style加一个属性:display: none</div>
<div v-if="true">只有条件符合,才会渲染</div>
// template 只能搭配v-if使用,并且不影响结构
<template v-if="true">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
</template>

v-for,列表渲染

// 遍历数组,testArr=[1,2,3,4]
<div>
	<span v-for="(data, index) in testArr" :key="index">
		{{data}}
	</span>
</div>
// 遍历数组,data=[1,2,3,4],in可以写成of
<div>
	<span v-for="(data, index) of testArr" :key="index">
		{{data}}
	</span>
</div>
// 遍历对象,testObject={name: "123", age: 12, sex="1"}
<div>
	<span v-for="(value, key) of testObject" :key="key">
		{{key}}:{{value}}
	</span>
</div>
// 遍历字符串,testString="hello"
<div>
	<span v-for="(str, index) of testString" :key="index">
		{{str}}
	</span>
</div>
// 遍历指定次数
<div>
	<span v-for="(number, index) in 10" :key="index">
		{{number}}
	</span>
</div>

v-for的key作用

在这里插入图片描述
在这里插入图片描述

列表过滤

// 用watch监听
const vm = Vue({
	el: "#root",
	data: {
		search: "",
		list: [
			{name: "ABCD", age: 18},
			{name: "1236", age: 18},
			{name: "EDFGBD", age: 18},
			{name: "QAZWSXED", age: 18}
		],
		newList: []
	},
	watch: {
		search: {
			// 这里开启immediate,是因为首次会先调用一次watch
			immediate: true,
			handler(value) {
				this.newList = this.list.filter((obj) => {
					return obj.name.indexof(value) !== -1
				})
			}
		}
	}
// 用computed计算属性
const vm = Vue({
	el: "#root",
	data: {
		search: "",
		list: [
			{name: "ABCD", age: 18},
			{name: "1236", age: 18},
			{name: "EDFGBD", age: 18},
			{name: "QAZWSXED", age: 18}
		]
	},
	computed: {
		// 这里用计算属性,能够实现和watch一样的效果,是因为里面依赖了this.search,search一旦被更新,计算属性就会调用一次
		comList() {
			return this.list.filter((obj) => {
				return obj.name.indexof(this.search) !== -1
			})
		}
	}
})

列表过滤

// 用computed计算属性
const vm = Vue({
	el: "#root",
	data: {
		// 0 原,1 升序,2降序
		sortType: 0
		search: "",
		list: [
			{name: "ABCD", age: 18},
			{name: "1236", age: 18},
			{name: "EDFGBD", age: 18},
			{name: "QAZWSXED", age: 18}
		]
	},
	computed: {
		// 这里用计算属性,能够实现和watch一样的效果,是因为里面依赖了this.search,search一旦被更新,计算属性就会调用一次
		comList() {
			const arr = this.list.filter((obj) => {
				return obj.name.indexof(this.search) !== -1
			})
			// 这里进行排序处理
			if (this.sortType > 0) {
				arr.sort((p1, p2) => {
					return this.sortType === 1 ? p1.age - p2.age : p2.age - p1.age
				})
			}
			return arr
		}
	}
})

Vue监视数据

在这里插入图片描述

data: {
	// 数组下标,是没有添加setter和getter的,所以,直接修改数组下标,vue是监视不到变化,页面数据就不会刷新
	list: [
		// 只有对象里面的属性,才会添加getter和setter
		{name: "hello", age: 18}
	]
}

// 要想实现让vue监视到数组的变化,要使用指定的7个函数
// 或者使用vue提供的方法,Vue.set(),但是只能对data下面属性的属性进行添加,不能直接添加到data

Vue表单数据

在这里插入图片描述

// 修饰符
<input v-model.trim="text">去除前后空格</input>
<input type="number" v-model.number="text">配合type使用,只能输入数字</input>
<input v-model.lazy="text">失去焦点后,响应</input>

Vue的过滤器filters

// 单个过滤器
<div>{{name | testFilter}}</div>
// 单个过滤器,并且传值
<div>{{name | test2Filter("hello")}}</div>
// 串联过滤器
<div>{{name | testFilter | newFilter}}</div>

filers: {
	testFilter(val) {
		return "修改" + val
	},
	testFilter(val, text) {
		return "修改" + val + text
	},
	newFilter(val) {
		return "串联" + val
	}
}

// 全局过滤器
Vue.filter("globalFilter", function(val) {
	return val
})

v-text 文本指令

在这里插入图片描述

<div v-text="name">这里面的div内容无效,会被v-text直接替代</div>

data: {
	name: "<h2>会直接输出文本内容,相当于格式化</h2>"
}

v-html

<div v-html="text">会直接解析内容</div>

data: {
	text: "<h1>hello</h1>"
}

v-cloak

在这里插入图片描述

<div v-cloak>在vue没有加载之前,可以配合css隐藏掉</div>

css样式
[v-cloak] {
	display: none;
}

v-once

在这里插入图片描述

// 只会读取一次值
<div v-once>{{name}}</div>

v-pre

<div v-pre>直接跳过vue的解析,提高效率</div>

自定义指令

// 1. 初始化会触发自定义指令的刷新
// 2. 所在的模板,被重新解析,自定义指令也会重新刷新
<div v-hello="name">我是特殊内容</div>


data: {
	name: "hahaha"
},
directives: {
	// 简写
	hello(elements, binding) {
		elements.innerText = "My name is:" + binding.value
	}
	// 高级写法
	hello: {
		bind(elements, binding) {
			console.log("初始化调用")
		},
		inserted(elements, binding) {
			console.log("插入元素时,调用")
		},
		update(elements, binding) {
			console.log("更新数据时,调用")
		}
	},
	// 有多个单词这样写
	'hello-xixi-haha'(elements, binding) {
		elements.innerText = "My name is:" + binding.value
	}
}

// 全局指令
Vue.directives("hello", function(elements, binding) {
	elements.innerText = "My name is:" + binding.value
})


更新日志

提示:将会持续优化更新

20221203
Vue模板支持js表达式
一个Vue容器只会接管一个元素
一个元素只能被一个Vue接管
指令语法 v-bind: 和 简写 :

20221202
初识Vue.js
实例化Vue,让Vue运行起来
favicon图标加载问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值