vue渲染
Mustache语法 {{ }} 双大括号
1.插值表达式和文本渲染
<script setup>
let name = "java";
let emp = {
id: 101,
name: "<h1>rose</h1>",
salary: 6000,
gender: 0,
};
let fo1 = () => {
console.log("fo1函数");
return "aaa";
};
const data={
name:'百度',
url:"http://www.baidu.com",
}
</script>
<template>
<div>
<div>{{ name }}</div>
<div>{{ emp.id }}</div>
<div>{{ emp.name }}</div>
<div>{{ emp.salary + 200 }}</div>
<div>{{ emp.gender == 0 ? "男" : "女" }}</div>
<div>{{ emp.salary > 5000 }}</div>
<div>{{ emp.name.substring(2) }}</div>
<div>{{ fo1() }}</div>
<!-- v-text和v-html的区别是html里面的标签可用 -->
<div v-text="emp.name"></div>
<div v-html="emp.name"></div>
下面是对属性进行渲染因为插值表达式不能直接放在标签的属性中
v-bind可以用于渲染任何元素的属性,语法为 `v-bind:属性名='数据名'`, 可以简写为 `:属性名='数据名'`
<!-- attribute属性渲染 -->
<a
v-bind:href='data.url'
target="_self">
<img
:src="data.logo"
:title="data.name">
<br>
<input type="button"
:value="`点击访问${data.name}`">
</a>
2.事件绑定
<script setup type="module">
import {ref} from 'vue' /ref函数 vue里面有很多函数
// 响应式数据 当发生变化时,会自动更新 dom树
let count=ref(0)
let addCount= ()=>{
count.value++
}
let incrCount= (event)=>{
count.value++
// 通过事件对象阻止组件的默认行为
event.preventDefault();
}
</script>
<template>
<div>
<h1>count的值是:{{ count }}</h1>
<!-- 方法事件处理器
v-on:click="addCount()" 或简写为 @click="addCount()"-->
<button v-on:click="addCount()">addCount</button> <br>
<!-- 内联事件处理器 -->
<button @click="count++">incrCount</button> <br>
<!-- 事件修饰符 once 只绑定事件一次 -->
<button @click.once="count++">addOnce</button> <br>
<!-- 事件修饰符 prevent 阻止组件的默认行为 -->
<a href="http://www.atguigu.com" target="_blank" @click.prevent="count++">prevent</a> <br>
<!-- 原生js方式阻止组件默认行为 (推荐) -->
<a href="http://www.atguigu.com" target="_blank" @click="incrCount($event)">prevent</a> <br>
</div>
</template>
补充事件修饰符:
- .once:只触发一次事件 .prevent:阻止默认事件。例如重置输入框时候想要清提示信息,当然也可以写属性计算来实现这个重置
- .stop:阻止事件冒泡。.capture:使用事件捕获模式而不是冒泡模式。
- .self:只在事件发送者自身触发时才触发事件。
3.响应式
关键字 ref 只能包裹单一元素
函数中要操作ref处理过的数据,需要通过.value形式
关键字reactive
https://cn.vuejs.org/api/reactivity-core.html#reactive
reactive() 函数创建一个响应式对象或数组
关键字toRefs 和 toRef
<script type="module" setup>
/* 从vue中引入reactive方法 */
import {ref,reactive,toRef,toRefs} from 'vue'
let data = reactive({
counter:0,
name:"test"
})
// 将一个reactive响应式对象中的某个属性转换成一个ref响应式对象
let ct =toRef(data,'counter');
// 将一个reactive响应式对象中的多个属性转换成多个ref响应式对象
let {counter,name} = toRefs(data)
function show(){
alert(data.counter);
// 获取ref的响应对象,需要通过.value属性
alert(counter.value);
alert(name.value)
}
/* 函数中要操作ref处理过的数据,需要通过.value形式 */
let decr = () =>{
data.counter--;
}
let incr = () =>{
/* ref响应式数据,要通过.value属性访问 */
counter.value++;
}
</script>
<template>
<div>
<button @click="data.counter--">-</button>
<button @click="decr()">-</button>
{{ data.counter }}
&
{{ ct }}
<button @click="data.counter++">+</button>
<button @click="incr()">+</button>
<hr>
<button @click="show()">显示counter值</button>
</div>
</template>
4.v-if v-else v-show v-for
<script setup>
import{ref} from 'vue'
let awesome =ref(true)
</script>
<template>
<div>
<h1 v-show="awesome">Vue is awesome!</h1>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh,no</h1>
<button @click="awesome=!awesome">Togg</button>
</div>
</template>
<script setup>
let arrs=['java','html','js','vue','vite']
let computers=[
{id:1,brand:'heying',price:3000,size:15},
{id:2,brand:'moying',price:5200,size:16},
]
</script>
<template>
<div>
<ul>
<li v-for="item,index in arrs" :key="index">
{{ index }}:{{ item }}
</li>
</ul>
<table>
<tr>
<th>编号</th>
<th>品牌</th>
<th>单价</th>
<th>尺寸</th>
</tr>
<tr v-for="computers,index in computers" :key="index">
<td>{{ computers.id }}</td>
<td>{{ computers.brand }}</td>
<td>{{ computers.price }}</td>
<td>{{ computers.size }}</td>
</tr>
</table>
</div>
</template>
vue事件双向绑定
v-model专门用于双向绑定表单标签的value属性,
语法为 model:value=‘’,可以简写为 v-model=‘’
也可以支持 textarea 和select
<script setup>
import { ref,reactive } from 'vue';
let user=reactive({username:null,password:null,name:null,})
// 注册意思是向后端发送数据
function regist(){
alert(user.username.value);
alert(JSON.stringify(user));}
function clearx(){
user.username=''
user.password=''
user.name=''
}
</script>
<template>
<div>
账号: <input type="text" placeholder="请输入账号!" v-model="user.username"> <br>
密码: <input type="password" placeholder="请输入账号!" v-model="user.password"> <br>
重复密码: <input type="password" placeholder="请输入账号!" v-model="user.password"> <br>
姓名:<input type="text" placeholder="请输入姓名!" v-model="user.name"> <br>
简介:<textarea v-model="user.introduce"></textarea><br>
<button @click="regist()">注册</button>
<button @click="clearx()">重置</button>
{{ console.log(hbs) }}
{{ console.log(user) }}
</div>
</template>
4.属性计算
属性可以用来描述依赖响应式状态的复杂逻辑 简化代码
<script type="module" setup>
//引入模块函数
import { reactive,computed} from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// 一个计算属性 ref 定义的计算属性 ref自动解包无需添加.value
const publishedBooksMessage = computed(() => {
console.log("publishedBooksMessage")
return author.books.length > 0 ? 'Yes' : 'No'
})
// 一个函数
let hasBooks = ()=>{
console.log("hasBooks")
return author.books.length > 0?'Yes':'no'
}
</script>
<template>
<div>
<p>{{author.name}} Has published books?:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
<span>{{ hasBooks() }}</span><!-- 调用方法,每个标签都会调用一次 -->
<span>{{ hasBooks() }}</span>
<p>{{author.name}} Has published books?:</p>
<span>{{ publishedBooksMessage }}</span><!-- 属性计算,属性值不变时,多个个标签只会调用一次 -->
<span>{{ publishedBooksMessage }}</span>
</div>
</template>
<style scoped>
</style>
若我们将同样的函数定义为一个方法而不是计算属性,两种方式在结果上确实是完全相同的,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books
不改变,无论多少次访问 publishedBooksMessage
都会立即返回先前的计算结果,相当于绑定上面了,比较快
5.数据监听
关键字 watch
watch一般监听ref 如果是reactive会监听他的所有属性(太深了)不过也可以监听指定数据, 深度监听一般用deep:true
深度监视immediate:true 在进入页面时立即执行一次
关键字 watchEffect
默认监听所有的响应式数据 ,直接在内部使用监听属性即可!不用外部声明
也不需要,即时回调设置!默认初始化就加载!
watch
和 watchEffect
都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch
只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch
会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。watchEffect
,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。