Vue基本使用

发布于:2023-01-04 ⋅ 阅读:(496) ⋅ 点赞:(0)

 vue插件内容解析

vue 的实例构建及基本使用

vue2 两种基本使用方式

vue3的两种基本使用

 基本交互

1.插值表达式

语法: Mustache 语法 {{ }}
功能:取决于JS框架为其赋予的功能特性, 在不同的框架下 语法功能能不同
特性:响应式数据功能 当变量发生变化时该标签会重新渲染加载。
使用: < 标签 >{{ Vue 对象数据仓库变量 |JS 表达式 |JS 内置对象 }}</ 标签 >
范围:插值表达式只能被定于标签内容中
注意:
html格式字符串将不被解析
js 转义符将不被识别

 

{{}} vue的插值表达式 => Mustache语法 {{ 变量 }}

                 功能:用于加载当前容器对应的vue应用提供的-数据仓库变量-

                      取决于JS框架为其赋予的功能特性,在不同的框架下 语法功能能不同

                 范围:插值表达式只能被定于标签内容中

                 使用:<标签>{{ Vue应用数据仓库变量|JS匿名变量|JS表达式|JS内置对象 }}</标签>

                 记忆:当模板语法处于{{}}内部时,当做JS代码进行开发(注意使用范围)

<div id="app">
        <!-- 
            {{}} vue的插值表达式 => Mustache语法 {{ 变量 }}
                 功能:用于加载当前容器对应的vue应用提供的-数据仓库变量-
                      取决于JS框架为其赋予的功能特性,在不同的框架下 语法功能能不同
                 范围:插值表达式只能被定于标签内容中
                 使用:<标签>{{ Vue应用数据仓库变量|JS匿名变量|JS表达式|JS内置对象 }}</标签>
                 记忆:当模板语法处于{{}}内部时,当做JS代码进行开发(注意使用范围)
        -->
        <!-- <p class="{{ msg }}"></p> -->
        <p >Vue应用数据仓库变量-msg:{{ msg }}</p>
        <!-- <p >JS匿名变量:{{ 匿名字符串 }}</p> -->
        <p >JS匿名变量:{{ '匿名字符串' }}</p>
        <p >JS匿名变量:{{ 100 }}</p>
        <p >JS匿名变量:{{ [1,2,3,4,5,6] }}</p>
        <!-- 构建匿名对象时,必须通过空格明确分割语法和对象 -->
        <p >JS匿名变量:{{ { a:1,b:2 } }}</p>
        <p>vue的仓库变量msg的值是:{{ msg }}</p>
        <!-- <p >JS表达式:{{ JS表达式 }}</p> -->
        <p>{{ 'vue的仓库变量msg的值是:' + msg }}</p>
        <p>{{ num * 100 }}%</p>
        <p>arr:{{ arr }}</p>
        <p>arr[0]:{{ arr[0] }}</p>
        <p>user:{{ user }}</p>
        <p>user.username:{{ user.username }}</p>
        <p>user['username']:{{ user['username'] }}</p>
        <p>flag三目计算:{{ flag?"真":"假" }}</p>
        <p>flag三目计算:{{ !flag?"真":"假" }}</p>
        <!-- 使用错误 -->
        <!-- <p>{{ for(){} }}</p> -->
        <!-- <p >JS内置对象:{{ JS内置对象 }}</p> -->
        <p>PI:{{ Math.PI }}</p>
        <p>random:{{ Math.random }}</p>
        <p>random():{{ Math.random() }}</p>
2.基础指令
为开发者提供的,在页面中进行特殊功能执行的的属性描述语法
语法:Vue指令以 v- 名称 结构定义
位置: 指令只能被用于 html 容器的标签属性上 < 标签 v- 指令 ="" ></ 标签 >
实现:指令本身实际上就是一个JS方法的特殊封装,页面定义的指令只是对方法的调用和
触发
功能:通过指令可实现 HTML标签写入,标签判断、标签循环、标签事件绑定、标签属性
绑定……
完整语法: v- 指令名 [: 参数 ][. 修饰符 ][……][=" 取值 "]
指令特性:无痕迹特性==代码开发时标签上的vue语法表达式,在项目运行时会被删除,
不会保留
指令特性:指令中部分特殊指令和插值表达式一样具有响应式特性 1、v-text
取值: string
功能:更新元素的 textContent 。如果要更新部分的 textContent ,需要使用 {{
Mustache }} 插值。
示例: <span v-text="msg"></span>
2、v-html
取值: string
功能:更新元素的 innerHTML
示例: <div v-html="html"></div>
3、v-pre
取值: 不需要表达式 ,该指令为boolean类型属性
写表示 true(启用功能) 不写表示 false(不启用功能)
功能:跳过这个元素和它的子元素的编译过程。
示例: <span v-pre>{{ 该语法会直接显示在页面 }}</span>
4、v-once
取值: 不需要表达式 ,该指令为boolean类型属性
写表示 true(启用功能) 不写表示 false(不启用功能)
功能:对当前元素和内部元素vue功能执行 一次 ,程序执行过程不再对该元素范围内的vue
功能进行重新执行
示例: <span v-once> 该区域 vue 功能只在初始化时执行一次 {{msg}}</span>

