Vue_Study01
1.Vue是什么?
1.1-Vue怎么学
- Vue是在工程化的环境下进行学习的
1.2-Vue开发方式
1.3-Vue脚手架项目创建
-
目录
1.x-创建工程文件报错解决方案
-
注意点!!!
- 如果index.html出现
-
解决方法
-
在vue.config.js里面修改为
-
module.exports = { // 部署生产环境和开发环境下的URL。 // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 // 例如 https://www.uxsoft.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.uxsoft.vip/admin/,则设置 baseUrl 为 /admin/。 publicPath: process.env.NODE_ENV === "production" ? "/" : "/", // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist) outputDir: "dist", // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下) assetsDir: "static", // 是否开启eslint保存检测,有效值:ture | false | 'error' lintOnSave: process.env.NODE_ENV === "development", // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 productionSourceMap: false, // webpack-dev-server 相关配置 chainWebpack(config) { config.plugin("html").tap(args => { args[0].title = "title名字"; return args; }) } }
-
-
-
试验如果对vue.config.js不进行修改的话,也可以正常启动(默认就是)
-
chainWebpack(config) { config.plugin("html").tap(args => { args[0].title = "title名字"; return args; }) }
-
-
如果template报下面的错误
-
TypeScript intellisense is disabled on template. To enable, configure `"jsx": "preserve"` in the `"compilerOptions"` property of tsconfig or jsconfig. To disable this prompt instead, configure `"experimentalDisableTemplateSupport": true` in `"vueCompilerOptions"` property.
-
解决方案 jsconfig.json
-
{ "compilerOptions": { "target": "es5", "module": "esnext", "baseUrl": "./", "jsx": "preserve", //在这里添加"jsx": "preserve", "moduleResolution": "node", "paths": { "@/*": [ "src/*" ] }, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] } }
-
-
1.4-Vue工程目录和代码分析
-
目录
-
脚手架里面的主要文件和作用?
- node_moudules - 都是下载的第三方包
- public/index.html - 浏览器运行的网页
- src/main.js - webpack打包的入口
- scr/App.vue - Vue页面的入口
- package.json - 依赖包列表文件
1.5-Vue主要的三个文件关系
- main.js和App.vue,以及index.html作用和关系?
- main.js-项目打包主入口——Vue初始化
- App.vue——Vue页面主入口
- index.html——浏览器运行的文件
- App.vue=>main.js=>index.html
1.6-脚手架项目配置文件是什么?
vue.config.js
//vue脚手架项目——默认的配置文件名
//webpack+node环境——导出配置对象
module.exports = {
devServer:{
port:3000,
open:true //浏览器自动打开
}
}
1.7-Vue_eslint简介
- eslint是什么?
- eslint是代码检查工具,违反规定就报错
- 如何暂时关闭?
- 在vue.config.js中设置lintOnSave为false,重启服务器
1.8-单Vue文件讲解
- Vue推荐采用.vue文件来开发项目
- template里只能有一个根标签
- js独立作用域互不影响
- style配合scoped属性,保证样式只针对当前template内标签生效
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
1.9-vue清空脚手架欢迎界面
- assets下的图片和componts下的文件,App.vue初始代码
- 删除即可,但是要留下Vue项目入口页面App.vue文件
2.Vue语法
2.1-插值表达式:
<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>
- 什么是插值表达式?
- 双大括号,可以把vue数据变量直接显示在标签内
- Vue中变量声明在哪里?
- data函数返回的对象上,用key属性声明
2.2-MVVM设计模式:
-
什么是设计模式?
- 设计模式是对代码的分层,引入一种架构的概念
-
MVVM是什么?
- MVVM(模型,视图,视图模型双向关联的一种设计模式)
-
MVVM好处?
- 减少DOM操作,提高开发效率
-
如何给dom标签的属性,设置Vue数据变量
- : 属性名= “Vue数据变量”
2.3-Vue指令_v-bind
问题:以前给a标签设置href如何做?
Vue的做法:
-
v-bind语法和简写
- 语法:v-bind:属性名=“vue变量”
- 简写——:属性名=“vue变量”
-
<template> <div> <!-- * 2.值 -> 标签原生属性上 --> <!-- * 语法:v-bind:原生属性名 = "vue变量" --> <a v-bind:href="url">点击去百度</a> <img :src="imgurl" alt="" /> </div> </template> <script> export default { // 1.准备变量 data() { return { url: "http://www.baidu.com", imgurl: "https://imagepphcloud.thepaper.cn/pph/image/85/933/79.jpg", }; }, }; </script> <style> </style>
2.4-Vue指令_v-on
问题:以前如何给按钮绑定点击事件?
语法:
- v-on:事件名=“要执行的少量代码”
- v-on:事件名=“methods中的函数名”
- v-on:事件名=“methods中的函数名(实参)”
示例
案例效果:
2.4.1:v-on的简写
- 语法:
- @事件名=“methods中的函数”
案例代码:
<template>
<div>
<p>你要买商品的数量:{{ count }}</p>
<!-- * 1.绑定事件 语法:v-on:事件名="少量代码" -->
<button v-on:click="count = count + 1">增加1</button>
<!-- * 语法:v-on:事件名="methods里函数名" -->
<button v-on:click="addFn">增加1个</button>
<!-- * 语法:v-on:事件名="methods"里面函数名 -->
<button v-on:click="addCountFn(5)">一次加5件</button>
<!-- * 语法:@事件名="methods里函数名" -->
<button @click="subFn">减少1</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 1,
};
},
// * 2.定义函数
methods: {
addFn() {
// this指向的export default的{} data函数会把对象挂到当前组件对象上
this.count++;
},
addCountFn(num) {
this.count = this.count + num;
},
subFn() {
this.count--;
},
},
};
</script>
<style>
</style>
2.4.2:小结
- 如何给dom标签绑定事件?
- @事件名=“methods里的函数名”
- 如何给事件传值呢?
- @事件名=“methods里的函数名(实参)”
2.5-接收事件对象
目标:Vue事件处理函数中,拿到事件对象
- 语法:
- 无传参,通过形参直接接收
- 传参,通过$event指代事件对象传给事件处理函数
<template>
<div>
<a @click="one" href="http://www.baidu.com">百度</a>
<hr />
<a @click="two(10, $event)" href="http://www.taobao.com">淘宝</a>
</div>
</template>
<script>
export default {
methods: {
// 1.事件触发,无传值,可以直接获取事件对象
one(e) {
e.preventDefault();
},
// 2.事件触发,需要手动传入$event
two(num, e) {
e.preventDefault();
},
},
};
</script>
<style>
</style>
2.6-Vue事件_修饰符
-
语法
- @事件名.修饰符=“methods里函数”
-
修饰符列表
- .stop - 阻止事件冒泡
- .prevent - 阻止默认行为
- .once - 程序运行期间,只触发/执行一次事件处理函数
<template> <div> <div @click="fatherFn"> <!-- * .stop就是阻止事件冒泡的 --> <p @click.stop="oneFn">.stop - 阻止事件冒泡</p> <a href="http://www.baidu.com" @click.prevent.stop>去百度</a> <!-- * .once - 程序运行期间,只触发/执行一次事件处理函数 --> <p @click.once="twoFn">点击观察事件处理函数执行几次</p> <!-- * 这里要注意,是函数只触发一次,但是一次点击就可以触发一次 --> </div> </div> </template> <script> export default { methods: { fatherFn() { console.log("father-触发click事件"); }, oneFn() { console.log("p标签点击了"); }, twoFn() { console.log("p标签被点击了"); }, }, }; </script> <style> </style>
2.7-Vue按键_修饰符
目标:给键盘事件,添加修饰符,增强能力
- 语法:
- @keyup.enter - 监测回车按键
- @keyup.esc - 监测返回按键
<template>
<div>
<!-- * 1. 绑定键盘按下事件 .enter-回车 -->
<input type="text" @keydown.enter="enterFn" />
<hr />
<!-- * 2. 绑定.esc修饰符 - 取消键 -->
<input type="text" @keydown.esc="escFn" />
</div>
</template>
<script>
export default {
methods: {
enterFn() {
console.log("用户按下的回车");
},
escFn() {
console.log("用户按下的Esc键");
},
},
};
</script>
<style>
</style>
- 按键修饰符如何使用?
- @键盘事件.按键修饰符=“methods里函数名”
- 有哪些主要按键修饰符?
- .enter - 只有按下回车才能触发这个键盘事件函数
- .esc - 只有按下取消键才能触发这个键盘事件函数
2.8-Vue指令_v-model
2.8.1-基础使用
value属性和Vue数据变量,双向绑定到一起
-
语法:v-model = “Vue数据变量”
-
双向数据绑定
- 变量变化 - > 视图自动同步
- 视图变化 - > 变量自动同步
-
案例:完成注册表单
-
<template> <div> <div> <span>用户名:</span> <!-- 1.v-model 双向数据绑定 --> <!-- ? value属性 - vue变量 --> <input type="text" v-model="username" /> </div> <div> <span>密码</span> <input type="password" v-model="password" /> </div> </div> </template> <script> export default { data() { return { username: "", password: "", }; }, }; </script> <style> </style>
v-model用在哪里?
- 暂时只能用在表单标签上
v-model有什么用?
- 把vue的数据变量和表单的value属性双向绑定在一起
2.8.2-v-model绑定不同表单标签
-
下拉菜单,复选框,单选框如何绑定Vue变量
-
语法:v-model = “Vue数据变量”
-
<template> <div> <div> <span>来自于:</span> <!-- * 下拉菜单要绑定在select上 --> <select v-model="form"> <option value="北京市">北京</option> <option value="南京市">南京</option> <option value="天津市">天津</option> </select> </div> <div> <!-- (重要) 遇到复选框的时候,v-model的变量值 非数组 - 关联的是复选框的checked属性 数组 - 关联的是复选框的value属性 --> <span>爱好:</span> <input type="checkbox" v-model="hobby" value="抽烟" />抽烟 <input type="checkbox" v-model="hobby" value="喝酒" />喝酒 <input type="checkbox" v-model="hobby" value="玩Vue" />玩Vue </div> <div> <span>性别:</span> <input type="radio" v-model="gender" value="男" name="sex" />男 <input type="radio" v-model="gender" value="女" name="sex" />女 </div> <div> <span>自我介绍</span> <textarea v-model="info" name="" id="" cols="30" rows="10"></textarea> </div> </div> </template> <script> export default { data() { return { // 如果想让选项框/文本框,默认选中/由内容 // 数据双向绑定,可以实现 form: "南京市", hobby: ["抽烟"], gender: "男", info: "在这里写自我介绍", }; }, }; </script> <style> </style>
-
重点!
- 遇到复选框的时候,v-model的变量值 ->
- 非数组 - 关联的是复选框的checked属性
- 数组 - 关联的是复选框的value属性
- 遇到复选框的时候,v-model的变量值 ->
-
小结
- 下拉菜单v-model写在哪里?
- 在select,value在option上
- vue变量初始值会不会影响表单的默认状态?
- 影响,因为双向数据绑定-互相影响
- 下拉菜单v-model写在哪里?
2.8.3-v-model修饰符
目标:让v-model拥有更强大的功能
-
语法:v-model.修饰符=“Vue数据变量”
- .number 以parseFloat转成数字类型
- 转成数值类型赋予给Vue数据变量
- .trim 去除首尾空白字符
- 去除左右两边空格后把值赋予给Vue数据变量
- .lazy 在change时触发而非input
- 等表单失去焦点,才把值赋予给Vue数据变量
- .number 以parseFloat转成数字类型
-
<template> <div> <div> <span>年龄</span> <!-- * .number修饰符-把值parseFloat转数值之后再赋予给v-model对应的变量 --> <input type="number" v-model.number="age" /> </div> <div> <!-- * .trim修饰符 - 去除首尾两边空格 --> <span>人生格言</span> <input type="text" v-model.trim="motto" /> </div> <div> <!-- * .lazy修饰符 - 失去焦点内容改变时(onchange事件),把内容同步给v-model的变 * 说白了,就是鼠标离开这个textarea文本框之后->失去焦点之后,将变量同步 --> <span>个人简介</span> <textarea v-model.lazy="info"></textarea> </div> </div> </template> <script> export default { data() { return { age: 0, motto: "", info: "", }; }, }; </script> <style> </style>
2.9-Vue指令v-text和v-html
-
目标:更新Dom对象的innerText/innerHTML
-
语法:
- v-text = “Vue数据变量”
- v-html = “Vue数据变量”
-
作用?
- 设置标签显示的内容
-
区别:
- v-text把值当成普通字符串显示
- v-html把值当成标签进行解析显示
-
注意:会覆盖插值表达式
-
<template> <div> <p v-text="str"></p> <p v-html="str">{{ 10 + 20 }}</p> <!-- * 注意:v-text和v-html会覆盖插值表达式 --> <p></p> </div> </template> <script> export default { data() { return { str: "<span>我是一个span</span>", }; }, }; </script> <style> </style>
2.10-Vue指令_v-show和v-if
目标:控制标签的隐藏或出现
-
语法:
- v-show = “Vue变量”
- v-if = “Vue变量”
-
原理:
- v-show隐藏:采用display:none ->频繁切换 ——用css方式隐藏
- v-if隐藏:采用从DOM树直接移除 -> 移除
-
高级
- v-else的使用
- v-if可以配合v-else或者v-else-if使用
- v-else的使用
-
小结
- v-show或者v-if,给变量赋予true/false
2.11-Vue指令_v-for
目标:列表渲染,所在标签结构,按照数据数量,循环生成
-
语法:
- v-for=“(值变量,索引变量)in目标结构”
- v-for=“值变量in目标结构”
-
目标结构
- 可以遍历数组/对象/数字
-
注意:
- v-for的临时变量名不能用到v-for范围外
-
案例图片:
-
<template> <div> <!-- * 语法1: v-for="(值变量名,索引变量名) in 目标结构"--> <ul> <li v-for="(item, index) in arr" :key="index"> {{ item }} ------{{ index }} <!-- * 其实就是for循环里面的值 --> </li> </ul> <ul> <!-- * 语法2 v-for="值变量名 in 目标结构" --> <li v-for="obj in stuArr" :key="obj.id"> <span>{{ obj.name }}</span> <span>{{ obj.sex }}</span> <span>{{ obj.hobby }}</span> </li> </ul> <!-- * 语法3(了解): v-for="(value,key) in 对象" --> <div> <p v-for="(value, key) in tObj" :key="value"> <span>{{ value }}</span> ==================== <span>{{ key }}</span> </p> </div> <!-- * 语法4(了解): v-for="变量名 in 固定数字" --> <!-- ! 从1开始遍历 --> <div v-for="n in count" :key="n">{{ n }}</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> <style> </style>
2.11.1-v-for更新检测
目标:目标结构变化,触发v-for的更新
-
情况1:数组翻转
-
情况2:数组截取
-
情况3:更新值
-
口诀
- 数组变更方法,就会导致v-for更新,页面更新
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
- 数组非变更方法,返回新数组,就不会导致v-for更新,可采用覆盖数组或this.$set()
- filter()
- concat()
- slice()
- 数组变更方法,就会导致v-for更新,页面更新
-
案例代码
-
<template> <div> <ul> <li v-for="(val, index) in arr" :key="index"> {{ val }} </li> </ul> <button @click="revBtn">数组翻转</button> <button @click="sliceBtn">截取前3个</button> <button @click="updateBtn">更新第一个元素值</button> </div> </template> <script> export default { data(){ return { arr: [5, 3, 9, 2, 1] } }, methods: { revBtn(){ // 1. 数组翻转可以让v-for更新 this.arr.reverse() }, sliceBtn(){ // 2. 数组slice方法不会造成v-for更新 // slice不会改变原始数组 // this.arr.slice(0, 3) // 解决v-for更新 - 覆盖原始数组 let newArr = this.arr.slice(0, 3) this.arr = newArr }, updateBtn(){ // 3. 更新某个值的时候, v-for是监测不到的 // this.arr[0] = 1000; // 解决-this.$set() // 参数1: 更新目标结构 // 参数2: 更新位置 // 参数3: 更新值 this.$set(this.arr, 0, 1000) } } } </script> <style> </style>
小结:
- 哪些数组方法会导致v-for更新页面?
- 可以改变原数组的方法(如2.11.1所述)
- 有的数组方法不导致v-for更新页面,如何处理?
- 拿返回的新数组,直接替换旧数组
- this.$set()方法更新某个值
2.x-练习
1.点击翻转字符串显示思路是什么?
案例图:
- 写需求要先静态标签,在考虑动态效果,找好第一步干什么
- 记住方法的特点——可以自己总结字典和口诀
- Vue是靠数据驱动视图,只需要关心数据变化即可
<template>
<div>
<!-- * 2. 变量准备-静态页面铺设 -->
<h1>{{ msg }}</h1>
<!-- * 绑定点击事件 -->
<button @click="btn">逆转</button>
</div>
</template>
<script>
export default {
// 1. 准备变量
data() {
return {
msg: "Hello,Chenwei",
};
},
methods: {
btn() {
// 3.截取字符串返回数组
let arr = this.msg.split("");
// 4.翻转
arr.reverse();
// 5.数组拼接
this.msg = arr.join("");
// 简化写法 this.msg = this.msg.split("").reverse().join("");
},
},
};
</script>
<style>
</style>
2.折叠面板
案例思路
-
先完成设计静态标签
-
显示/隐藏用v-show和vue变量来控制(默认true)
-
点击切换vue变量达成目的
-
<template> <div id="app"> <h3>案例:折叠面板</h3> <div> <div class="title"> <h4>芙蓉楼送辛渐</h4> <!-- ? 1.绑定点击事件 --> <span class="btn" @click="btn"> <!-- * 4. 根据isShow的值显示不同的 文字 --> {{ isShow ? "收起" : "展开" }} </span> </div> <!-- ? 2.v-show配合变量控制标签隐藏出现 --> <div class="container" v-show="isShow"> <p>寒雨连江夜入吴,</p> <p>平明送客楚山孤。</p> <p>洛阳亲友如相问,</p> <p>一片冰心在玉壶。</p> </div> </div> </div> </template> <script> export default { data() { return { isShow: true, }; }, methods: { btn() { // 3.点击时,把值改为false 但是需要添加每次点击时,取反 this.isShow = !this.isShow; }, }, }; </script> <style lang="less"> body { background-color: #ccc; #app { width: 400px; margin: 20px auto; background-color: #fff; border: 4px solid blueviolet; border-radius: 1em; box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5); padding: 1em 2em 2em; h3 { text-align: center; } .title { display: flex; justify-content: space-between; align-items: center; border: 1px solid #ccc; padding: 0 1em; } .title h4 { line-height: 2; margin: 0; } .container { border: 1px solid #ccc; padding: 0 1em; } .btn { /* 鼠标改成手的形状 */ cursor: pointer; } } } </style>