1.1 初始化脚手架

1.1.1 说明

  1. Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)
  2. 最新的版本是 4.x
  3. 文档

1.1.2 具体步骤

  1. 第一步(仅第一次执行):全局安装 @vue/cli

    npm install -g @vue/cli
  2. 第二步: 切换到要创建项目的目录 ,然后使用命令创建项目

    vue create xxxx

    xxxx: 项目名

  3. 第三步:启动项目

    npm run serve
  4. 备注:

    1. 如出现:下载缓慢请配置淘宝镜像:

      npm config set registry https://registry.npm.taobao.org
    2. Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpack配置,请执行:

      vue inspect > output.js

1.1.3 模板项目的结构

├──node_modules
├──public
│ ├──favicon.ico:页签图标
│ └──index.html:主页面
├──src
│ ├──assets:存放静态资源
│ │ └──logo.png
│ │──component:存放组件
│ │ └──HelloWorld.vue
│ │──App.vue:汇总所有组件
│ │──main.js:入口文件
├──.gitignore:git版本管制忽略的配置
├──babel.config.js:babel的配置文件
├──package.json:应用包配置文件
├──README.md:应用描述文件
├──package-lock.json:包版本控制文件

1.1.4 不同版本的 Vue

  1. vue.jsvue.runtime.xxx.js 的区别:

    1. vue.js 是完整版的 Vue,包含:核心功能 + 模板解析器。
    2. vue.runtime.xxx.js 是运行版的 Vue,只包含:核心功能;没有模板解析器
  2. 因为 vue.runtime.xxx.js 没有模板解析器,所以不能使用 template 这个配置项,需要使用 render 函数接收到的 createElement 函数去指定具体内容

1.1.5 vue.config.js 配置文件

  1. 使用 vue inspect > output.js 可以查看到Vue脚手架的默认配置。

  2. 使用 vue.config.js 可以对脚手架进行个性化定制,详情

1.2 ref