5、v-cloak
取值: 不需要表达式 ,该指令为boolean类型属性
功能:实现在vue功能构建完成前,隐藏浏览上vue语法表达式, 该指令本身不具有特殊功
能,需配合css样式实现效果
v-html 、v-text等指令都可实现渲染之前的隐藏操作,但是该指令在完成渲染之前的隐藏操作时,属于影响最小的指令(副作用最小的指令)
示例:
[v-cloak] {
display : none;
}
<div v-cloak >
{{ message }}
/ div>
<style>
        /* 属性选择器 */
        [v-cloak],
        [v-html] {
            display: none;
        }

        [v-cloak]+.loading {
            display: block;
        }

        .loading {
            display: none;
            position: fixed;
            top: 0px;
            left: 0px;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.6);
            color: white;
            font-size: 40px;
            text-align: center;
            padding-top: 200px;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <div id="app" v-cloak>
        <p>插值表达式:{{msg}}</p>
        <p v-text="'v-text:'+msg"></p>
    </div>
    <div class="loading">
        loading
    </div>
    <script type="module">
        import { createApp } from "../assets/vue3.0/vue.esm-browser.js"
        // 模拟网络状态缓慢的情况
        setTimeout(() => {
            createApp({
                data() {
                    return {
                        msg: "仓库数据MSG"
                    }
                }
            }).mount("#app")
        }, 5000)

6、v-on

缩写: @ ,项目中可用 @ 替代 v-on:
语法:
<button v-on: 参数 . 修饰符 = " 取值 " > / button>
<button @ 参数 . 修饰符 = " 取值 " > / button>
- 动态事件 >
<button v-on: [ 仓库变量 ]= " 取值 " > / button>
<button @[ 仓库变量 ]= " 取值 " > / button>

- 取值:Function | Inline Statement | Object | Array

                        * 当事件绑定时取值为 对应 方法名时,可以省略 () 不写

                    - 事件名称:JavaScript 的 eventName

