Vue3【组合式API、setup、响应式原理、ref对象解包、模板的语法、v-bind】


组合式API

  • 在组合式api中直接声明的变量,就是一个普通的变量,不是响应式属性
  • 修改这些属性时,不会在视图中产生效果
  • 可以通过 reactive()来创建一个响应式的对象
  • 在setup()中可以通过返回值来指定那些内容要暴露给外部
  • 暴露后的内容,可以在模板中直接使用
<script>
import { reactive } from "vue"

export default {
    setup() {
        // 定义变量
        // 在组合式api中直接声明的变量,就是一个普通的变量,不是响应式属性
        //      修改这些属性时,不会在视图中产生效果
        let msg = "今天天气真不错!"
        let count = 0

        //可以通过 reactive()来创建一个响应式的对象
        const stu = reactive({
            name: "孙悟空",
            age: 18,
            gender: "男"
        })

        function changeAge(){
            stu.age = 44
        }

        // 在setup()中可以通过返回值来指定那些内容要暴露给外部
        // 暴露后的内容,可以在模板中直接使用
        return {
            msg,
            count,
            stu,
            changeAge
        }
    }
}
</script>
<template>
    <h1>演示组合式API</h1>
    <h2>{{ msg }}</h2>
    <h3>{{ count }}</h3>
    <button @click="changeAge">点我一下</button>
    <h2>{{ stu.name }} -- {{ stu.age }} -- {{ stu.gender }}</h2>
</template>

setup

  • script标签中加上setup,就说明要使用组合式API
<script setup>
//默认暴露了
import { reactive } from "vue"

const msg = "我爱Vue"
const count = 0
const stu = reactive({
    name: "孙悟空"
})

function fn() {
    alert("哈哈哈,好快乐!")
}
</script>
<template>
    <h1 @click="fn">组合式的API</h1>
    <h2>{{ msg }} -- {{ count }}</h2>
    <h3>{{ stu.name }}</h3>
</template>

响应式原理

reactive()

  • 返回一个对象的响应式代理
  • 返回的是一个深层响应式对象
  • 也可以使用shallowReactive()创建一个浅层响应式对象
  • 缺点:
    • 只能返回对象的响应式代理!不能处理原始值

ref()

  • 接收一个任意值,并返回它的响应式代理
  • ref在生成响应式代理时,它是将值包装为了一个对象 0 --> {value:0}
  • 访问ref对象时,必须通过 对象.value 来访问其中的值
  • 在模板template中,ref对象会被自动解包,不用通过.value来访问
  • vue给我们提供了一个语法糖,使得ref对象在script标签中也可以自动解包
  • $是一个实验性的,需要在vite插件(vite.config.js)中做一些配置 reactivityTransform:true.即在这里修改
plugins: [vue({
	eactivityTransform:true
})],

<script setup>
import { reactive, ref } from "vue"
import { $ref } from "vue/macros"
/* 
    reactive()
        - 返回一个对象的响应式代理
        - 返回的是一个深层响应式对象
        - 也可以使用shallowReactive()创建一个浅层响应式对象
        - 缺点:
            - 只能返回对象的响应式代理!不能处理原始值

    ref()
        - 接收一个任意值,并返回它的响应式代理

*/
const stu = reactive({
    name: "孙悟空"
})

// ref在生成响应式代理时,它是将值包装为了一个对象 0  --> {value:0}
// 访问ref对象时,必须通过 对象.value 来访问其中的值
// 在模板template中,ref对象会被自动解包,不用通过.value来访问
let count = $ref(0) // 生成一个0的响应式代理

// count = 10 // 改变量只会影响到变量自己,在js中,无法实现对一个变量的代理
console.log(count)

// vue给我们提供了一个语法糖,使得ref对象在script标签中也可以自动解包
// $是一个实验性的,需要在vite插件(vite.config.js)中做一些配置 reactivityTransform:true
// 即在这里修改  plugins: [vue({
//     reactivityTransform:true
//   })],
function fn() {
    // count自增
    count++
}
</script>
<template>
    <h1>组合式的API</h1>
    <h2 @click="fn">{{ count }}</h2>
</template>

ref对象解包

<script setup>
import { ref, reactive, computed } from "vue"

const msg = ref("Hello Vue")

// {value: obj}
// obj.value.name
// 一般用这种方式,而不是下面的obj2
const obj = ref({
    name: "孙悟空",
    age: 18
})

// obj2.name.value
const obj2 = {//此时obj2对象不是响应式的
    name: ref("孙悟空"), // {value:"孙悟空"}
    age: ref(18) // // {value:18}
}

const { name, age } = obj2 //对obj2对象解构,此时就是顶层对象了,直接在模板解析name即可,不用加value

