Vue 基本概念
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。库是封装的属性或方法(如:jQuery),而框架是拥有自己的规则和元素,比库强大的多(如:Vue)。
MVVM 设计模式
@vue/cli 脚手架
1 2 3
| yarn global add @vue/cli
npm install -g @vue/cli
|
创建项目启动服务
- 创建项目
- 进入脚手架项目下, 启动内置的热更新本地服务器
1 2 3 4 5
| cd vuecil-demo
npm run serve
yarn serve
|
目录树和代码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| vuecil-demo ├── node_modules ├── public ├── favicon.ico └── index.html ├── src ├── assets └── logo.png ├── components └── HelloWorld.vue ├── App.vue └── main.js ├── .gitignore ├── babel.config.js ├── package.json ├── README.md └── yarn.lock
|
主要文件及含义
1 2 3 4 5
| node_modules中都是下载的第三方包 public/index.html – 浏览器运行的网页 src/main.js – webpack打包的入口文件 src/App.vue – vue项目入口页面 package.json – 依赖包列表文件
|
eslint 了解
一个代码检查工具,如声明了变量但未使用,会报错,本阶段主要学习 Vue 语法,暂时关闭 eslint 检查
1 2 3
| module.exports = { lintOnSave: false, };
|
注意事项
- Vue 推荐采用.vue 文件来开发项目
- template 里只能有一个根标签
- vue 文件-独立模块-作用域互不影响
- style 配合 scoped 属性, 保证样式只针对当前 template 内标签生效
- vue 文件配合 webpack, 把他们打包起来插入到 index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div>{{ name }}</div> </template>
<script> export default { data() { return { name: 'Hello Vue', }; }, }; </script>
<style scoped></style>
|
Vue 指令
插值表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <h1>{{ msg }}</h1> <h2>{{ obj.name }}</h2> <h3>{{ obj.age > 18 ? '成年' : '未成年' }}</h3> </div> </template>
<script> export default { data() { return { msg: 'hello, vue', obj: { name: '小vue', age: 5, }, }; }, }; </script>
<style></style>
|
v-bind
- 语法:v-bind:属性名="vue 变量"
- 简写:
:属性名="vue变量"
1 2 3
| <a v-bind:href="url">我是a标签</a> <img :src="imgSrc" />
|
v-on
- 语法:
- v-on:事件名="要执行的==少量代码=="
- v-on:事件名="methods 中的函数"
- v-on:事件名="methods 中的函数(实参)"
- 简写:
@事件名="methods 中的函数"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <div> <p>你要买商品的数量: {{ count }}</p> <button v-on:click="count ++">增加1</button> <button v-on:click="addFn">增加1个</button> <button v-on:click="addCountFn(5)">一次加5件</button> <button @click="count --">减少</button> </div> </template>
<script> export default { data() { return { count: 1 } } methods: { addFn() { this.count++ }, addCountFn(num) { this.count += num } }, } </script>
|
v-on 事件对象
- 无传参, 通过形参直接接收
- 传参, 通过 $event 指代事件对象传给事件处理函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <a @click="one" href="http://www.baidu.com">阻止百度</a> <hr /> <a @click="two(10, $event)" href="http://www.baidu.com">阻止去百度</a> </div> </template>
<script> export default { methods: { one(e) { e.preventDefault(); }, two(num, e) { e.preventDefault(); }, }, }; </script>
|
v-on 修饰符
- @事件名.修饰符="methods 里函数"
- .stop - 阻止事件冒泡
- .prevent - 阻止默认行为
- .once - 程序运行期间, 只触发一次事件处理函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div @click="fatherFn"> <button @click.stop="btn">.stop阻止事件冒泡</button> <a href="http://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a> <button @click.once="btn">.once程序运行期间, 只触发一次事件处理函数</button> </div> </template>
<script> export default { methods: { fatherFn() { console.log('father被触发'); }, btn() { console.log(1); }, }, }; </script>
|
v-on 按键修饰符
- @keyup.enter - 监测回车按键
- @keyup.esc - 监测返回按键
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <input type="text" @keydown.enter="enterFn" /> <hr /> <input type="text" @keydown.esc="escFn" /> </div> </template>
<script> export default { methods: { enterFn() { console.log('enter回车按键了'); }, escFn() { console.log('esc按键了'); }, }, }; </script>
|
综合案例-翻转世界
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <h1>{{ message }}</h1> <button @click="btn">逆转世界</button> </div> </template>
<script> export default { data() { return { message: 'HELLO, WORLD', }; }, methods: { btn() { this.message = this.message.split('').reverse().join(''); }, }, }; </script>
|
v-model
- 语法: v-model="vue 数据变量"
- 双向数据绑定
- 数据变化 -> 视图自动同步
- 视图变化 -> 数据自动同步
- 演示: 用户名绑定 - vue 内部是 MVVM 设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <template> <div>
<div> <span>用户名:</span> <input type="text" v-model="username" /> </div> <div> <span>密码:</span> <input type="password" v-model="pass" /> </div> <div> <span>来自于: </span> <select v-model="from"> <option value="北京市">北京</option> <option value="南京市">南京</option> <option value="天津市">天津</option> </select> </div> <div>
<span>爱好: </span> <input type="checkbox" v-model="hobby" value="抽烟" />抽烟 <input type="checkbox" v-model="hobby" value="喝酒" />喝酒 <input type="checkbox" v-model="hobby" value="写代码" />写代码 </div> <div> <span>性别: </span> <input type="radio" value="男" name="sex" v-model="gender" />男 <input type="radio" value="女" name="sex" v-model="gender" />女 </div> <div> <span>自我介绍</span> <textarea v-model="intro"></textarea> </div> </div> </template>
<script> export default { data() { return { username: '', pass: '', from: '', hobby: [], sex: '', intro: '', }; }, }; </script>
|
特别注意: v-model, 在 input[checkbox]的多选框状态:
- 变量为非数组, 则绑定的是 checked 的属性(true/false) - 常用于: 单个绑定使用
- 变量为数组, 则绑定的是他们的 value 属性里的值 - 常用于: 收集勾选了哪些值
v-model 修饰符
- v-model.修饰符="vue 数据变量"
- .number 以 parseFloat 转成数字类型
- .trim 去除首尾空白字符
- .lazy 在 change 时触发而非 inupt 时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <template> <div> <div> <span>年龄:</span> <input type="text" v-model.number="age" /> </div> <div> <span>人生格言:</span> <input type="text" v-model.trim="motto" /> </div> <div> <span>自我介绍:</span> <textarea v-model.lazy="intro"></textarea> </div> </div> </template>
<script> export default { data() { return { age: '', motto: '', intro: '', }; }, }; </script>
|
v-text 和 v-html
v-text 把值当成普通字符串显示, v-html 把值当做 html 解析
- 语法:
- v-text="vue 数据变量"
- v-html="vue 数据变量"
- 注意: 会覆盖插值表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <p v-text="str"></p> <p v-html="str"></p> </div> </template>
<script> export default { data() { return { str: '<span>我是一个span标签</span>', }; }, }; </script>
|
v-show 和 v-if
- 语法:
- v-show="vue 变量"
- v-if="vue 变量"
- 原理
- v-show 用的 display:none 隐藏 (频繁切换使用)
- v-if 直接从 DOM 树上移除
- 高级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <h1 v-show="isOk">v-show的盒子</h1> <h1 v-if="isOk">v-if的盒子</h1>
<div> <p v-if="age > 18">我成年了</p> <p v-else>还得多吃饭</p> </div> </div> </template>
<script> export default { data() { return { isOk: true, age: 15, }; }, }; </script>
|
综合案例-折叠面板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div id="app"> <h3>案例:折叠面板</h3> <div> <div class="title"> <h4>芙蓉楼送辛渐</h4> <span class="btn" @click="isShow = !isShow"> {{ isShow ? '收起' : '展开' }} </span> </div> <div class="container" v-show="isShow"> <p>寒雨连江夜入吴,</p> <p>平明送客楚山孤。</p> <p>洛阳亲友如相问,</p> <p>一片冰心在玉壶。</p> </div> </div> </div> </template>
<script> export default { data() { return { isShow: false, }; }, }; </script>
|
v-for
- 语法
- v-for="(值, 索引) in 目标结构"
- v-for="值 in 目标结构"
- 目标结构:
- 可以遍历数组 / 对象 / 数字 / 字符串 (可遍历结构)
- 注意:
- v-for 的临时变量名不能用到 v-for 范围外
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| <template> <div id="app"> <div id="app"> <p>学生姓名</p> <ul> <li v-for="(item, index) in arr" :key="item">{{ index }} - {{ item }}</li> </ul>
<p>学生详细信息</p> <ul> <li v-for="obj in stuArr" :key="obj.id"> <span>{{ obj.name }}</span> <span>{{ obj.sex }}</span> <span>{{ obj.hobby }}</span> </li> </ul>
<p>老师信息</p> <div v-for="(value, key) in tObj" :key="value">{{ key }} -- {{ value }}</div>
<p>序号</p> <div v-for="i in count" :key="i">{{ i }}</div> </div> </div> </template>
<script> export default { data() { return { arr: ['小明', '小欢欢', '大黄'], stuArr: [ { id: 1001, name: '孙悟空', sex: '男', hobby: '吃桃子', }, { id: 1002, name: '猪八戒', sex: '男', hobby: '背媳妇', }, ], tObj: { name: '小黑', age: 18, class: '1期', }, count: 10, }; }, }; </script>
|