取值: Function | Inline Statement | Object | Array
参数:eventName(事件名称)
功能:绑定元素事件监听器,事件类型由参数指定
v-on 绑定的事件必须是vue对象 方法仓库 中的一个自定义方法
 <div id="app">
        <!-- 
        v-on 指令
            + 功能:绑定元素事件监听器,事件类型由参数指定
            + 缩写:@ ,项目中可用 @ 替代 v-on:  => @缩写方法必须携带事件名
            +  语法:
                <button v-on:事件名称="取值"></button>
                <button @事件名称="取值"></button>
                    - 取值:Function | Inline Statement | Object | Array
                        * 当事件绑定时取值为 对应 方法名时,可以省略 () 不写
                    - 事件名称:JavaScript 的 eventName

        v-on事件绑定对应的回调方法,根据vue的语法要求应该是容器对应的应用methods方法仓库中定义方法 
            methods:{
                方法名:Function
            }
            + methods 中定义方法,在vue程序构建时,会将此区域中的所有方法定义通过 call 方式调用的方法
                      而 js 中 call函数在执行方法时,可以通过 参数方式设置方法的内部this指向
                      this 指向被锁死在 当前vue应用实例上;
            + 因为vue在构建应用实例时,数据仓库中的数据,方法仓库中方法,最终都会被直接作为当前vue应用
              实例的根数据进行绑定,所以通过构建vue应用实例对象是可以直接方法这些定义数据的
            + methods 定义的一层属性的方法取值为保证this指向,必须是普通函数
        -->
        <h5>取值:function</h5>
        <input type="button" value="v-on:click提示-带()" v-on:click="showInfo()">
        <input type="button" value="@click提示-带()" @click="showInfo()">
        <!-- 不带() 的写法主要用于 vue组件化开发中 ==> 02vue进阶篇-组件数据传递 详细讲解 -->
        <input type="button" value="v-on:click提示-不带()" v-on:click="showInfo">
        <input type="button" value="@click提示-不带()" @click="showInfo">
        
        <h5>取值:Inline Statement 赋值行内表达式</h5>
        <p>flag:{{ flag }}</p>
        <p>flag1:{{ flag1 }}</p>
        <input type="button" value="changeFlag" @click="changeFlag()">
        <input type="button" value="flag=!flag" @click=" flag = !flag; flag1 = !flag; ">

        <h5>取值:Object 通过 v-on 指令一次性完成多事件的绑定操作</h5>
        <input type="text" placeholder="input&change-无法执行" v-on=" { input:callbackA(),change:callbackB() } ">
        <br>
        <input type="text" placeholder="input&change" v-on=" { input:callbackA,change:callbackB } ">
        <input type="text" placeholder="input&change-data中的事件对象" v-on="events">
        <br>
        <input type="text" placeholder="input&change-data中的事件对象" v-on="events1">
        <input type="text" placeholder="input&change-data中的事件对象" v-on="events2">
        <br>
        <input type="text" placeholder="input&change" v-on:input="callbackA()" @change="callbackB()">

        <h5>取值:Array 通过 v-on 指令为一个事件绑定多个回调</h5>
        <input type="button" value="绑定两个回调-不能执行" @click="[ callbackC(),callbackD() ]">
        <br>
        <input type="button" value="绑定两个回调" @click="[ callbackC,callbackD ]">
        <input type="button" value="绑定两个回调" @click="[ callbackD,callbackC ]">
        <br>
        <!-- 当一个元素同时出现相同事件绑定的指令时,只有最先绑定的有效 -->
        <input type="button" value="绑定两个回调" @click="callbackC()" @click="callbackD()">
        <br>
        <!-- 实际项目开发中常用的是如下绑定规则 -->
        <input type="button" value="绑定两个回调" @click="callbackC(),callbackD()">

    </div>

    <script type="module">

        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        import Message from "../assets/message/message.js"
        let app = createApp({
            data(){
                // 仓库方法data中的this在vue3中依然指向于当前vue的应用实例
                return {
                    flag:false,
                    flag1:true,
                    events:{
                        // this.callbackA this.callbackB 来自于 methods 方法仓库
                        input:this.callbackA,
                        change:this.callbackB
                    },
                    events1:{
                        input:function(){
                            console.log("input-匿名-普通方法",this)
                        },
                        change:function(){
                            console.log("change-匿名-普通方法",this)
                        }
                    },
                    events2:{
                        input:()=>{
                            console.log("input-匿名-箭头函数",this)
                        },
                        change:()=>{
                            console.log("change-匿名-箭头函数",this)
                        }
                    }
                }
            },
            // 方法仓库
            methods: {
                showInfo:function(){
                    Message.info({
                        message:"测试事件绑定"
                    })
                },
                changeFlag(){
                    console.log(app===this);
                    console.log(app,this);
                    this.flag = !this.flag;
                },
                // changeFlag:()=>{
                //     console.log(app===this);
                //     console.log(app,this);
                //     this.flag = !this.flag;
                // },
                callbackA(){
                    console.log("input事件触发");
                },
                callbackB(){
                    console.log("change事件触发");
                },
                callbackC(){
                    console.log("方法1");
                    // this.callbackD()
                },
                callbackD(){
                    console.log("方法2");
                }
            },
        }).mount("#app")
    </script>
 <div id="app">
        <h5>vue2 语法中 取值Object 时 v-on 不能使用 缩写关键字 @</h5>
        <!-- 
            v-on = " { 事件名:回调方法|表达式 , …… } "
            v-on 对象取值绑定方式 不支持 @ 缩写关键字的
                 对象中事件的对应回调方法不能被调用
         -->
        <input type="text" placeholder="input&change" v-on=" { input:callbackA,change:callbackB } ">
        <!-- <input type="text" placeholder="input&change" @=" { input:callbackA,change:callbackB } "> -->

        <h5>vue2 语法中 v-on 绑定数据取值 data 仓库中变量时 this 的问题</h5>
        <input type="text" placeholder="input&change" v-on="events">


    </div>

    <script type="module">

        import Vue from "../assets/vue/2.0/vue.esm.browser.js";
        import Message from "../assets/message/message.js"
        let vm = new Vue({
            el: "#app",
            // data:{
            //     events:{
            //         input:this.callbackA,
            //         change:this.callbackB
            //     },
            // },
            data() {
                console.log(this);
                return {
                    events: {
                        input: this.callbackA,
                        change: this.callbackB
                    },
                }
            },
            methods: {
                callbackA() {
                    console.log("input事件触发");
                },
                callbackB() {
                    console.log("change事件触发");
                },
            },
        })
    </script>