1.2.1 使用说明

  1. 被用来给元素或子组件注册引用信息(id 的替代者)
  2. 应用在 html 标签上获取的是真实 DOM 元素,应用在组件标签上是组件实例对象(vc
  3. 使用方式:
    1. 打标识:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
    2. 获取:this.$refs.xxx

1.3 props

1.3.1 使用说明

  1. 功能:让组件接收外部传过来的数据

  2. 传递数据:<Demo name="xxx"/>

  3. 接收数据:

    1. 第一种方式(只接收):props:['name']

    2. 第二种方式(限制类型):props:{name:String}

    3. 第三种方式(限制类型、限制必要性、指定默认值):

      props:{
      name:{
      type:String, //类型
      required:true, //必要性
      default:'老王' //默认值
      }
      }

    备注:props 是只读的,Vue 底层会监测你对 props 的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制 props 的内容到 data 中一份,然后去修改 data 中的数据。

1.3.2 代码示例

父组件 App 中使用子组件 Student,并传参数

<template>
<div id="app">
<!-- 注意:属性前面有没有加 : 的区别,没加就是表示传的参数是字符串,加了就是表示具体的类型值 -->
<!-- <Student studentName="张三" studentSex="男" studentAge="18"/> -->
<hr />
<Student studentName="张三" studentSex="男" :studentAge="18"/>
<hr />
<Student studentSex="男" :studentAge="20"/> </div>
</template>
<script>
import Student from "./components/Student.vue"; export default {
components: { Student }
};
</script>

Student 组件接收父组件传来的参数

<template>
<div>
<h2>{{ msg }}</h2>
<h2>学生姓名: {{ studentName }}</h2>
<h2>学生性别: {{ studentSex }}</h2>
<!-- <h2>学生年龄: {{ studentAge + 1 }}</h2> -->
<h2>学生年龄: {{ age + 1 }}</h2>
<button @click="addAge">点我年龄 +10 </button>
</div>
</template> <script>
export default {
name: "Student",
// 接收参数的简要写法
// props: ['studentName', 'studentSex', 'studentAge'], // 接受参数 + 指定类型的写法
// props: {
// studentName: String,
// studentSex: String,
// // 指令类型为数值类型,当传入的类型不是数值类型时就会报错
// // Expected Number with value 18, got String with value "18".
// studentAge: Number,
// }, // 接收参数 + 指定类型 + 指定是否必传 + 指定默认值
props: {
studentName: {
// 指定类型是字符串
type: String,
// 指定默认值
default: "李四"
},
studentSex: {
type: String,
// 指定必传
required: true
},
studentAge: {
type: Number
}
}, data() {
return {
msg: "我是一名学生",
age: this.studentAge
};
}, methods: {
addAge() {
// props 是只读的,Vue 底层会监测你对 props 的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制 props 的内容到 data 中一份,然后去修改 data 中的数据。
// 警告
// Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
// this.studentAge += 10;
this.age += 10
}
}
};
</script>

1.4 混入

1.4.1 使用说明

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:

    第一步定义混入:

    {
    data(){....},
    methods:{....}
    ....
    }

    第二步使用混入:

    ​ - 全局混入:Vue.mixin(xxx)

    ​ - 局部混入:mixins:['xxx']

1.4.2 代码示例

定义混入 mixin.js

// 定义一个混入配置信息
// 说明:如果混入中配置的数据、方法,在组件中有同样的数据定义、方法名称,会加载组件中的数据和方法,混入中的数据和方法就不起作用
const mixin1 = {
data() {
return {
x: 200,
y: 100
}
},
methods: {
showName() {
alert(this.name)
}
},
}
// 说明:生命周期中的函数,如果混入、组件中都有配置的话,二者都会执行
const mixin2 = {
mounted() {
console.log("mixin 中的 mounted... ")
},
} export {
mixin1,
mixin2
}

在组件中使用混入:

<template>
<div>
<h2>学校名称: {{ name }}</h2>
<h2>学校地址: {{ address }}</h2>
<button @click="showName">点我提示信息</button>
</div>
</template> <script>
// 引入混入
import { mixin1 } from "@/mixin"; export default {
name: "School",
// 混入配置项
mixins: [mixin1],
data() {
return {
name: "北京大学",
address: "北京",
};
},
methods: {
// showName() {
// alert(this.name);
// },
},
};
</script>
<template>
<div>
<h2>学生姓名: {{ name }}</h2>
<h2>学生性别: {{ sex }}</h2>
<h2>学生年龄: {{ age }}</h2>
<button @click="showName">点我提示信息</button>
</div>
</template> <script>
// 引入混入
import { mixin1, mixin2 } from "../mixin";
export default {
name: "Student",
mixins: [mixin1, mixin2], data() {
return {
name: "张三",
sex: "男",
age: 20,
x: 1000,
};
},
methods: {
showName() {
console.log("student... ");
alert(this.name + "hello world");
},
},
mounted() {
console.log("student 中的 mounted... ");
},
};
</script>

1.5 插件

1.5.1 使用说明

  1. 功能:用于增强 Vue

  2. 本质:包含 install 方法的一个对象,install 的第一个参数是 Vue,第二个以后的参数是插件使用者传递的数据。

  3. 定义插件:

    对象.install = function (Vue, options) {
    // 1. 添加全局过滤器
    Vue.filter(....) // 2. 添加全局指令
    Vue.directive(....) // 3. 配置全局混入(合)
    Vue.mixin(....) // 4. 添加实例方法
    Vue.prototype.$myMethod = function () {...}
    Vue.prototype.$myProperty = xxxx
    }
  4. 使用插件:Vue.use()

1.5.2 代码示例

定义插件 plugins.js

export default {
install(Vue) {
console.log(Vue, "@@@@@"); // 全局定义过滤器
Vue.filter("strSlice", function (value) {
return value.slice(0, 4)
}) // 全局定义指令
Vue.directive("fbind", {
// 指令与元素成功绑定时 一上来
bind(element, binding) {
element.value = binding.value
},
// 指令所在元素插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在模板被重新解析时
updated(element, binding) {
element.value = binding.value
},
})
// 给 Vue 原型上添加一个方法 vm、vc 都能使用
Vue.prototype.hello = () => {
console.log("hello world ");
}
}, }

main.js 中使用插件

// 引入插件
import plugins from './plugins' // 使用插件
Vue.use(plugins)

1.6 scoped 样式

  1. 作用:让样式在局部生效,防止冲突。

  2. 写法:

    <style scoped>
    .demo {
    background-color: orange;
    // less 与 css 的一个区别就是 less 可以叠加写,css 不可以
    .title {
    font-size: 40px;
    }
    }
    </style>

1.7 组件化编码流程

  1. 组件化编码流程:

    1. 拆分静态组件:组件要按照功能点拆分,命名不要与 html 元素冲突。
    2. 实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
      1. 一个组件在用:放在组件自身即可。
      2. 一些组件在用:放在他们共同的父组件上(状态提升)。
      3. 实现交互:从绑定事件开始。
  2. props 适用于:
    1. 父组件 ==> 子组件 通信
    2. 子组件 ==> 父组件 通信(要求父先给子一个函数)
  3. 使用 v-model 时要切记:v-model 绑定的值不能是 props 传过来的值,因为 props 是不可以修改的!
  4. props 传过来的若是对象类型的值,修改对象中的属性时 Vue 不会报错,但不推荐这样做。

1.8 webStorage

1.8.1 使用说明

  1. 存储内容大小一般支持 5MB 左右(不同浏览器可能还不一样)

  2. 浏览器端通过 Window.sessionStorageWindow.localStorage 属性来实现本地存储机制

  3. 相关API:

    1. xxxxxStorage.setItem('key', 'value');

      该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值

    2. xxxxxStorage.getItem('person');

      ​该方法接受一个键名作为参数,返回键名对应的值

    3. xxxxxStorage.removeItem('key');

      ​该方法接受一个键名作为参数,并把该键名从存储中删除

    4. xxxxxStorage.clear()

      该方法会清空存储中的所有数据

  4. 备注:

    1. SessionStorage 存储的内容会随着浏览器窗口关闭而消失
    2. LocalStorage 存储的内容,需要手动清除才会消失
    3. xxxxxStorage.getItem(xxx) 如果 xxx 对应的 value 获取不到,那么 getItem 的返回值是 null
    4. JSON.parse(null) 的结果依然是 null

1.8.2 代码示例

LocalStorage

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>localStorage 浏览器本地存储</title>
</head>
<body>
<div>
<h2>localStorage 浏览器本地存储</h2>
<button onclick="save()">点我保存一个数据</button>
<button onclick="read()">点我读取一个数据</button>
<button onclick="remove()">点我删除一个数据</button>
<button onclick="clearAll()">点我清空数据</button>
</div> <script type="text/javascript">
let person = {name: "张三", age: 19} // localStorage 保存数据时最终都是 字符串
function save() {
// 保存字符串
localStorage.setItem("name", "张三")
// 保存数字
localStorage.setItem("age", 18)
// 保存对象数据
// localStorage.setItem("person", person)
localStorage.setItem("person", JSON.stringify(person))
} function read() {
// 读取字符串
console.log(localStorage.getItem("name"))
// 读取数字
console.log(localStorage.getItem("age"))
// 读取对象
console.log(localStorage.getItem("person"))
console.log(JSON.parse(localStorage.getItem("person")))
} function remove() {
// 删除字符串
localStorage.removeItem("name")
// 移除数字
localStorage.removeItem("age")
// 移除对象
localStorage.removeItem("person")
} function clearAll() {
console.log("clear...");
localStorage.clear()
}
</script>
</body>
</html>

SessionStorage

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sessionStorage 浏览器本地存储</title>
</head>
<body>
<div>
<h2>sessionStorage 浏览器本地存储</h2>
<button onclick="save()">点我保存一个数据</button>
<button onclick="read()">点我读取一个数据</button>
<button onclick="remove()">点我删除一个数据</button>
<button onclick="clearAll()">点我清空数据</button>
</div> <script type="text/javascript">
let person = {name: "张三", age: 19} // sessionStorage 保存数据时最终都是 字符串
function save() {
// 保存字符串
sessionStorage.setItem("name", "张三")
// 保存数字
sessionStorage.setItem("age", 18)
// 保存对象数据
// sessionStorage.setItem("person", person)
sessionStorage.setItem("person", JSON.stringify(person))
} function read() {
// 读取字符串
console.log(sessionStorage.getItem("name"))
// 读取数字
console.log(sessionStorage.getItem("age"))
// 读取对象
console.log(sessionStorage.getItem("person"))
console.log(JSON.parse(sessionStorage.getItem("person")))
} function remove() {
// 删除字符串
sessionStorage.removeItem("name")
// 移除数字
sessionStorage.removeItem("age")
// 移除对象
sessionStorage.removeItem("person")
} function clearAll() {
console.log("clear...");
sessionStorage.clear()
}
</script>
</body>
</html>

1.9 组件的自定义事件

1.9.1 使用说明

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A 是父组件,B 是子组件,B 想给 A 传数据,那么就要在 A 中给 B 绑定自定义事件(事件的回调在 A 中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:<Demo @helloWorld="test"/><Demo v-on:helloWorld="test"/>

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
      this.$refs.xxx.$on('helloWorld', this.test)
      }
    3. 若想让自定义事件只能触发一次,可以使用 once 修饰符,或 $once 方法。

  4. 触发自定义事件:this.$emit('helloWorld',数据)

  5. 解绑自定义事件this.$off('helloWorld')

  6. 组件上也可以绑定原生 DOM 事件,需要使用 native 修饰符。

  7. 注意:通过 this.$refs.xxx.$on('helloWorld',回调) 绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则 this 指向会出问题!

1.9.2 代码示例

父组件 App

<template>
<div id="app" class="app">
<h1>学校名称是:{{ schoolName }}</h1>
<h1>学生姓名是:{{ studentName }}</h1> <!-- 通过 props 来实现子组件给父组件传递数据 -->
<School :getSchoolName="getSchoolName" /> <!-- 第一种写法:通过父组件给子组件绑定一个自定义事件来实现子组件给父组件传递数据 使用 @ 或者 v-on -->
<!-- <Student @getStudentName="getStudentName" /> --> <!-- 第二种写法:通过父组件给子组件绑定一个自定义事件来实现子组件给父组件传递数据 使用 ref-->
<Student ref="student" /> <!-- 通过父组件给子组件绑定一个自定义事件来实现子组件给父组件传递数据,只触发一次 -->
<!-- <Student @getStudentName.once="getStudentName"/> -->
<!-- <Student ref="student" /> --> <!-- 使用组件原生的方法 -->
<!-- <Student @click.native="show" /> --> <!-- <Student @getStudentName="getStudentName" @getDemo="getDemo" /> -->
</div>
</template> <script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
components: { School, Student },
data() {
return {
schoolName: "",
studentName: "",
};
}, methods: {
// 接收 School 子组件传递来的数据
getSchoolName(name) {
console.log("App 组件收到了学校名称", name);
this.schoolName = name;
}, // 接收 Student 子组件传递来的数据
getStudentName(name) {
console.log("App 组件收到了学生姓名", name);
this.studentName = name;
}, // 接收多个数据
getDemo(...params) {
console.log(...params);
}, show() {
alert(123)
}
}, mounted() {
// 写法一
this.$refs.student.$on("getStudentName", (name) => {
// 普通函数写法 此时 this 是 VueComponent 实例 Student
// 箭头函数写法 此时 this 是 vm
console.log(this,"@@@", name);
this.studentName = name
})
// 写法二
// this.$refs.student.$on("getStudentName", this.getStudentName)
// this.$refs.student.$once("getStudentName", this.getStudentName)
},
};
</script> <style>
.app {
background-color: gray;
padding: 5px;
}
</style>

