let newJson = new Proxy(myJson,{
get(target,prop){
console.log(`在读取${prop}属性`);
return target[prop];
},
set(target,prop,val){
console.log(`在设置${prop}属性值为${val}`);
if(prop=="name"){
document.getElementById("myTitle").innerHTML = val;
}
if(prop=="age"){
document.getElementById("myText").value = val;
}
target[prop] = val;
}
})
虚拟dom
vue中合理利用了js中的虚拟dom思想
优化原生js多次渲染页面造成的卡顿情况
//指令式js 渲染 浏览器 html解析器 css解析器 js解析器
// document.getElementById("myTitle").innerHTML = 1;
// document.getElementById("myTitle").innerHTML = 2;
// document.getElementById("myTitle").innerHTML = 3;
// 虚拟的dom结构 统一赋值 做一次显示
原理示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 id="myTitle"></h1>
<input id="myText" type="text"/>
</body>
<script>
/* 框架负责dom操作 */
let myVal = 10;
let myJson = {name:"jack",age:15};
console.log(myJson);
// myJson.addr="第五大街"
// console.log(myJson);
//vue原理 响应式数据原理(数据赋值 页面自动渲染)
// vue2原理 数据劫持(把dom操作 藏在getset方法中) vue2加载过程慢
// vue3原理 数据劫持(简单数据 数字 bol值 字符串) 大对象(代理对象 重写get/set)
// Object.defineProperty(myJson,"newAddr",{
// get(){
// console.log("get方法触发了");
// },
// set(val){
// console.log("set方法触发了");
// document.getElementById("myTitle").innerHTML = val;
// }
// })
// //console.log(myJson);
// myJson.newAddr="aaa";
let newJson = new Proxy(myJson,{
get(target,prop){
console.log(`在读取${prop}属性`);
return target[prop];
},
set(target,prop,val){
console.log(`在设置${prop}属性值为${val}`);
if(prop=="name"){
document.getElementById("myTitle").innerHTML = val;
}
if(prop=="age"){
document.getElementById("myText").value = val;
}
target[prop] = val;
}
})
console.log(newJson);
newJson.age=22;
newJson.name="rose";
console.log(newJson);
// newJson.addr = "new street";
// console.log(myJson);
// console.log(newJson);
//vue原理 虚拟dom 做统一渲染
//指令式js 渲染 浏览器 html解析器 css解析器 js解析器
// document.getElementById("myTitle").innerHTML = 1;
// document.getElementById("myTitle").innerHTML = 2;
// document.getElementById("myTitle").innerHTML = 3;
// 虚拟的dom结构 统一赋值 做一次显示
//
</script>
</html>
3常用新语法
3.1es模块化语法(通过模块化做导入导出 替换通过script标签导入js文件)
其他js文件 需要有导出
export 导出
<script type="module">
import 导入
</script>
1默认导出 和导入
js文件中
let myData = "xxxx"
export default myData
注意:只能导出一个对象
导入
<script type="module">
import myData from '文件地址'
注意 只能导入一个对象 名字可以自定义
</script>
2指定导出 和导入
js文件中
let myData1 = "xxxx1"
let myData2 = "xxxx2"
export {myData1,myData2}
注意:可以导出多个对象 函数
导入
<script type="module">
import { myData1,myData2} from '文件地址'
注意 需要使用哪些 就导入哪些
</script>
3.2 函数定义
通过箭头函数 替代匿名函数
function(){}
替换为
()=>{}
如果形参只有一个 ()可以不写
d=>{}
示例:
定义函数
let newFun = (a,b)=>{
return a+b;
}
遍历时使用
let myArr = [1,2,3,4];
myArr.forEach(d=>{
console.log(d);
})
定时函数使用
setInterval(()=>{
console.log(111);
},100)
3.3json中函数的简化定义
注意对比
let myJson = {name:"jack",readBook:function(){
console.log("读书");
}
}
可以简化为:
let myJson = {name:"jack",readBook(){
console.log("读书");
}
}
3.4修饰符
const 用来修饰常量 (实际上 不能通过=赋值) 语法特点
在js中 json对象 经常用const修饰符
示例:
定义json
const myObj = {name:"jack",age:15};
myObj.name="rose";
console.log(myObj);
定义函数
const myFun3 = ()=>{
console.log(1111);
}
4vue中变量定义
vue中存在三种变量
普通变量(跟页面显示无关)
用来记录程序执行过程中的变化数据 类似之前的公共变量
let imgIdx= 1;
响应式变量(改变量 页面自动渲染)
1 引用对象 ref object.definedProperty 简单数据类型(数字 bol 字符串) 全都能用 但是复杂对象慢
//定义
const messageRef = ref(123)
//赋值
messageRef.value = "你好 Vue!"
2 代理对象 reactive 不建议用在简单类型数据 代理对象 proxy json对象
//定义
const myJson = reactive({name:"jack",age:15});
//赋值
myJson.name = "rose";
myJson.age = 77;
函数定义:
使用箭头函数 简化函数定义
const changeName = ()=>{
console.log(myJson);
messageRef.value = "'你好 Vue!'"
//message = '你好 Vue!'
myJson.name = "rose";
myJson.age = 77;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{ messageRef }}
<input type="button" value="改内容" @click="changeName()">
<hr>
<h1>{{myJson.name}}</h1>
<h2>{{myJson.age}}</h2>
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
// vue中使用变量 函数 定义在setup函数中
setup() {
//普通变量 初次显示有效果 后续无效果
//一般用来做公共变量 记录过程变化数据
let message = 'Hello Vue!';
//响应式变量修饰符
//1 引用对象 ref object.definedProperty 简单数据类型 全都能用 但是复杂对象慢
//定义
//const messageRef = ref(123)
//赋值
//messageRef.value = "'你好 Vue!'"
//2 代理对象 reactive 代理对象 proxy json对象
//定义
//const myJson = reactive({name:"jack",age:15});
//赋值
//myJson.name = "rose";
//myJson.age = 77;
//函数定义:
/*
函数名 参数
const changeName = ()=>{
console.log(myJson);
执行的代码
需要返回值加return
}
*/
const messageRef = ref(123)
const myJson = reactive({name:"jack",age:15});
const changeName = ()=>{
console.log(myJson);
messageRef.value = "'你好 Vue!'"
//message = '你好 Vue!'
myJson.name = "rose";
myJson.age = 77;
}
return {
//对外暴漏 div要使用的数据
message,messageRef,myJson,changeName
}
}
}).mount('#app')
</script>
</html>
vue指令 用于绑定变量与DOM的对应关系
5显示文本
常用指令 {{}} 插值表达式
v-hmtl 解析html标签
插值表达式: 显示纯文本 不能解析html标签相当于 innerText属性
v-html指令 可以解析html标签 相当于innerHTML属性
vue中页面元素通常直接在页面中编辑 不需要解析html标签 v-html使用较少
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>欢迎{{ myName }}登录</h1>
欢迎<span><b>{{ myName }}</b> </span>
<hr>
欢迎<span v-html="tempVal"></span>
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const myName = ref('jack')
const tempVal = ref('<b>jack</b>')
return {
myName,tempVal
}
}
}).mount('#app')
/*
显示文本
1.插值表达式
显示文本 可以与其他文本一起编辑 方便使用
相当于 innerText 不能解析html标签
2.v-html指令
相当于 innerHTML 能解析html标签 (用的少)
*/
</script>
</html>
6属性绑定
v-bind 作用时让变量与页面元素的属性建立关联
元素属性
v-bind:type="textType"
变量
const textType = ref('button');
v-bind:type 可以简写 :type
注意:
属性绑定值的部分 可以使用js代码段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.cls1{
color: lightcoral;
}
.cls2{
background-color: lightseagreen;
}
</style>
</head>
<body>
<div id="app">
<input :class="{'cls1':clsStatus1,'cls2':clsStatus2}"
:type="textType"
:value="textVal+'d'"
:disabled="btnStatus">
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const textVal = ref("abc");
const textType = ref('button');
const btnStatus = ref(false);
const currentCls = ref('cls1')
const clsStatus1 = ref(true)
const clsStatus2 = ref(false)
//返回的值少了的不显示,多了的报错
return {
textVal,textType,btnStatus,currentCls,clsStatus1,clsStatus2
}
}
}).mount('#app')
/*
属性操作指令 v-bind
在原生的属性前 加v-bind指令 值的部分对应变量值
元素属性
v-bind:type="textType"
变量
const textType = ref('button');
v-bind:type 可以简写 :type
要与原生的属性适配
普通属性 使用字符串
disabled 使用bol值
class 使用字符串 也可以使用json配置每个样式对应一个bol值
:class="{'cls1':clsStatus1,'cls2':clsStatus2}"
v-bind:type="textType"
js代码段 支持js代码表达式
*/
</script>
</html>
7分支指令
页面生成多分支 根据不同情况 显示页面的不同元素
根据分支生成页面元素
单分支
v-if
双分支
v-if
v-else
多分支
v-if
v-else-if
v-else
注意与v-show的区别
//v-if 分支指令 为false时 代码不存在
//v-show 显示指令 为false时 控制样式 display:none
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
这是一个正常页面
<!-- <div v-if="isVip">
这是登录之后可以看的内容
</div>
<div v-else>
登录之后就可以看见精彩内容了.....
</div> -->
<!-- <div v-if="vipGrade == 1" >
这是普通VIP看的
</div>
<div v-else-if="vipGrade == 2">
这是大VIP看的
</div>
<div v-else-if="vipGrade == 3">
这是至尊VIP看的
</div>
<div v-else-if="vipGrade == 4">
这是VIP中P看的
</div>
<div v-else>
熊B 赶紧重置 精彩内容等着你
</div> -->
<div v-if="isVip">
这是登录之后可以看的内容 v-if
</div>
<div v-show="isVip">
这是登录之后可以看的内容 v-show
</div>
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const isVip = ref(false)
const vipGrade = ref(7)
return {
isVip,vipGrade
}
}
}).mount('#app')
//v-if 分支指令 为false时 代码不存在
//v-show 显示指令 为false时 控制样式 display:none
/*
根据分支生成页面元素
单分支
v-if
双分支
v-if
v-else
多分支
v-if
v-else-if
v-else
注意:多分支时 通过表达式返回bol值
<div v-if="vipGrade == 1" >
这是普通VIP看的
</div>
*/
</script>
</html>
8.事件指令
onclick 原生事件
v-on:click vue中的事件
@click 简写
原生事件 on 换成@ 就可以了
注意:vue中配置的函数 如果没有传参 不用写()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div>{{divVal}}</div>
<input type="text" :value="textVal"/>
<input type="button" value="测试" @click="myTest('aaa')"/>
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const divVal = ref('')
const textVal = ref('')
const myTest = (val)=>{
console.log(val);
divVal.value = val;
textVal.value = val;
}
return {
myTest,divVal,textVal
}
}
}).mount('#app')
/*
vue中 事件
onxxx onclick onchange
变成
@xxx @click @change
页面中使用的函数 也需要对外暴漏
页面中函数调用 如果不传参 可以不写()
*/
</script>
</html>
9双向绑定v-model
普通属性绑定 单向的
model --- > view
变量 页面元素
当model发生改变事 view会自动变化
v-model表单元素
双向绑定
model < --- > view
变量 页面元素
双方一起变化
不管是vue的属性还是js原生属性v-model都可使其一起发生变化
输入类(输入框 密码框):
输入类(输入框 密码框)
v-model 替代value属性
<input type="text" :value="textVal"> 单向
<input type="text" v-model="textVal"> 双向
选择类(单选按钮 多选按钮):
v-model 分组 表示被选中的值 checked用不到
<input type="radio" v-model="gender" value="1"/>男
<input type="radio" v-model="gender" value="2"/>女
radio 使用单值变量 const gender = ref('1')
<input type="checkbox" v-model="hobby" value="java"/>java
<input type="checkbox" v-model="hobby" value="js"/>js
<input type="checkbox" v-model="hobby" value="python"/>python
checkbox 使用数组变量 const hobby = ref([])
下拉列表
<select v-model="area">
<option disabled value="">---------请选择------------</option>
<option value="1">北京1</option>
<option value="2">北京2</option>
<option value="3">北京3</option>
</select>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="textVal">
<button @click="testBtn">测试按钮</button>
<hr>
<input type="radio" v-model="gender" value="1"/>男
<input type="radio" v-model="gender" value="2"/>女
{{gender}}
<hr>
<input type="checkbox" v-model="hobby" :value="1"/>java
<input type="checkbox" v-model="hobby" :value="2"/>js
<input type="checkbox" v-model="hobby" :value="'3'"/>python
{{hobby}}
<hr>
<select v-model="area">
<option disabled value="">---------请选择------------</option>
<option value="1">北京1</option>
<option value="2">北京2</option>
<option value="3">北京3</option>
</select>
{{area}}
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const textVal = ref('jack');
const gender = ref('1')
const hobby = ref([2])
const area = ref('')
const testBtn = ()=>{
//textVal.value = "rose"
console.log(textVal.value);
}
return {
textVal,testBtn,gender,hobby,area
}
}
}).mount('#app')
/*
vue中 通过双向绑定 让变量获取表单元素的数据
普通属性绑定 单向的
model --- > view
变量 页面元素
当model发生改变事 view会自动变化
v-model
表单元素
双向绑定
model < --- > view
变量 页面元素
双方一起变化
输入类(输入框 密码框)
v-model 替代value属性
<input type="text" :value="textVal"> 单向
<input type="text" v-model="textVal"> 双向
选择类(单选 多选按钮)
v-model 分组 表示被选中的值 checked用不到
<input type="radio" v-model="gender" value="1"/>男
<input type="radio" v-model="gender" value="2"/>女
radio 使用单值变量 const gender = ref('1')
<input type="checkbox" v-model="hobby" value="java"/>java
<input type="checkbox" v-model="hobby" value="js"/>js
<input type="checkbox" v-model="hobby" value="python"/>python
checkbox 使用数组变量 const hobby = ref([])
加上属性绑定 可以控制数据类型
value="3" 字符串
:value="'3'" 字符串
:value="3" 数字
下拉列表
<select v-model="area">
<option disabled value="">---------请选择------------</option>
<option value="1">北京1</option>
<option value="2">北京2</option>
<option value="3">北京3</option>
</select>
配置单值变量 对应被选中的option的值
const area = ref('')
*/
</script>
</html>
10遍历指令
v-for 遍历生成元素
v-for="每次遍历到的元素 in 遍历的集合"
v-for="(每次遍历到的元素,索引) in 遍历的集合"
v-for="obj in list" obj作为遍历到元素的临时变量
:key作用:给列表项添加的**唯一标识。便于Vue进行列表项的正确排序复用。
1. key 的值只能是字符串 或 数字类型
2. key 的值必须具有唯一性
3. 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)
遍历时 生成元素要搭配的语法
生成文本 {{}}
生成属性 :属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="newsData in myNews" :key="idx">{{idx}}--{{newsData.content}}</li>
</ul>
<table border="1">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<tr v-for="stu in stuList">
<td>{{stu.id}}</td>
<td>{{stu.name}}</td>
<td>{{stu.age}}</td>
</tr>
</table>
<select v-model="selVal">
<option disabled value="">---------请选择------------</option>
<option v-for="opa in opaList" :value="opa.code">{{opa.name}}</option>
<option value="004">河南</option>
</select>
{{selVal}}
</div>
</body>
<script type="module">
import { createApp,ref,reactive } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const opaList = ref([
{code:'001',name:'北京'},
{code:'002',name:'上海'},
{code:'003',name:'深圳'}
])
const selVal = ref('')
const myNews = ref([{content:"“退钱哥”说不退钱了"},
{content:"神十九航天员要准备收快递了"},
{content:"沙特官员辟谣来珠海航展只为扫货"}
])
const stuList = ref([{id:1,name:"jack",age:15},
{id:2,name:"jack2",age:17},
{id:3,name:"jack3",age:12}
])
return {
myNews,stuList,selVal,opaList
}
}
}).mount('#app')
/*
v-for 遍历生成元素
v-for="每次遍历到的元素 in 遍历的集合"
v-for="(每次遍历到的元素,索引) in 遍历的集合"
v-for="obj in list"
遍历时 使用每次遍历的元素
obj.key
{{obj.key}} 生成文本数据
:属性="obj.key" 生成元素的属性
遍历时 如果加上:key属性 作为唯一标记 给每条数据加唯一标记 (可选)
table遍历生成
<tr v-for="stu in stuList">
<td>{{stu.id}}</td>
<td>{{stu.name}}</td>
<td>{{stu.age}}</td>
</tr>
select遍历生成
<select v-model="selVal">
<option disabled value="">---------请选择------------</option>
<option v-for="opa in opaList" :value="opa.code">{{opa.name}}</option>
<option value="004">河南</option>
</select>
*/
</script>
</html>