vue中容器的环境实际上就是与之对应的vue应用实例

在vue容器环境中 ,事件源对象的关键字 被修改为了 $event

vue3 容器页面中的this 为当前容器的应用实例对象

<!-- vue中容器的环境实际上就是与之对应的vue应用实例 -->
    <div id="app">
        <h5>匿名参数 = v-on 完成事件回调绑定时,以JS语法规范提供参数</h5>
        <input type="button" value="事件匿名参数" 
            @click="printArgs('字符串',123,false,[1,2],{a:1},new Date(),new Set([1,2]) )"
        >

        <h5>vue应用的仓库变量参数&表达式参数 = 以JS语法规范提供参数(变量只能是容器对应应用的仓库数据)</h5>
        <!-- info 获取不到 -->
        <input type="button" value="事件仓库变量参数" 
            @click="printArgs( msg,info,`仓库变量msg的值是:${msg}` )"
        >

        <h5>事件源对象参数 = 触发该事件的组成对象(对象中记录事件触发时相关功能参数-参数会因触发方式不同发生变化)</h5>
        <!-- 在vue容器环境中 ,事件源对象的关键字 被修改为了 $event -->
        <input type="button" value="点击事件源对象" @click="printEvent( event )">
        <input type="button" value="点击事件源对象" @click="printEvent( $event )">

        <h5>容器页面中的this = (不要在容器中使用this关键字)</h5>
        <!-- vue3 容器页面中的this 为当前容器的应用实例对象 -->
        <input type="text" @input="getInputNewValue1(this.value)">
        <input type="text" @input="getInputNewValue1(this)"><br>
        <p>nv:{{ nv }}</p>
        <input type="text" @input="getInputNewValue( $event.target.value )">
        
    </div>

    <script type="module">
        let info = "js全局环境的变量";
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        createApp({
            data(){
                return {
                    msg:"仓库数据变量",
                    nv:""
                }
            },
            methods: {
                // 方法形参定义模式为 ...变量名 ,表示该方法可以接收任意长度的参数
                // 参数会被组成数组 提供变量
                printArgs(...args){
                    console.log("参数:",args);
                },
                printEvent(e){
                    console.log(e);
                },
                getInputNewValue1(v){
                    console.log(v)
                },
                getInputNewValue(v){
                    console.log(v)
                    this.nv = v;
                }
            },
        }).mount("#app")
    </script>

vue2 容器页面中的this 是 window 对象

<!-- vue中容器的环境实际上就是与之对应的vue应用实例 -->
    <div id="app">
        <h5>容器页面中的this</h5>
        <!-- vue2 容器页面中的this 是 window 对象 -->
        <input type="text" @input="getInputNewValue1(this)"><br>
        <input type="text" @input="getInputNewValue1(this.value)">
        <p>nv:{{ nv }}</p>
        <input type="text" @input="getInputNewValue( $event.target.value )">
        
    </div>

    <script type="module">
        let info = "js全局环境的变量";
        import Vue from "../assets/vue/2.0/vue.esm.browser.js";
        new Vue({
            el:"#app",
            data(){
                return {
                    nv:""
                }
            },
            methods: {
                getInputNewValue1(v){
                    console.log(v)
                },
                getInputNewValue(v){
                    console.log(v)
                    this.nv = v;
                }
            },
        })
    </script>
事件修饰符: 通过调用事件源对象的内置事件方法,完成事件功能限制(例如阻止事件冒
泡等)
.once : 被该修饰符修饰的事件一旦被调用一次后,会直接删除事件绑定 - 一次性事
 v-on:事件名.修饰符.修饰符……[="回调方法"]

<input type="button" value="一次性事件" @click.once="printFun()">

 

 html 结构中,元素存在层级嵌套关系,而页面布局需要使用嵌套元素结构构建复杂页面

                 但事件是和元素进行的绑定,必然存在部分元素只为了页面效果存在,事件被定义于父元素上

                 当功能是希望通过任意子元素触发都可以调用父元素事件

            为了实现上述功能,html事件操作时引入了事件传播机制 - 子元素被执行了相关事件事件,其父元素也会被执行相关事件 (相同事件)

            html事件传播提供两种传播方式 =>

                + 事件冒泡(主流浏览器) :在事件传播机制基础上,由子元素向父元素顺序调用事件

                + 事件捕获 :在事件传播机制基础上,由父元素向子元素顺序调用事件

