Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。
使用vite创建一个vue+JavaScript项目
npm create vite
npm install
npm run dev
1. 插值表达式
插值表达式:最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 ,即双大括号`{{}}`
<script setup>
//定义变量
let msg = 'hello world'
//定义函数
let fun = () => {
return 'hello china'
}
//定义对象
let compurse = [{name:'纽纳', number:3, price:9}, {name:'牛', number:8, price:60}]
function add() {
let count = 0;
for(let index in compurse) {
count += compurse[index].price * compurse[index].number
}
return count
}
</script>
<template>
<div>
<!--插值表达式 {{ }}-->
{{ msg }}
<h1>{{ msg }}</h1>
{{ fun() }} <hr>
{{ add() }} <hr>
{{ compurse }}
</div>
</template>
<style scoped>
2. 文本渲染命令
/**
* v-text:不识别html结构的文本 类似于innerText
* v-html:识别html结构的文本 innerHtml
* 插值表达式{{}}
* v-*** vue命令(该命令必须在标签中使用才生效)
*/
<script setup>
let msg = "hello wrold"
//命令支持模板字符串
let msg2 = `hello ${"china"}`
//命令支持常见运算符
let age = 19
//命令支持常见对象的API调用
let bee = '蜜,蜂'
//命令支持函数调用
function hello() {
return 'hello'
}
//命令中支持
let msg3 = '<h1>哈哈</h1>'
</script>
<template>
<div>
<h1 v-text="msg"></h1>
<h1 v-text="msg2"></h1>
<h1 v-text="`hello ${'china'}`"></h1>
<h1 v-text="age > 18 ? '成年' : '未成年'"></h1>
<h1 v-text="bee.split(',')[0]"></h1>
<h1 v-text="hello()"></h1>
<h1 v-html="msg3"></h1>
</div>
</template>
<style scoped>
</style>
3. 属性渲染命令
/***
* 属性渲染命令:v-bind:属性名=
*/
<script setup>
let dregon = {
picture: 'demo1-html\img\屏幕截图 2024-03-23 162925.png',
name: '奶龙',
href:'https://blog.csdn.net/2301_79526467?type=blog'
}
</script>
<template>
<a v-bind:href="dregon.href">
<img v-bind:src="dregon.picture" v-bind:title="dregon.name">
</a>
</template>
<style scoped>
</style>
4. 事件渲染命令
/***
* 事件渲染命令语法:
* v-on:事件名=函数名()
* @事件名=函数名()
* 原生js中绑定事件:onclick ondbclick ...
* vue事件命令事件名去掉on即可 此时click dbclick
*/
<script setup>
import {ref} from 'vue'
let count = ref(10)
function add() {
count.value++
}
function desc() {
count.value--;
}
function p(event) {
let flag = confirm("确认要跳转页面吗?")
console.log(flag)
if (!flag) {
//原生js方式阻止提交
event.preventDefault()
}
}
</script>
<template>
<div>
<!--vue事件渲染命令-->
<button v-on:click="add()">+</button>
{{ count }}
<button @click="desc()">-</button>
<!--函数内联(即要执行的函数体直接放入此处)-->
<button v-on:click="count--">hello</button>
<!--事件修饰符once prevent
once:只生效一次
prevent:直接阻止提交
-->
<a href="https://blog.csdn.net/2301_79526467?type=blog" v-on:click="p($event)">奶龙鸭</a>
</div>
</template>
<style scoped>
</style>
5. 响应式数据
/***
* 响应式数据处理方式
* 1.ref函数:多用于响应单个数据
* 在script标签中改变值需通过.value的形式
* 在template标签中改变值不需要通过.value形式
* 2.reactive函数:多用于响应对象
* 在script、template中处理响应式数据直接通过 对象名.属性名处理即可
*/
<script setup>
import { ref, reactive } from 'vue'
let num = ref(10);
function add() {
num.value++
}
let people = reactive(
{
name: 'zhangsan',
age: 19
}
)
</script>
<template>
<div>
<button @click="add()">+</button>
{{ num }} <hr>
<button @click="people.age++">age</button>
{{ people }}
</div>
</template>
<style scoped>
</style>
6. 条件渲染命令
/**
* 条件渲染命令:
* v-if:条件未true则执行该命令
* v-else:不满足if则执行该else命令
*
* v-show:为true则展示
*
* v-if和v-show区别:
* v-if只有条件为true时才会进行渲染
* v-show不论初始化条件是否为true都会进行渲染保留在dom树中,只是通过display进行控制
*/
<script setup>
import {ref} from 'vue'
let flag = ref(true)
</script>
<template>
<diV>
<h1 id="a" v-if="flag">if执行啦</h1>
<h1 id="b" v-else>else执行啦</h1>
<h1 id="c" v-show="flag">show展示</h1>
<button @click="flag = !flag">展示</button>
</diV>
</template>
<style scoped>
</style>
7. 列表渲染命令
/**
* 列表渲染:
* v-for命令
* 语法规则:
* v-for="变量名 in 数组名" 类似于Java中的forEach语句 for(变量名 : 数组名)
* 该命令尽量加上key属性
* 如:v-for="item, index in items" v-bind:key="item.id"
* 第一个参数表示迭代到的当前数据的变量名,第二个参数表示当前数据的数组下标
*/
<script setup>
import {reactive} from 'vue'
//商品列表
let items = reactive([
{
id: 'item1',
name: '牛奶',
price: 3.5,
num: 12
},
{
id: 'item2',
name: '薯片',
price: 6,
num: 18
},
{
id: 'item3',
name: '炸鸡',
price: 19,
num: 3
}
])
//删除单个商品函数
function removeItem(index) {
//调用数组的api删除,index表示从哪开始,1代表要删除数组内多少个数据
items.splice(index, 1)
}
//计算商品总金额函数
function count() {
let tem = 0;
for(let index in items) {
tem += items[index].price * items[index].num
}
return tem
}
//清空购物车
function removeAll() {
items.splice(0, items.length)
}
</script>
<template>
<div>
<h1>皇家购物车</h1>
<table border="black">
<thead>
<td>序号</td>
<td>商品</td>
<td>价格</td>
<td>数量</td>
<td>小计</td>
<td>操作</td>
</thead>
<tbody v-for="item, index in items" v-bind:key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.name }}</td>
<td>{{ item.price }}</td>
<td>{{ item.num }}</td>
<td>{{ item.price * item.num }}</td>
<button @click="removeItem(index)">删除</button>
</tbody>
<td colspan="5">
商品总金额:{{ count() }}
</td>
<button @click="removeAll()">清空</button>
</table>
<hr>
<ul>
<li v-for="item, index in items" v-bind:key="item.id">
{{ index + 1 }}
{{ item.name }}
</li>
</ul>
</div>
</template>
<style scoped>
</style>
8. 双向绑定
/**
* 单向绑定
* 如:v-bind:value="变量名"
单向绑定也可以 :value='变量名'
* 双向绑定
* v-model="变量名"
*/
<script setup>
import {reactive} from 'vue'
let people = reactive(
{
name: '',
password: '',
sex: '',
hobby: [],
introduce: ''
}
)
function remove() {
people.name = ''
people.password = ''
people.sex = ''
people.hobby.splice(0, people.hobby.length)
people.introduce = ''
}
</script>
<template>
<div>
账号<input type="text" v-model="people.name"> <br>
密码<input type="password" v-model="people.password"> <br>
性别:
男<input type="radio" value="boy" name="sex" v-model="people.sex">
女<input type="radio" value="gril" name="sex" v-model="people.sex">
<br>
爱好:
唱<input type="checkbox" value="sing" name="hobby" v-model="people.hobby">
跳<input type="checkbox" value="dance" name="hobby" v-model="people.hobby">
rap<input type="checkbox" value="rap" name="hobby" v-model="people.hobby">
<br>
个人简介:
<textarea v-model="people.introduce"></textarea> <br>
<button @click="remove()">清空</button>
<hr>
{{ people }}
</div>
</template>
<style scoped>
</style>
9. 计算属性
/**
* 计算属性:
* computer函数
*/
<script setup>
import {reactive, computed} from 'vue'
let people = reactive({
name: "张三",
book: ["java", "mysql", "c++"]
})
function f() {
return people.book.length > 0 ? "yes" : "no"
}
//数据未发生变化则不会重新计算区别于直接调用方法,方法每执行一次就会计算一次
let flag = computed(() => {return people.book.length > 0 ? "yes" : "no"})
</script>
<template>
<div>
<p>作者:{{ people.name }}</p>
是否出版图书:{{ flag }} <br>
是否出版图书:{{ f() }}
</div>
</template>
<style scoped>
</style>
10. 数据监听器
/**
* 数据监听器:watch、watchEffect函数
*/
<script setup>
import {reactive, watchEffect} from 'vue'
let people = reactive({
username: "",
userpassword: ""
})
//要监听哪个事件直接监听即可
watchEffect(() => {
console.log(people.username)
}
)
</script>
<template>
<div>
账号:<input type="text" v-model="people.username"> <br>
密码:<input type="password" v-model="people.userpassword"> <br>
{{ people }}
</div>
</template>
<style scoped>
</style>
11. 导入其他组件
<script setup>
import Header from './components/Header.vue';
import Navigator from './components/Navigator.vue';
import Control from './components/Control.vue';
</script>
12. 组件传递参数
<script setup>
import Header from './components/Header.vue';
import Navigator from './components/Navigator.vue';
import Control from './components/Control.vue';
import {ref} from 'vue'
//定义一个变量接收子组件传递的信息
let message = ref('')
//定义函数处理子组件传递的数据
function receive(data) {
message.value = data
}
</script>
<template>
<div>
{{ message }}
<hr>
<Header class="header"></Header>
<!--绑定的事件名必须和子组件中定义和传递的事件名保持一致-->
<Navigator @sendMenu="receive" class="navigator"></Navigator>
<!--父组件传递数据给子组件可直接在此处定义属性名和传递的数据-->
<control class="control" :delieve="message"></control>
</div>
</template>
<style scoped>
.header {
border: 2px solid red;
}
.navigator {
border: 2px solid green;
width: 15%;
height: 300px;
float: left;
}
.control {
border: 2px solid blue;
width: 83%;
height: 300px;
float: right;
}
</style>
子传父
<script setup>
/**
* 子组件传递数据给父组件
* 用函数defineEmits
*/
import {defineEmits, ref} from 'vue'
//通过defineEmits函数获取传递参数的对象
const emit = defineEmits(['sendMenu'])
//定义要传递给父组件的数据
let data = ref('')
function send(data) {
//参数一:组件定义的事件名,接收数据的组件可通过该事件名进行绑定操作
//参数二:当前组件传递的数据
emit('sendMenu', data)
}
</script>
<template>
<div>
<ul>
<!--send函数的参数即组件要传递的内容-->
<li @click="send('探花管理')">探花管理</li>
<li @click="send('学员管理')">学员管理</li>
<li @click="send('教员管理')">教员管理</li>
<li @click="send('系统管理')">系统管理</li>
<li @click="send('请假管理')">请假管理</li>
</ul>
</div>
</template>
<style scoped>
</style>
父传子
<script setup>
/**
* 父组件传递数据给子组件
* 用函数defineProps
*/
import {defineProps} from 'vue'
defineProps({
//子组件接收父组件传递信息时属性名必须和定义的保持一致:后面的数据类型和传递的数据类型必须保持一致
delieve:String
})
</script>
<template>
<div>
<!--直接使用父组件传递的数据-->
{{delieve}}
</div>
</template>
<style scoped>
</style>