子组件 School

<template>
<div class="school">
<h2>学校名称: {{ name }}</h2>
<h2>学校地址: {{ address }}</h2>
<button @click="sendSchoolName">把学校名称给 App 组件</button>
</div>
</template> <script>
export default {
name: "School",
props: ["getSchoolName"],
data() {
return {
name: "北京大学",
address: "北京",
};
},
methods: {
sendSchoolName() {
this.getSchoolName(this.name);
},
},
};
</script> <style>
.school {
background-color: skyblue;
padding: 5px;
}
</style>

子组件 Student

<template>
<div class="student">
<h2>学生姓名: {{ name }}</h2>
<h2>学生性别: {{ sex }}</h2>
<h2>学生年龄: {{ age }}</h2>
<button @click="sendStudentName">把学生姓名给 App 组件</button>
<button @click="unbind">解绑自定义事件</button>
<button @click="death">销毁当前组件实例</button>
</div>
</template> <script>
// 引入混入
export default {
name: "Student", data() {
return {
name: "张三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 触发 student 组件实例的 getStudentName 事件
this.$emit("getStudentName", this.name);
this.$emit("getDemo", 1, 2, 3, 4);
},
// 解绑自定义事件
unbind() {
// 解绑一个自定义事件
// this.$off("getStudentName"); // 解绑多个自定义事件
this.$off(["getStudentName", "getDemo"]);
},
// 销毁当前组件实例
death() {
// 销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
this.$destroy()
}
},
};
</script> <style lang="less" scoped>
.student {
background-color: orange;
padding: 5px;
margin-top: 30px;
}
</style>