.prevent : 为事件添加阻止默认事件功能(调用js event.preventDefault())
.stop : 为事件添加阻止事件冒泡(方法执行)特性(调用js
event.stopPropagation())
.capture :改变事件执行顺序,将冒泡事件转换为事件捕获
 <!-- 捕获是优先于冒泡 -->
        <div class="box" @click.capture="printName('div1')">div1
            <div class="box" @click="printName('div2')">div2
                <div class="box" @click.stop="printName('div3')">div3
                    <div class="box" @click.capture="printName('div4')">div4
                        <div class="box" @click="printName('div5')">div5</div>
                    </div>
                </div>
            </div>
        </div>
打印结果为:1,4,5,3

.self : 事件只有被绑定的元素才具有权限触发 - 仍然保留事件冒泡(事件穿透)

是只有点击该元素时才会触发事件,点击其他该元素不触发事件

按键修饰符: 通过对电脑外设的按键进行监听控制操作,完成回调触发限制
.{keyAlias} 对js键盘事件而言,事件源对象($event)必然存在两个特殊取值 keyCode
key
.enter 别名限定回车键
.tab 别名限定缩进键
.esc 别名限定退出键
.space 别名限定空格键
.delete (捕获“删除”和“退格”键)
.up 别名定义方向上 .down 别名定义方向下
.left 别名定义键盘方向左、定义鼠标左键
.right 别名定义键盘方向右、定义鼠标右键
.middle 定义鼠标中键(滚轮键)
 <!-- middle 修饰符只能限制点击效果 -->
        <textarea cols="30" rows="5" @click.middle=" setInfo($event)  "></textarea>

!!! 按键修饰符 连写为或者关系

​
 <!-- 按键修饰符的连写属于或者关系 -->
        <textarea cols="30" rows="5" @keydown.a.b.c.d=" setInfo($event)  "></textarea>

​
系统修饰符: 监听外设键盘的上的特殊系统功能按键的状态
.ctrl 描述ctrl被激活时触发事件
.alt 描述alt被激活时触发事件
.shift 描述shift被激活时触发事件
.meta 描述meta被激活时触发事件
!!!系统修饰键配合按键修饰符连写为并且关系
<!-- 
            键盘按键和系统按键同时定义时属于 并且关系
         -->
        <textarea cols="30" rows="5" @keydown.ctrl.a=" setInfo($event) "></textarea>
        <br>
        <!-- ctrl+a || ctrl+c -->
        <textarea cols="30" rows="5" @keydown.ctrl.a.c=" setInfo($event) "></textarea>
        <br>
        <!-- ctrl+alt+a -->
        <textarea cols="30" rows="5" @keydown.ctrl.alt.a=" setInfo($event) "></textarea>
        <br>
      
       

精确修饰符(2.5+):

.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
 <!-- exact 修饰符限制事件触发 只能是 ctrl+alt+a -->
        <textarea cols="30" rows="5" @keydown.ctrl.alt.a.exact=" setInfo($event) "></textarea>
7、v-bind
缩写: : ,项目中可用 替代 v-bind:
语法:
<p v-bind: 参数 . 修饰符 = " 取值 " > / p>
<p : 参数 . 修饰符 = " 取值 " > / p>
- 动态属性 >
<p v-bind: [ 仓库变量 ]= " 取值 " > / p>
<p : [ 仓库变量 ]= " 取值 " > / p>
 <!-- vue2.6^ 版本提供 事件绑定时事件名描述关键字 [] , [] 中定义名字将被作为仓库变量进行加载 -->
        <input type="text" v-on:[en]=" msg = $event.target.value "> <br>
<script type="module">
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        createApp({
            data(){
                return {
                    en:"input",
                }
            }
        }).mount("#app")
取值: any ( 对应属性取值 ) | Object ( 对应属性取值 )
参数: attrOrProp (optional)
作用:
动态地绑定一个或多个元素属性。
在绑定 class style 特性时,支持其它类型的值,如数组或对象。
示例: - 绑定一个属性 >
<img v-bind:src = "imageSrc" >
v-bind 完成 样式属性操作
:class :style的三种取值方式
String类型取值=>按照HTML标签属性class取值规则进行定义即可

Object类型取值=>通过JS对象的key表示样式名,value取值true|false表示样式是否生效

Array类型取值=>提供样式列表,实现样式的循环组合显示=>classList

