24.11.15 Vue3

时间:2024-11-16 19:42:14
    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>