const changeMsgHandler = () => {
    // 修改ref对象时,必须通过value。语法糖暂未正式用,但也可以用
    // msg.value = "哈哈"
    name.value = "你看我变不变"
}

// computed 用来生成计算属性
const newMsg = computed(() => {
    return msg.value + "-我爱Vue!"
})
</script>

<template>
    <!-- ref对象在模板中可以自动解包(要求ref对象必须是顶层对象) -->
    <h1>{{ msg }}</h1>
    <h1>{{ newMsg }}</h1>
    <h2>{{ obj.name }}</h2>
    <!-- name不是顶层响应式对象,所以不能自动解包 -->
    <!-- <h2>{{ obj2.name.value }}</h2> -->
    <h2>{{ name }}</h2>
    <hr />
    <h2>{{ obj.age + 1 }}</h2>
    <!-- <h2>{{ obj2.age.value + 1 }}</h2> -->
    <h2>{{ age + 1 }}</h2>
    <button @click="changeMsgHandler">点我一下</button>
</template>

模板的语法

  • 在模板中,可以直接访问到组件中声明的变量

    • 除了组件中的变量外,vue也为我们提供了一些全局对象可以访问:
      比如:Date、Math、RegExp …
      除此之外,也可以通过app对象来向vue中添加一些全局变量
      在main.js中添加app.config.globalProperties
    • 使用插值(双大括号),只能使用表达式
      表达式,就是有返回值的语句
    • 插值实际上就是在修改元素的textContent,
      如果内容中含有标签,标签会被转义显示,不会作为标签生效

    指令:

    • 指令模板中为标签设置的一些特殊属性,它可以用来设置标签如何显示内容
    • 指令使用v-开头
      v-text 将表达式的值作为元素的textContent插入,作用同{{}}
      使用指令时,不需要通过{{}}来指定表达式
      v-html 将表达式的值作为元素的innerHTML插入,有xss攻击的风险
<script setup>
const msg = "我爱vue"
const html = `<h2>我是一段html代码</h2>`

const fn = () => {
    console.log("哈哈哈")
}
</script>

<template>
    <!-- 
    - 在模板中,可以直接访问到组件中声明的变量
    - 除了组件中的变量外,vue也为我们提供了一些全局对象可以访问:
        比如:Date、Math、RegExp ...
        除此之外,也可以通过app对象来向vue中添加一些全局变量
        在main.js中添加app.config.globalProperties
    - 使用插值(双大括号),只能使用表达式
        表达式,就是有返回值的语句
    - 插值实际上就是在修改元素的textContent,
        如果内容中含有标签,标签会被转义显示,不会作为标签生效

    指令:
      - 指令模板中为标签设置的一些特殊属性,它可以用来设置标签如何显示内容
      - 指令使用v-开头
        v-text 将表达式的值作为元素的textContent插入,作用同{{}}
          使用指令时,不需要通过{{}}来指定表达式
        v-html 将表达式的值作为元素的innerHTML插入,有xss攻击的风险


  -->
    <h1>{{ "hello" + "world" }}</h1>
    <!-- <h2>{{ if(1+1==2){console.log(123)} }}</h2> -->
    <div>{{ html }}</div>
    <div v-text="html"></div>
    <div v-html="html"></div>
</template>

v-bind

  • 当我们需要为标签动态的设置属性时,需要使用v-bind指令,
    • v-bind可以简写为 :
  • 当我们为一个布尔值设置属性时,
    • 如果值为true,则元素上有该属性(转换后为true,也算true)
    • 如果值为false,则元素没有该属性(转换后为false,也算false)
    • 特殊情况:“” 空串,在这里会被当成真值

动态参数
同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:

<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 简写 -->
<a :[attributeName]="url"> ... </a>

这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName,其值为 "href",那么这个绑定就等价于 v-bind:href

<script setup>
import { ref } from "vue"
const imgPath = ref("/images/messi.png")
const changeImg = () => {
    imgPath.value = "/images/neymar.png"
}
const attrs = {
    id: "box1",
    class: "hello"
}

const attrName = "title"
const attrValue = "这是一个title属性"

const isDisabled = ""
</script>

<template>
    <!-- 
      当我们需要为标签动态的设置属性时,需要使用v-bind指令,
        v-bind可以简写为 :
      当我们为一个布尔值设置属性时,
        如果值为true,则元素上有该属性(转换后为true,也算true)
        如果值为false,则元素没有该属性(转换后为false,也算false)
        特殊情况:"" 空串,在这里会被当成真值


  -->
    <!-- <button @click="changeImg">切换图片</button> -->
    <img :[attrName]="attrValue" :src="imgPath" alt="梅西" />
    <div :="attrs"></div>  <!--等价于 <div id="box1" class="hello"></div> -->

    <input type="text" :disabled="isDisabled" />
</template>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值