动静结合绑定操作=>class静态样式定义和动态样式绑定可以同时存在
 <style>
        body{
            padding-bottom: 800px;
        }
        .fs{
            font-size: 24px;
        }
        .fc{
            color: red;
        }
        .bc{
            background-color: #ccc;
        }
        .border{
            border: 4px solid black;
        }
    </style>
</head>
<body>
    <div id="app">
        <h4>v-bind 完成 样式属性操作</h4>
        <h5>class的动态绑定</h5>

        <p>String类型取值=>按照HTML标签属性class取值规则进行定义即可</p>
        <!-- 简单样式组成时的动态操作 -->
        <div :class=" classStr ">string变量绑定</div>
        <input type="button" value="切换fc" @click="changeStringFc()">
        
        <br>
        <p>Object类型取值=>通过JS对象的key表示样式名,value取值true|false表示样式是否生效</p>
        <div :class=" classObj ">Object变量绑定</div>
        <input type="button" value="切换fs" @click=" classObj.fs = !classObj.fs ">
        <input type="button" value="切换fc" @click=" classObj.fc = !classObj.fc ">
        <input type="button" value="切换bc" @click=" classObj.bc = !classObj.bc ">
        <input type="button" value="切换border" @click=" classObj.border = !classObj.border ">
        <div :class=" { fc:flag } ">Object变量绑定</div>
        <input type="button" value="切换fc" @click=" flag = !flag ">

        <br>
        <p>Array类型取值=>提供样式列表,实现样式的循环组合显示=>classList</p>
        <div :class=" classArr ">Array变量绑定</div>
        <input type="button" value="切换fc" @click="changeArrayFc()">

        <h5>动静结合绑定操作=>class静态样式定义和动态样式绑定可以同时存在</h5>
        <!-- <div :id=" fc " id="a" ></div> -->
        <div class="fs bc border" :class=" fc ">动静结合绑定操作</div>

        <hr>
        <h5>style的动态绑定</h5>

        <p>String类型取值=>按照HTML标签属性style取值规则进行定义即可</p>
        <div :style=" styleStr ">style-string动态绑定</div>
        
        <p>Object类型取值=>通过JS对象的key表示样式名(可以定义JS的行内样式名),value取值是样式的有效取值(vue会剔除无效属性)</p>
        <div :style=" styleObj ">style-Object动态绑定</div>
        <div :style=" { color:'red',fontSize:size+'px' } ">style-Object动态绑定</div>
        <input type="button" value="+" @click=" size++ ">
        <input type="button" value="-" @click=" size-- ">

        <p>Array类型取值=>组合程序多个对象的行内样式取值-(复用动态样式)</p>
        <div :style=" [ styleObj,styleObj2 ] ">style-Object动态绑定</div>

        <h5>动静结合绑定操作=>style静态样式定义和动态样式绑定可以同时存在</h5>
        <div style="color:red" :style=" `font-size:${size}px` ">style-动静结合绑定绑定</div>
    </div>

    <script type="module">
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        createApp({
            data(){
                return {
                    classStr:"fs fc bc border",
                    classObj:{
                        fs:true,
                        fc:true,
                        bc:true,
                        border:true
                    },
                    flag:false,
                    classArr:["fs","fc","bc","border"],
                    fc:"fc",
                    styleStr:"color:red;font-size:24px",
                    styleObj:{
                        color:"blue",
                        // "font-size":"24px"
                        fontSize:"24px"
                    },
                    styleObj2:{
                        border:"2px solid black"
                    },
                    size:24
                }
            },
            methods: {
                changeStringFc(){
                    let arr = this.classStr.split(" ");
                    // console.log(arr);
                    let i = arr.indexOf("fc")
                    if(i>=0){
                        arr.splice(i,1);
                    }else{
                        arr.push("fc")
                    }
                    this.classStr = arr.join(" ");
                },
                changeArrayFc(){
                    let set = new Set(this.classArr);
                    if(set.has("fc")){
                        set.delete("fc")
                    }else{
                        set.add("fc")
                    }
                    this.classArr = Array.from(set);
                }
            },
        }).mount("#app")
    </script>
修饰符:
.camel - 将 kebab-case attribute 名转换为 camelCase。仅配合提供给svg标签属性使用的

.prop - 将一个绑定强制设置为一个 DOM property。

.attr - 将一个绑定强制设置为一个 DOM attribute。

