目标: webpack自己配置环境很麻烦, 下载@vue/cli包,用vue命令创建脚手架项目
@vue/cli是Vue官方提供的一个全局模块包(得到vue命令), 此包用于创建脚手架项目脚手架是为了保证各施工过程顺利进行而搭设的工作平台
vuecil-demo # 项目目录
├── node_modules # 项目依赖的第三方包
├── public # 静态文件目录
├── favicon.ico# 浏览器小图标
└── index.html # 单页面的html文件(网页浏览的是它)
├── src # 业务文件夹
├── assets # 静态资源
└── logo.png # vue的logo图片
├── components # 组件目录
└── HelloWorld.vue # 欢迎页面vue代码文件
├── App.vue # 整个应用的根组件
└── main.js # 入口js文件
├── .gitignore # git提交忽略配置
├── babel.config.js # babel配置
├── package.json # 依赖包列表
├── README.md # 项目说明
└── yarn.lock # 项目包版本锁定和缓存地址
主要文件及含义
node_modules下都是下载的第三方包
public/index.html – 浏览器运行的网页
src/main.js – webpack打包的入口文件
src/App.vue – vue项目入口页面
package.json – 依赖包列表文件
目标:项目中没有webpack.config.js文件,因为@vue/cli用的vue.config.js
src并列处新建vue.config.js
/* 覆盖webpack的配置 */
module.exports = {
devServer: { // 自定义服务配置
open: true, // 自动打开浏览器
port: 3000
}
}
目标: 单vue文件好处, 独立作用域互不影响
Vue推荐采用.vue文件来开发项目
template里只能有一个根标签
vue文件-独立模块-作用域互不影响
style配合scoped属性, 保证样式只针对当前template内标签生效
vue文件配合webpack, 把他们打包起来插入到index.html
<!-- template必须, 只能有一个根标签, 影响渲染到页面的标签结构 -->
<template>
<div>欢迎使用vue</div>
</template>
<!-- js相关 -->
<script>
export default {
name: 'App'
}
</script>
<!-- 当前组件的样式, 设置scoped, 可以保证样式只对当前页面有效 -->
<style scoped>
</style>
最终: Vue文件配合webpack, 把他们打包起来插入到index.html, 在浏览器运行
src/App.vue默认有很多内容, 可以全部删除留下框
assets 和 components 文件夹下的一切都删除掉 (不要默认的欢迎页面)
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。
最基本的数据绑定形式是文本插值,使用的是“Mustache”语法 (即双大括号):
<script>
export default {
data(){
return{
msg: "模板语法"
}
}
}
script>
<template>
<span>
Message: {{msg}}
span>
template>
<style scoped>
style>
双大括号标签会被替换为相应组件实例中 msg
属性的值。同时每次 msg
属性更改时它也会同步更新。
双大括号会将数据解释为纯文本,不是 HTML,若想插入HTML,用v-html指令
<script>
export default {
data(){
return{
rawHtml: "color: red">展示文本插值和html插入效果 "
}
}
}
script>
<template>
<p>这是文本插值的效果展示: {{ rawHtml }}p>
<p>这是使用v-html的方式展示: <span style="color: red" v-html="rawHtml">span>p>
template>
v-html
attribute 被称为一个指令。指令由 v-
作为前缀,表明它们是一些由 Vue 提供的特殊 attribute,它们将为渲染的 DOM 应用特殊的响应式行为。这里我们做的事情就是:在当前组件实例上,将此元素的 innerHTML
与 rawHtml
属性保持同步。
通过v-once指令,能执行一次性的插值,当数据改变时,插值处的内容不会更新,但是这个会影响到该节点上的其他数据绑定:
示例展示:
<script>
export default {
data(){
return{
msg: "",
num: 2,
uname:""
}
}
}
script>
<template>
<div>
<h1>{{msg}}h1>
<h2>{{num}}h2>
<p>{{uname}}p>
<p v-once>{{uname}}p>、
<button @click="changUname">改变uname值button>
template>
如果想要改变num的值可以加一个方法调用:
在data方法的结尾处 ,method:{}
<script>
export default {
data(){
return{
msg: "",
num: 2,
uname:"张三"
}
},
methods:{
//给vue定义一个方法 用来改变属性值
changUname: function(){
//this 指向vue实例
this.uname="老六"
}
}
}
</script>
在dom标签中, 直接插入内容
又叫: 声明式渲染/文本插值
语法: {{ 表达式 }}
<template>
<div>
<h1>{{ msg }}h1>
<h2>{{ obj.name }}h2>
<h3>{{ obj.age > 18 ? '成年' : '未成年' }}h3>
div>
template>
<script>
export default {
data() { // 格式固定, 定义vue数据之处
return { // key相当于变量名
msg: "hello, vue",
obj: {
name: "小vue",
age: 5
}
}
}
}
script>
<style>
style>
dom中插值表达式赋值, vue的变量必须在data里声明
用数据驱动视图改变, 操作dom的事, vue源码内干了
设计模式: 是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
演示: 在上个代码基础上, 在devtool工具改变M层的变量, 观察V层(视图的自动同步)
学v-model再观察V改变M的效果
- MVVM,一种软件架构模式,决定了写代码的思想和层次
- M: model数据模型 (data里定义)
- V: view视图 (html页面)
- VM: ViewModel视图模型 (vue.js源码)- MVVM通过
数据双向绑定
让数据自动地双向同步 不再需要操作DOM
- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动同步)
2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)
vue源码内采用MVVM设计模式思想, 大大减少了DOM操作, 挺高开发效率
给标签属性设置vue变量的值
vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头
每个指令, 都有独立的作用
- 语法:
v-bind:属性名="vue变量"
- 简写:
:属性名="vue变量"
<script>
import imgObj from './assets/mm.gif'
<!-- vue指令-v-bind属性动态赋值 -->
export default {
data(){
return{
url:"http://www.baidu.com",
imgUrl: "https://img13.360buyimg.com/n1/s450x450_jfs/t1/175460/22/30483/67259/638dbe8fE9900688c/83ac7462bd005fdf.jpg",
localImg: imgObj
}
}
}
script>
<template>
<a v-bind:href="url">点击去百度a>
<img :src="imgUrl" />
<img :src="localImg">
div>
template>
把vue变量的值, 赋予给dom属性上, 影响标签显示效果
案例2:动态更改属性的值
<script>
export default {
data(){
return{
id: "d1",
imageUrl: "https://img13.360buyimg.com/n1/s450x450_jfs/t1/175460/22/30483/67259/638dbe8fE9900688c/83ac7462bd005fdf.jpg"
}
},
methods:{
changogg:function(){
this.id="d2"
}
}
}
script>
<template>
<div>
<p v-bind:id="id">v-bind的绑定p>
<img v-bind:src="imageUrl"/>
<button @click="changogg">更改id的颜色button>
<button @click="id='d2'">更改id的颜色button>
div>
template>
<style>
#d1{
color: burlywood;
}
#d2{
color: red;
}
style>
给标签绑定事件
- 语法
- v-on:事件名=“要执行的少量代码”
- v-on:事件名=“methods中的函数”
- v-on:事件名=“methods中的函数(实参)”
- 简写: @事件名=“methods中的函数”
<p>你要买商品的数量: {{count}}p>
<button v-on:click="count = count + 1">增加1button>
<button v-on:click="addFn">增加1个button>
<button v-on:click="addCountFn(5)">一次加5件button>
<button @click="subFn">减少button>
<script>
export default {
// ...其他省略
methods: {
addFn(){ // this代表export default后面的组件对象(下属有data里return出来的属性)
this.count++
},
addCountFn(num){
this.count += num
},
subFn(){
this.count--
}
}
}
script>
常用@事件名, 给dom标签绑定事件, 以及=右侧事件处理函数
vue事件处理函数中, 拿到事件对象
- 语法:
- 无传参, 通过形参直接接收
- 传参, 通过 $event 指代事件对象传给事件处理函数
<template>
<div>
<a v-on: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: {
// 1. 事件触发, 无传值, 可以直接获取事件对象是
one(e){
e.preventDefault()
},
// 2. 事件触发, 传值, 需要手动传入$event
two(num, e){
e.preventDefault()
}
}
}
script>
动态参数说明: 在指令参数中用JavaScript表达式,用方括号括起来:
示例:
<script>
export default {
data(){
return{
id: "d1",
attributeName:"id",
mouseEvent:"click",
}
}
}
script>
<template>
<div>
<span v-bind:[attributeName]="id">v-bind的绑定span><br>
<button @click="attributeName='class'">改变属性字体大小button>
<button @[mouseEvent]="attributeName='class'">改变属性button>
<button @click="mouseEvent='mouseover'">改变属性样式button>
div>
template>
<style>
.d1{
font-size: 50px;
}
style>
在事件后面.修饰符名 - 给事件带来更强大的功能
- 语法:
- @事件名.修饰符=“methods里函数”
- .stop - 阻止事件冒泡
- .prevent - 阻止默认行为
- .once - 程序运行期间, 只触发 一次 事件处理函数
<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>
<script>
export default {
data(){
return{
msg:"V-on 修饰符"
}
},
methods:{
fatherFn(){
console.log("father被触发 click事件")
},
oneFn(){
console.log("button标签点击了")
},
twoFn(){
console.log("button标签被点击了")
}
}
};
script>
<template>
<div @click="fatherFn">
<h1>{{msg}}h1>
<button @click.stop="oneFn">.stop-阻止事件冒泡button>
<a href="http://www.baidu.com" @click.prevent="oneFn">.prevent阻止去百度a>
<button @click.once="twoFn">点击观察事件处理函数执行几次button>
div>
template>
<style>
h1{
color: red;
}
style>
修饰符给事件扩展额外功能
给键盘事件, 添加修饰符, 增强能力
- 语法:
- @keyup.enter - 监测回车按键
- @keyup.esc - 监测返回按键
<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>
点击按钮 - 把文字取反显示 - 再点击取反显示(回来了)
提示: 把字符串取反赋予回去
正确代码:
<template>
<div>
<h1>{{ message }}h1>
<button @click="btn">逆转世界button>
div>
template>
<script>
export default {
data() {
return {
message: "HELLO, WORLD",
};
},
methods: {
btn(){
// 3.翻转字体
this.message = this.message.split("").reverse().join("")
}
}
};
script>
分解程序:
<template>
<div>
<h1>{{message}}h1>
<button @click="btn">翻转世界button>
div>
template>
<script>
export default {
data(){
return{
message:"hello,WORLD"
};
},
methods:{
btn(){
//3.截取字符串返回数组
let arr=this.message.split("")
console.log(arr)
//4.翻转
arr.reverse()
console.log(arr.reverse+"=这是什么")
//5.数组拼接起来
this.message=arr.join("")
console.log(this.message)
// 3.翻转字体
//this.message=this.message.split("").reverse().join("")
}
}
}
记住方法特点, 多做需求, vue是数据变化视图自动更新, 减少操作DOM时间, 提高开发效率
把value属性和vue数据变量, 双向绑定到一起
v-model=
“vue数据变量”基本使用方式:
<template>
<div>
<div>
<span>用户名:span>
<input type="text" v-model="username">
<p>{{username}}p>
div>
<div>
<span>密码:span>
<input type="password" v-model="pass">
<p>{{pass}}p>
div>
div>
template>
<script>
export default {
data(){
return{
username: "",
pass:""
}
}
}
script>
案例导入使用:
<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: "",
};
// 总结:
// 特别注意: v-model, 在input[checkbox]的多选框状态
// 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
// 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值
}
};
script>
让v-model拥有更强大的功能
- 语法:
- v-model.修饰符=“vue数据变量”
- .number 以parseFloat转成数字类型
- .trim 去除首尾空白字符
- .lazy 在change时触发而非inupt时
<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-model修饰符, 可以对值进行预处理, 非常高效好用