Vue3-模板语法

113 阅读3分钟

1.模板语法

1-1 我的第一个vue应用

<div id="box">
    {{10+20}}
    {{name}}
</div>
<script>
    var app=Vue.createApp({
        data(){
            return {
                name:"xiaoming"
            }
        }
    }).mount('#box')
</script>

1-2应用背后的真相

(1)Object.defineProperty

var obj = {}
var oBox = document.getElementById("box")
Object.defineProperty(obj,"myname",{
    get(){
        console.log("有人访问了")
        return obox.innerHTML
    },
    set(value){
        console.log("有人改变我了",value)
        oBox.innerHTML = value
    }
})
/* 缺陷:无法监听数组的改变,无法监听class改变,无法监听Map Set结构 */

Object.defineProperty(对象,属性名称,options)可以定义一个对象不会被修改也不能被遍历

通过Object.defineProperty定义的属性默认是:无法被修改,无法被遍历,无法被删除

Object.defineProperty提供了get和set方法

注意: 1. get和set不能和value和writable一起使用 2. 当给对象设置属性的值,会触发set
详见js笔记js高级(1)

(2)

var obj = {}
var obox = document.getElementById("box")

var vm = new Proxy(obj, {
    get(target, key) {
        console.log("get")
        return target[key]
    },
    set(target, key, value) {
        console.log("set")

        target[key] = value
        obox.innerHTML = value
    }
})

/*
    vue3 基于Proxy ,ES6 Proxy ,
      if(支持proxy){
          // proxy进行拦截处理, 实现功能
      }else{
          // object.defineProtery
      }

    */

1-3 模板语法

(1)最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号): <span>Message: {{ msg }}</span>

(2)双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令

(3)表达式的支持

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

(4)指令

<a v-on:click="doSomething"> ... </a>

<!-- 简写 -->
<a @click="doSomething"> ... </a>

v-bind的基本使用

v-bind的基本使用

todolist案例
<body>
    <div id="box">
        <input type="text" v-model="mytext" />
        <button @click="handleclick()">发送</button>
        <ul v-for="(item,index) in list">
            <li>{{item}}--<button @click="del(index)">删除</button></li>
        </ul>
    </div>
    
    <script>
        var app=Vue.createApp({
            data(){
                return {
                    mytext:"",
                    list:[]
                }
            },
            methods:{
                handleclick(){
                    this.list.push(this.mytext)
                },
                del(index){
                    this.list.splice(index,1)
                }
            }
        }).mount('#box')
    </script>
</body>
点击变色案例
<body>
    <div id="box">
        <ul>
            <li v-for="data,index in datalist" @click="handleclick(index)" :class="current===index?'active':''">
                {{data}}
            </li>
        </ul>
    </div>
    <script>
        var obj = {
            data() {
                return {
                    datalist:["11","22","33"],
                    current:0
                }
            },
            methods: {
                handleclick(index){
                    this.current = index
                }
            }
        }
        var app = Vue.createApp(obj).mount("#box")
    </script>
</body
v-html 模板的陷阱

双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

注意: 在网站上动态渲染任意HTML是非常危险的,因为这非常容易造成XSS漏洞(伪站点攻击),仅在内容安全可信时再使用v-html,并且永远不要使用用户提供的HTML内容

2.class和style

2-1 class的绑定

对象写法

<body>
    <div id='box'>
        <div :class="objClass">动态切换class---对象</div>
        <div :class="arrClass">动态切换class---数组</div>
    </div>
</body>
<script>
var app=Vue.createApp({
    data(){
        return {
            objClass:{
                aaa:true,
                bbb:false,
                ccc:true
            },
            arrClass:['aaa','bbb'] //vue 不支持后来添加新属性   vue3支持    
        }
    }
}).mount("#box")
</script>    

2-2 style的绑定

对象写法

<body>
    <div id="box">
       
        <div :style="styleArr"></div>

        <!-- <div :style="imgObj"></div> -->
        <button @click="handleAjax()">click</button>
    </div>
    <script>
        var obj = {
            data() {
                return {
                    styleObj1: {
                        background: "red"
                    },
                    styleObj2: {
                        color: "yellow"
                    },

                    styleArr: [{
                        width: "200px",
                        height: "200px",
                        backgroundSize: "cover"
                    }]
                }
            },
            methods: {
                handleAjax() {
                    this.styleArr.push(
                        {
                            backgroundImage:"url(https://static.maizuo.com/pc/v5/usr/movie/862ab6736237acd11599e5eecbbc83d7.jpg?x-oss-process=image/quality,Q_70)"
                        }
                    )
                }
            }
        }
        var app = Vue.createApp(obj).mount("#box")
    </script>
</body> 

3.条件渲染

v-if是"真实的"按条件渲染,因为它确保了在切换时,条件区块内的事件监听和子组件都会被销毁与重建

v-if也是惰性的:如果在初次渲染时条件值为false,不会做任何事情,条件区块只有当条件首次变为true时才被渲染

v-show元素无论初始条件如何,始终会被渲染,只有CSS的display属性会被切换

因此v-if有更高的切换开销,v-show有更高的初始渲染开销,在不考虑数据的安全需要频繁切换的,使用v-show较好,如果在运行时绑定条件很少改变,v-if更合适

<body>
    <div id="box">
      <ul>
        <li v-for="({title,state},index) of datalist">
            {{title}}---{{index}}
            <span v-if="state===0">
                交易完成
            </span>
            <span v-else-if="state===1">
                已付款
            </span>
            <span v-else>
                已发货
            </span>
        </li>
      </ul>
    </div>
    <script>
        // v-if v-else-if v-else
        /*
        
            1. 支持解构
            2. (item,index) in datalist
            3. in===of 
        */

        var obj = {
            data() {
                return {
                    datalist:[
                        {
                            title:"手机",
                            state:0
                        },
                        {
                            title:"衣服",
                            state:1
                        },
                        {
                            title:"裤子",
                            state:2
                        },
                       
                    ]
                }
            }
        }
        var app = Vue.createApp(obj).mount("#box")
    </script>
</body>