8、v-show
取值: any
功能:根据表达式的 boolean 结果, 切换元素的 display CSS 属性,控制元素显示隐藏
示例: <p v-show=" flag "></p>
9、v-if、v-else-if、v-else
取值:
v-if: any
v-else-if: any
v-else: 不需要表达式 ,该指令为boolean类型属性
用法:根据表达式的boolean结果, 执行元素的创建和删除操作
示例:
<div v-if = "type = 'A'" > A / div>
<div v-else-if = "type = 'B'" > B / div>
<div v-else > Not A/B/C / div>
v-else 指令的上一个元素 必须使用了 v-if 或者 v-else-if
v-else-if 指令的上一个元素 必须使用了 v-if

取值:

            * v-if:any

            * v-else-if:any

            * v-else:不需要表达式,该指令为boolean类型属性

                * v-else 指令的上一个兄弟元素(不含注释) 必须使用了 v-if 或者 v-else-if

                * v-else-if 指令的上一个兄弟元素(不含注释) 必须使用了 v-if 或者 v-else-if

v-show&v-if 的取值必须是可用于判断的boolean结果,如果取值不是boolean类型,遵守JS转换规则

        v-show

            * 取值:any

            * 功能:根据表达式的 boolean 结果,切换元素的 display CSS 属性,控制元素显示隐藏

            * 示例:`<p v-show=" flag "></p>`

       

        v-if

            * 取值:any

            * 功能:根据表达式的 boolean 结果,描述元素在页面渲染时的创建和删除

<h4>项目开发时什么时候使用v-show,什么时候使用v-if,两者有什么区别</h4>

        <ul>

            <li>区别:v-show通过css控制元素显示隐藏,而v-if通过元素的创建很删除描述元素的显示和消失</li>

            <li>数据安全:v-if项目中存在用户敏感数据需要保护,只能损失性能提高安全性; <br>

                程序安全:v-show在程序第一次加载时直接完成元素的创建和渲染操作,然后才完成渲染显示和隐藏操作, <br>

                v-if在程序第一加载时就会完成逻辑判断,确认是否需要创建该元素,因此v-if的程序安全性高于v-show

            </li>

            <li>运行效率:v-show的效率高于v-if => 性能优先的情况下,可以小范围进行性能提升</li>

            <li>v-if可以实现多分支连续判断</li>

        </ul>

10 v-for
功能:基于数据多次渲染元素或模板块
语法: < 标签 v - for=" 取值变量 in 待循环值 "></ 标签 >
< 标签 v - for=" ( 取值变量 , 取值变量 , 取值变量 ) in 待循环值 "></ 标签 >
待循环值取值: Array | Object | number | string | Iterable
取值表达式:可直接定义临时变量;
取值表达式:也可以为数组索引指定别名 ( 或者用于对象的键 )
<div v-if = "type === 'A'" > A </div>
<div v-else-if = "type === 'B'" > B </div>
<div v-else > Not A/B/C </div>
<div v-for = "item in items" >
{{ item.text }}
</div>
<div v-for = "(value, index) in arrs" ></div>
<div v-for = "(val, key) in object" ></div> <div v-for = "(val, name, index) in object" ></div>
<p>arr:{{ arr }}</p>
        <!--  let arr = ["aa","bb","cc"]
        for (let str of arr) {
            str = "11";
        }
        console.log(arr) -->
        <p>不会对arr进行任何修改,因为str为基本数据类型,修改只在该变量上生效</p>
        <ul>
            <li v-for="(str, i) in arr">
                <input type="text" :value="str" @input=" str = $event.target.value ">
            </li>
        </ul>
        <p>会对arr进行修改,因为arr[i]为引用调用,修改会发生在原数据的地址指向上</p>
        <ul>
            <li v-for="(str, i) in arr">
                <input type="text" :value="str" @input=" arr[i] = $event.target.value ">
            </li>
        </ul>
        <hr>
        <pre>list:{{ list }}</pre>
        <p>会对list进行修改,因为该数组循环后的每个元素依然是引用数据类型,直接修改该引用数据的属性等同地址指向性修改</p>
        <ul>
            <li v-for="(p, i) in list">
                {{ p.product }}: <input type="text" :value="p.num" @input=" p.num = $event.target.value ">
                <input type="button" value="修改销量" @click="setNum(i)">
                <input type="button" value="修改销量" @click="setNum2(p)">
            </li>
        </ul>
    </div>

    <script type="module">
        

        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        createApp({
            data(){
                return {
                    sales:[
                        { 
                            year:"2020",
                            list:[
                                { product: 'Matcha Latte', num:100},
                                { product: 'Milk Tea', num:50 },
                                { product: 'Cheese Cocoa', num:30 },
                                { product: 'Walnut Brownie', num:40 }
                            ] 
                        },
                        { 
                            year:"2021",
                            list:[
                                { product: 'Matcha Latte', num:80},
                                { product: 'Milk Tea', num:60 },
                                { product: 'Walnut Brownie', num:70 }
                            ] 
                        },
                        { 
                            year:"2022",
                            list:[
                                { product: 'Matcha Latte', num:120},
                                { product: 'Milk Tea', num:70 },
                                { product: 'Cheese Cocoa', num:80 },
                                { product: 'Walnut Brownie', num:10 }
                            ] 
                        }
                    ],
                    arr:["aa","bb","cc"],
                    list:[
                        { product: 'Matcha Latte', num:100},
                        { product: 'Milk Tea', num:50 },
                        { product: 'Cheese Cocoa', num:30 },
                        { product: 'Walnut Brownie', num:40 }
                    ] 
                }
            },
            methods: {
                setNum(i){
                   this.list[i].num = Math.ceil(Math.random()*100)
                },
                setNum2(p){
                   p.num = Math.ceil(Math.random()*100)
                }
            },
        }).mount("#app")
    </script>