1.10 全局事件总线

1.10.1 使用说明

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 安装全局事件总线:

    new Vue({
    ......
    beforeCreate() {
    Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    },
    ......
    })
  3. 使用事件总线:

    1. 接收数据:A 组件想接收数据,则在 A 组件中给 $bus 绑定自定义事件,事件的回调留在 A 组件自身。

      methods(){
      demo(data){......}
      }
      ......
      mounted() {
      this.$bus.$on('xxxx',this.demo)
      }
    2. 提供数据:this.$bus.$emit('xxxx',数据)

  4. 最好在 beforeDestroy 钩子中,用 $off 去解绑当前组件所用到的事件。

1.10.2 代码示例

main.js 中安装全局事件总线

import Vue from 'vue'

import App from './App.vue'

Vue.config.productionTip = false

new Vue({
el: "#app",
render: h => h(App),
beforeCreate() {
// 安装全局事件总线
Vue.prototype.$bus = this
}
})

在组件 School 中挂载全局事件

<template>
<div class="demo">
<h2>学校名称: {{ name }}</h2>
<h2>学校地址: {{ address }}</h2>
</div>
</template> <script>
export default {
name: "School",
data() {
return {
name: "北大大学",
address: "北京",
};
},
methods: {},
// 在组件挂载时绑定一个事件
mounted() {
this.$bus.$on("getStudentName", (data) => {
// 此时 this 是 VueComponent 的实例 School
console.log(this);
console.log("School 组件收到了数据:", data);
});
},
// 在组件销毁前解绑事件
beforeDestroy() {
this.$bus.$off("getStudentName")
}
};
</script> <style>
.demo {
background-color: skyblue;
}
</style>

