目录
Vue.js - 渐进式 JavaScript 框架
"渐进式"是指可以按需引入Vue.js的部分功能, 而不必全量引入整个框架
1.创建一个应用程序
/*
head处加 <script src="vue.global.js"></script>
<div id="app"></div> 指定一个 id 为 app 的 div 元素
{{ }} 插值表达式, 可以将 Vue 实例中定义的数据在视图中进行渲染
如: Vue 实例中定义一个 msg 变量, 值为 "Hello world", 在模板中若使用插值表达式 {{ msg }} 则会被渲染成 "Hello world"
响应式数据是指当数据发生变化时, 模板中依赖于该数据的部分会自动更新
*/
<script>
//创建一个 Vue 应用程序
Vue.createApp({
//Composition API(组合式 API) 的 setup选项 用于设置响应式数据和方法等
setup() {
//Composition API 的 reactive()函数 用于创建响应式数据
const web = Vue.reactive({ //Vue.reactive 创建一个响应式数据对象 web, 其中包含
title 和 url 属性
title: "编程",
url: "code.com"
})
//返回数据
return {
msg: "success",
web
}
}
}).mount("#app") //将 Vue 应用程序挂载(mount) 到 app 元素上
</script>
//将 Vue 对象中的 createApp、reactive 属性赋值给 createApp、reactive 变量
const { createApp, reactive } = Vue //解构赋值语法
2.模块化开发
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const web = reactive({
title: "编程",
url: "code.com"
})
return {
msg:"success",
web
}
}
}).mount("#app")
</script>
3.ref与reactive
<script type="module">
import { createApp, ref, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const number = ref(10) //ref用于存储单个基本类型的数据, 如:数字、字符串等
number.value = 20 //使用ref创建的响应式对象, 需要通过.value属性来访问和修改其值
const web = reactive({ //用于存储复杂数据类型, 如:对象或数组等
title: "编程",
url: "code.com"
})
web.url = "www.dengruicode.com" //使用reactive创建的响应式对象, 可以直接通过属性名来访问和修改值
return {
msg: "success",
number,
web
}
}
}).mount("#app")
</script>
4.绑定事件v-on (简写@)
html
<div id="app">
<h3>{{ msg }}</h3>
<h3>{{ web.url }}</h3>
<h3>{{ web.user }}</h3>
<h3>{{ sub(100, 20) }}</h3>
<!-- v-on:click 表示在 button 元素上监听 click 事件 -->
<button v-on:click="edit">修改</button> <br>
<!-- @click 简写形式 -->
<button @click="add(20, 30)">加法</button> <br>
<!--
enter space tab 按键修饰符
keyup是在用户松开按键时才触发
keydown是在用户按下按键时立即触发
-->
回车 <input type="text" @keyup.enter="add(40, 60)"> <br>
空格 <input type="text" @keyup.space="add(20, 30)"> <br>
Tab <input type="text" @keydown.tab="add(10, 20)"> <br>
w <input type="text" @keyup.w="add(5, 10)"> <br>
<!-- 组合快捷键 -->
Ctrl + Enter <input type="text" @keyup.ctrl.enter="add(40, 60)"> <br>
Ctrl + A <input type="text" @keyup.ctrl.a="add(20, 30)">
</div>
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const edit = () => {
web.url = "www.dengruicode.com"
//msg = "编程" //错误示例 不能直接改变msg的值,因为msg是一个普通变量, 不是响应式数据
}
const add = (a, b) => {
web.user += a + b
}
const sub = (a, b) => {
return a - b
}
return {
edit, //方法
add,
sub,
}
}
}).mount("#app")
</script>
5.v-show 显示与隐藏
<!-- html中 -->
<p v-show="web.show">编程 code.com</p>
//js中
const web = reactive({
show: true
})
const toggle = () => {
web.show = !web.show
}
6. 条件渲染v-if v-else-if v-else
v-if的用法与v-show相似,但不适合频繁使用,频繁从dom中添加删除元素,导致性能下降
<p v-if="web.user < 1000">新网站</p>
<p v-else-if="web.user >= 1000 && web.user < 10000">优秀网站</p>
<p v-else-if="web.user >= 10000 && web.user < 100000">资深网站</p>
<p v-else>超级网站</p>
7.动态属性绑定 v-bind (简写: )
<!-- :value -->
<h3>value="dengruicode.com"</h3>
<input type="text" value="dengruicode.com">
<h3>v-bind:value="web.url"</h3>
<input type="text" v-bind:value="web.url">
<h3>简写 :value="web.url"</h3>
<input type="text" :value="web.url">
<!-- :class -->
<h3>class="textColor"</h3>
<b class="textColor">邓瑞编程</b>
<h3>:class="{textColor:web.fontStatus}"</h3>
<b :class="{textColor:web.fontStatus}">dengruicode.com</b>
const web = reactive({
url: "www.code.com",
img: "windows.jpg",
fontStatus: true
})
8.遍历数组或对象
const data = reactive({
number: ["十", "十一", "十二"], //数组
user: { //对象
name: "Luna",
gender: "女"
},
teacher: [ //包含两个对象的数组
{ id: 100, name: "邓瑞", web: "dengruicode.com" },
{ id: 101, name: "David", web: "www.dengruicode.com" }
]
})
<ul>
<li v-for="(value, index) in data.number">
index=> {{ index }} : value=> {{ value }}
</li>
</ul>
<ul>
<li v-for="value in data.user">
value=> {{ value }}
</li>
</ul>
<ul>
<li v-for="(value, key) in data.user">
key=> {{ key }} : value=> {{ value }}
</li>
</ul>
<ul>
<li v-for="(value, key, index) in data.user">
index=> {{ index }} : key=> {{ key }} : value=> {{ value }}
</li>
</ul>
<ul>
<!-- <template> 标签可以用来包装多个元素或者多行代码, 不会在页面中渲染 -->
<template v-for="(value, key, index) in data.user">
<li v-if="index == 1">
index=> {{ index }} : key=> {{ key }} : value=> {{ value }}
</li>
</template>
</ul>
<ul>
<!-- :key="value.id" 为 每个 li 元素设置一个唯一的 key 值 -->
<li v-for="(value, index) in data.teacher" :title="value.name" :key="value.id">
index=> {{ index }} : value.id=>{{ value.id }} value.name=>{{ value.name }} value.web=>{{ value.web }}
</li>
</ul>
9.双向数据绑定 v-model
<div id="app">
<h3>文本框 {{ data.text }}</h3>
<h3>单选框 {{ data.radio }}</h3>
<h3>复选框 {{ data.checkbox }}</h3>
<h3>记住密码 {{ data.remember }}</h3>
<h3>下拉框 {{ data.select }}</h3>
<!-- 单向数据绑定 当数据发生改变时, 视图会自动更新. 但用户手动更改 input 的值, 数据不会自动更新 -->
单向数据绑定 <input type="text" :value="data.text">
<hr>
<!--
双向数据绑定 当数据发生改变时, 视图会自动更新. 当用户手动更改 input 的值, 数据也会自动更新
对于 <input type="text">, v-model 绑定的是 input 元素的 value 属性
-->
双向数据绑定 <input type="text" v-model="data.text">
<hr>
<!--
单选框
对于 <input type="radio">, v-model 绑定的是 input 元素的选中状态
-->
<input type="radio" v-model="data.radio" value="1">写作
<input type="radio" v-model="data.radio" value="2">画画
<hr>
<!--
复选框
对于 <input type="checkbox">, v-model 绑定的是 input 元素的选中状态
-->
<input type="checkbox" v-model="data.checkbox" value="a">写作
<input type="checkbox" v-model="data.checkbox" value="b">画画
<input type="checkbox" v-model="data.checkbox" value="c">运动
<hr>
<!-- 记住密码 -->
<input type="checkbox" v-model="data.remember">记住密码
<hr>
<!--
下拉框
对于 <select>, v-model 绑定的是 select 元素的选中状态
-->
<select v-model="data.select">
<option value="">请选择</option>
<option value="A">写作</option>
<option value="B">画画</option>
<option value="C">运动</option>
</select>
</div>
const data = reactive({
text: "dengruicode.com", //文本框
radio: "", //单选框
checkbox: [], //复选框
remember: false, //单个复选框-记住密码
select: "" //下拉框
})
10. v-model修饰符
<div id="app">
<h3>url: {{ web.url }}</h3>
<h3>user: {{ web.user }}</h3>
实时渲染 <input type="text" v-model="web.url"> <br>
在失去焦点或按下回车键之后渲染 <input type="text" v-model.lazy="web.url"> <br>
<!-- 输入 100人, web.user 的值仍为 100 -->
输入框的值转换为数字类型 <input type="text" v-model.number="web.user"> <br>
去除首尾空格 <input type="text" v-model.trim="web.url">
</div>
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const web = reactive({
url: "code.com",
user: 10
})
return {
web
}
}
}).mount("#app")
</script>
11.渲染数据v-text和v-html
<div id="app">
<h3>{{ web.title }}</h3>
<!-- v-text 将数据解析为纯文本格式 -->
<h3 v-text="web.title"></h3>
<!-- v-html 将数据解析为 html 格式 -->
<h3 v-html="web.url"></h3>
</div>
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const web = reactive({
title: "编程",
url:"<i style='color:blue;'>www.code.com</i>"
})
return {
web
}
}
}).mount("#app")
</script>
12.计算属性computed
<div id="app">
<h3>add: {{ add() }}</h3>
<h3>add: {{ add() }}</h3>
<h3>sum: {{ sum }}</h3>
<h3>sum: {{ sum }}</h3>
x <input type="text" v-model.number="data.x"> <br>
y <input type="text" v-model.number="data.y">
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
const data = reactive({
x: 10,
y: 20
})
//方法-无缓存
let add = () => {
console.log("add") //打印两次
return data.x + data.y
}
//计算属性-有缓存 [计算属性根据其依赖的响应式数据变化而重新计算]
const sum = computed(() => {
console.log("sum") //打印一次
return data.x + data.y
})
return {
data,
sum,
add
}
}
}).mount("#app")
</script>
13.侦听器watch
<div id="app">
爱好
<select v-model="hobby">
<option value="">请选择</option>
<option value="1">写作</option>
<option value="2">画画</option>
<option value="3">运动</option>
</select>
<hr>
年
<select v-model="date.year">
<option value="">请选择</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
</select>
月
<select v-model="date.month">
<option value="">请选择</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
</div>
<script type="module">
import { createApp, ref, reactive, watch } from './vue.esm-browser.js'
createApp({
setup() {
const hobby = ref("") //爱好
const date = reactive({ //日期
year: "2023",
month: "10"
})
//监听 hobby
watch(hobby, (newValue, oldValue) => {
console.log("oldValue", oldValue, "newValue", newValue)
if (newValue == "2") {
console.log("画画")
}
})
//监听 date
watch(date, (newValue, oldValue) => {
/*
JS中对象和数组是通过引用传递的, 而不是通过值传递
当修改对象或数组的值时, 实际上修改的是对象或数组的引用, 而不是创建一个新的对象或数组
所以,如果修改了对象或数组的值,那么打印出来的结果则是修改后的值
*/
console.log("oldValue", oldValue, "newValue", newValue)
if (newValue.year == "2025") {
console.log("2025")
}
if (newValue.month == "11") {
console.log("11")
}
})
//监听 date 中的某个属性 year
watch(() => date.year, (newValue, oldValue) => {
console.log("oldValue", oldValue, "newValue", newValue)
if (date.year == "2024") {
console.log("2024")
}
})
return {
hobby,
date
}
}
}).mount("#app")
</script>
14.自动侦听器watchEffect
<div id="app">
爱好
<select v-model="hobby">
<option value="">请选择</option>
<option value="1">写作</option>
<option value="2">画画</option>
<option value="3">运动</option>
</select>
<hr>
年
<select v-model="date.year">
<option value="">请选择</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
</select>
月
<select v-model="date.month">
<option value="">请选择</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
</div>
<script type="module">
/*
watch需要显式指定要监听的属性, 并且只有当监听的属性发生变化时才会执行
若需要更精细地控制或需要获取到原值, 需要使用watch
*/
import { createApp, ref, reactive, watchEffect } from './vue.esm-browser.js'
createApp({
setup() {
const hobby = ref("") //爱好
const date = reactive({ //日期
year: "2023",
month: "10"
})
//自动监听
watchEffect(() => {
console.log("------ 监听开始")
if (hobby.value == "2") {
console.log("画画")
}
if (date.year == "2025") {
console.log("2025")
}
if (date.month == "11") {
console.log("11")
}
console.log("------ 监听结束")
})
return {
hobby,
date
}
}
}).mount("#app")
</script>