v-for为什么一定要加key属性?

辅助属性key

 v-for为什么一定要加key属性?

  

            1、用于让vue模板语法对应的数据和标签直接产生唯一对应关系;

            2、通过唯一对应关系,可以改变vue的就近渲染原则,提该渲染效率

            <!--

                就近渲染原则:是保留页面中已存在的数据,基于新的数据进行数据替换,当元素不足时创建新的元素,元素多时删除多余元素

                             可以有效的减少元素的操作数量提高性能

                当使用key 作为唯一时:新增数据向页面进行渲染时,优先判断标签和数据是否对应,如果不是新增标签为该数据提供服务,如果是更新该标签

                                     使用key可以准确判断需要操作的元素,进一步减少元素的操作量,进一步提供程序运行性能

            -->

            <!--

                key 值取值下标和没定义key是一样的

                key 的有效取值必须是 数据对于的唯一关联值(来自于服务器后端的 数据 ID)

            -->

           

辅助标签 template

 <!-- 
        借用了HTML的 template 元素,通过功能修改实现元素包裹区定义和操作
        该标签可以充当临时父元素进行 v-for和v-if 指令调用,但指令一旦执行完成,该标签直接被移除,
        不影响页面结构
        -->
        
        <div class="list">
            <template v-for="(item, index) in list">
                <span>ID:{{ item.id }}</span>
                <span>NAME:{{ item.name }}</span>
                <br>
            </template>
        </div>
v-if v-for 的辅助渲染
辅助属性: key 描述 vue 项目构成的属性在创建删除时不被复用
辅助标签: <template> vue 页面提供 无父元素标签的统一操作 结构标

vue2 对于v-if和v-for指令同时定义于一个标签上时,优先执行v-for

      + vue2.0 语法程序可以正常运行 => v-if和v-for同时出现在一个标签上时,

          语法解析会先执行v-for,再执行v-if

vue3 对于v-if和v-for指令同时定义于一个标签上时,优先执行v-if

            + vue3.0 语法程序报错 => 直接优先执行 v-if ,最后再执行v-for

11 v-memo 性能比对指令
功能:该指令接收一个固定长度的数组作为依赖值进行记忆比对。如果数组中的每个
值都和上次渲染的时候相同,则整个包裹区的更新会被跳过。
语法: < 标签 v - memo="[ 变量 ,……]"></ 标签 > < 标签 v - memo="[ 表达式 ,……]"></ 标签 >
场景:
仅用于性能至上场景中的微小优化,应该很少需要。最常见的情况可能是有
助于渲染海量 v - for 列表 ( 长度超过 1000 的情况 )

 <!--

                v-memo="[ 判断属性|判断表达式,…… ]" 完成vue渲染的时机判断

                    当判断发现 绑定的属性或表达式和上一次渲染结果不同,对元素进行重新渲染执行

                    以此减少渲染次数,提高渲染性能

             -->

            <li v-for="(item, index) in list" :key="item.id" v-memo="[item.num]">

                {{ item.product }}:{{ item.num }}=={{ getStr(item.product) }}

                <br>

                <!-- num变化 可以触发渲染 -->

                <input type="button" value="+" @click="item.num++">

                <input type="button" value="-" @click="item.num--">

                <br>

                <!-- product 无法触发渲染 -->

                <input type="text" :value="item.product" @change=" item.product=$event.target.value ">

            </li>