Student 组件中触发全局事件

<template>
<div class="demo">
<h2 class="title">学生姓名: {{ name }}</h2>
<h2>学生性别: {{ sex }}</h2>
<h2>学生年龄: {{ age }}</h2>
<button @click="sendStudentName">把学生名字给 School 组件</button>
</div>
</template> <script>
// 引入混入
export default {
name: "Student", data() {
return {
name: "张三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 触发事件
this.$bus.$emit("getStudentName", this.name)
}
},
};
</script> <!-- <style>
.demo {
background-color: orange;
}
</style> -->
<!-- 不指定,默认使用 css -->
<!-- scoped: 表示样式只对指定的组件起作用-->
<!-- <style scoped>
.demo {
background-color: orange;
}
</style> --> <!-- lang: 指定用什么样式 -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
.demo {
background-color: orange;
// less 与 css 的一个区别就是 less 可以叠加写,css 不可以
.title {
font-size: 40px;
}
}
</style>

1.11 消息订阅与发布

1.11.1 说明使用

  1. 一种组件间通信的方式,适用于任意组件间通信

  2. 它包含以下操作:

    1. 订阅消息--对应绑定事件监听
    2. 发布消息--分发事件
    3. 取消消息订阅--解绑事件监听
  3. PubSub.js

    1. 在线文档
    2. 安装:
    3. 相关语法:
      • import PubSub from 'pubsub-js' : 引入
      • PubSub.subscribe(‘msgName’, functon(msgName, data){}): 订阅
      • PubSub.publish(‘msgName’,data): 发布消息,触发订阅的回调函数调用
      • PubSub.unsubscribe(token): 取消消息的订阅
  4. 使用步骤:

    1. 安装 pubsubnpm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
      demo(data){......}
      }
      ......
      mounted() {
      this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在 beforeDestroy 钩子中,用 PubSub.unsubscribe(pid) 去取消订阅。

1.11.2 代码示例

School 组件订阅消息

<template>
<div class="demo">
<h2>学校名称: {{ name }}</h2>
<h2>学校地址: {{ address }}</h2>
</div>
</template> <script>
import pubsub from "pubsub-js";
export default {
name: "School",
data() {
return {
name: "北大大学",
address: "北京",
};
},
methods: {},
mounted() {
// 订阅消息
const pubId = pubsub.subscribe("sendStudentName", (messageName, data) => {
// 箭头函数写法 此时 this 是 VueComponent 实例 School
console.log(this);
console.log(messageName, data);
})
// pubsub.subscribe("sendStudentName", function (messageName, data) {
// // 普通函数写法,此时 this undefined
// console.log(this);
// console.log(messageName, data);
// });
},
beforeDestroy() {
// 取消订阅消息
// 取消订阅消息时要用 pubId 去取消订阅
pubsub.unsubscribe(this.pubId);
},
};
</script> <style>
.demo {
background-color: skyblue;
}
</style>

Student 组件消费消息

<template>
<div class="demo">
<h2 class="title">学生姓名: {{ name }}</h2>
<h2>学生性别: {{ sex }}</h2>
<h2>学生年龄: {{ age }}</h2>
<button @click="sendStudentName">把学生姓名给 School 组件</button>
</div>
</template> <script>
// 引入消息订阅
import pubsub from "pubsub-js";
export default {
name: "Student",
data() {
return {
name: "张三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 发布消息
// 第一个参数是消息名
pubsub.publish("sendStudentName", this.name);
},
},
};
</script> <!-- <style>
.demo {
background-color: orange;
}
</style> -->
<!-- 不指定,默认使用 css -->
<!-- scoped: 表示样式只对指定的组件起作用-->
<!-- <style scoped>
.demo {
background-color: orange;
}
</style> --> <!-- lang: 指定用什么样式 -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
.demo {
background-color: orange;
// less 与 css 的一个区别就是 less 可以叠加写,css 不可以
.title {
font-size: 40px;
}
}
</style>

1.12 nextTick

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次 DOM 更新结束后执行其指定的回调
  3. 什么时候用:当改变数据后,要基于更新后的新 DOM 进行某些操作时,要在 nextTick 所指定的回调函数中执行

1.13 过度与动画

1.13.1 使用说明

  1. 作用:在插入、更新或移除 DOM 元素时,在合适的时候给元素添加样式类名

  2. 写法:

    1. 准备好样式:

      • 元素进入的样式:

        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    2. 使用<transition>包裹要过度的元素,并配置 name 属性:

      <transition name="hello">
      <h1 v-show="isShow">你好啊!</h1>
      </transition>
    3. 备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定 key

1.13.2 代码示例

transition

<template>
<div>
<button @click="isShow = !isShow">显示/隐藏</button>
<!-- appear 表示页面一进来就进行动画效果 -->
<transition name="hello" appear>
<h1 v-show="isShow">Hello World</h1>
</transition>
</div>
</template> <script>
export default {
name: "Test1",
data() {
return {
isShow: true,
};
},
};
</script> <style scoped>
h1 {
background-color: orange;
} .hello-enter-active {
animation: helloWorld 0.5s linear;
} .hello-leave-active {
animation: helloWorld 0.5s linear reverse;
} @keyframes helloWorld {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>

transition-group

<template>
<div>
<button @click="isShow = !isShow">显示/隐藏</button>
<!-- appear 表示页面一进来就进行动画效果 -->
<!-- transition-group 包裹一组标签,需要指定 key -->
<transition-group name="hello" appear="">
<h1 v-show="isShow" key="1">Hello</h1>
<h1 v-show="isShow" key="2">World</h1>
</transition-group>
</div>
</template> <script>
export default {
name: "Test2",
data() {
return {
isShow: true,
};
},
};
</script> <style scoped>
h1 {
background-color: skyblue;
} /* 进入的起点,离开的终点 */
.hello-enter,
.hello-leave-to {
transform: translateX(-100%);
} .hello-enter-active,
.hello-leave-active {
transition: 0.5s linear;
} /* 离开的起点,进入的重点 */
.hello-leave,
.hello-enter-to {
transform: translateX(0);
}
</style>

使用第三方动画库 Animate.css

<template>
<div>
<button @click="isShow = !isShow">显示/隐藏</button>
<!-- 使用第三方动画库 -->
<transition-group
appear
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp"
>
<h1 v-show="isShow" key="1">Hello</h1>
<h1 v-show="isShow" key="2">World</h1>
</transition-group>
</div>
</template> <script>
// Animate.css 使用步骤
// 0.官网地址:https://animate.style/
// 1.安装:npm install animate.css --save
// 2.引入: import "animate.css"; import "animate.css";
export default {
name: "Test3",
data() {
return {
isShow: true,
};
},
};
</script> <style scoped>
h1 {
background-color: orange;
}
</style>

1.14 插槽

1.14.1 使用说明

  1. 作用:让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件

  2. 分类:默认插槽、具名插槽、作用域插槽

1.14.2 默认插槽

父组件

<Category>
<div>html结构1</div>
</Category>

子组件

<template>
<div>
<!-- 定义插槽 -->
<slot>插槽默认内容...</slot>
</div>
</template>

1.14.3 具名插槽

父组件中

<Category>
<template slot="center">
<div>html结构1</div>
</template> <template v-slot:footer>
<div>html结构2</div>
</template>
</Category>

子组件中

<template>
<div>
<!-- 定义插槽 -->
<slot name="center">插槽默认内容...</slot>
<slot name="footer">插槽默认内容...</slot>
</div>
</template>

1.14.4 作用域插槽

  1. 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games 数据在 Category 组件中,但使用数据所遍历出来的结构由 App 组件决定)

  2. 具体编码:

    父组件中

    <Category>
    <template scope="scopeData">
    <!-- 生成的是ul列表 -->
    <ul>
    <li v-for="g in scopeData.games" :key="g">{{g}}</li>
    </ul>
    </template>
    </Category> <Category>
    <template slot-scope="scopeData">
    <!-- 生成的是h4标题 -->
    <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
    </template>
    </Category>

    子组件

    <template>
    <div>
    <slot :games="games"></slot>
    </div>
    </template> <script>
    export default {
    name:'Category',
    props:['title'],
    //数据在子组件自身
    data() {
    return {
    games:['红色警戒','穿越火线','劲舞团','超级玛丽']
    }
    },
    }
    </script>

Vue 脚手架编程的更多相关文章

  1. VUE脚手架使用

    什么是vue脚手架?   他是一个快速构建vue项目的工具,通过他,我们可以将vue所需要的文件安装完成. vue-cli这个构建工具大大降低了webpack的使用难度,支持热更新,有webpack- ...

  2. 【vue系列之一】使用vue脚手架工具搭建vue-webpack项目

    对于Vue.js来说,如果你想要快速开始,那么只需要在你的html中引入一个<script>标签,加上CDN的地址即可.但是,这并不算是一个完整的vue实际应用.在实际应用中,我们必须要一 ...

  3. vue脚手架使用swiper /引入js文件/引入css文件

    1.安装vue-cli 参考地址:https://github.com/vuejs/vue-cli 如果不使用严格语法需要在后三项打no:(加了挺头疼的,老是报错,但是对自己的代码规范性也是有很大的帮 ...

  4. 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)

    一.Vue的实例 1.1.创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 虽然没有完全遵循 ...

  5. Vue脚手架(vue-cli)安装总结

    单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序. 提供一 ...

  6. Vue脚手架搭建项目

    全局安装vue脚手架 $ npm install -g vue-cli 卸载方法 $ npm uninstall -g vue-cli 查看vue版本(注意:大写的V) $ vue -V 创建项目 $ ...

  7. npm——安装教程、安装vue脚手架

    npm:是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题.比如常用的有: 1)允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2)允许用户从NPM服务器下载并安 ...

  8. 用vue脚手架创建bootstrap-vue项目

    用vue脚手架创建bootstrap-vue项目 框架的地址:https://bootstrap-vue.js.org/docs/ 第一步 vue init webpack demo第二步 cd de ...

  9. 搭建vue脚手架---vue-cli

    vue-cli作为一款mvvm框架语言(vue)的脚手架,集成了webpack环境及主要依赖,对于项目的搭建.打包.维护管理等都非常方便快捷.我们在开发项目时尤其需要这样一个快速构建项目的工具. 以下 ...

  10. Vue脚手架使用步骤 2.9.6版本

    转载自:https://blog.csdn.net/sky_LQ/article/details/80729547 Vue脚手架使用步骤 2018年06月19日 12:10:35 sky_LQ 阅读数 ...

