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-ifv-else多分支v-ifv-else-ifv-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-ifv-else多分支v-ifv-else-ifv-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"/>pythoncheckbox 使用数组变量 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"/>pythoncheckbox 使用数组变量 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>