随机推荐

  1. SQL注入三连实战绕过WTS-WAF

    一键三连,sql注入 一次无意之间发现的sql注入,主要是因为有一个WTS-WAF,在此记录一下 只是友好测试,并非有意为之.... 牛刀小试1 手注 判断字段数 测试到order by 15的时候出 ...

  2. JuiceFS 社区版 v1.1- Beta 发布,新增五个实用功能

    我们很高兴地宣布 JuiceFS v1.1-Beta 版本正式发布啦!这是一个功能丰富的版本,带来了许多实用的新功能和改进.在这个版本中我们新增了以下功能: 目录配额:为目录设置配额限制,控制其大小和 ...

  3. Java 实战介绍 Cookie 和 Session 的区别

    HTTP 是一种不保存状态的协议,即无状态协议,HTTP 协议不会保存请求和响应之间的通信状态,协议对于发送过的请求和响应都不会做持久化处理. 无状态协议减少了对服务压力,如果一个服务器需要处理百万级 ...

  4. 【AGC】云监控日志服务查询不到Logger日志相关问题2

    ​[关键字] AGC.云监控.日志服务 [问题描述] 之前有开发者反馈在使用AGC云监控,填写了Logger日志,但是在云监控的日志服务查不到的问题.具体如下所述: 云函数按要求写了Logger日志, ...

  5. WPF 入门笔记 - 05 - 依赖属性

    如果预计中的不幸没有发生的话,我们就会收获意外的喜悦. --人生的智慧 - 叔本华 WPF属性系统 这一部分是中途加的,直接依赖属性有点迷糊,正好有了绑定的基础,理解起来还一些. WPF提供一组服务, ...

  6. Gamma:强大的AI制作PPT神器,用完再也回不去了!

    看过许多 AI 制作 PPT 软件,最终还是被 Gamma 惊艳到. Gamma 是一款基于人工智能技术的 PPT 制作工具,可以帮助用户轻松制作高质量的 PPT 演示文稿. 痛点解决 相比传统制作 ...

  7. 获取邮箱(QQ、126、163)的客户端授权码

    获取QQ邮箱的客户端授权码 1.首先登录QQ邮箱(https://mail.qq.com),然后,点击"设置"按钮. 2.点击"账户"按钮,进入"账户 ...

  8. DevOps|从腾讯TEG CDC解散聊技术中台价值和建设

    近日一则腾讯TEG CDC整个部门解散的消息在很多群里炸了锅,有的唱衰互联网行业,有的唉声叹气,还有的甩锅到 AGI 的发展.总体上来说,这个事情的确已经发生了,我想从组织架构和整体效能这两方面来分析 ...

  9. 使用C#编写.NET分析器(三)

    译者注 这是在Datadog公司任职的Kevin Gosse大佬使用C#编写.NET分析器的系列文章之一,在国内只有很少很少的人了解和研究.NET分析器,它常被用于APM(应用性能诊断).IDE.诊断 ...

  10. java使用SFTP连接服务器下载,上传文件

    package mocha.framework.util; /* * @author Xiehj * @version 2019年10月28日 上午9:37:28 */ import java.io. ...