my-app/
|- node_modules/ # 依赖库
|- public/ # 公共资源
| |- index.html # 应用程序的主 HTML 文件
| |- favicon.ico # 网站图标
|- src/ # 源代码
| |- assets/ # 静态资源(图片、样式表等)
| |- components/ # 组件
| |- views/ # 页面级别组件
| |- App.vue # 根 Vue 组件
| |- main.js # 主 JavaScript 文件
|- tests/ # 测试文件
|- .gitignore # Git 忽略配置文件
|- babel.config.js # Babel 编译器配置文件
|- package.json # 项目元数据和依赖信息
|- README.md # 项目文档
上述文件结构是一个典型的 Vue.js 项目的文件结构示例,其中包含了以下重要目录和文件:
这是一个常见的示例,实际的脚手架文件结构可能因具体的脚手架工具和项目需求而有所差异。
npm install -g @vue/cli
vue create xxx
npm run serv
备注:
如出现下载缓慢请配置 npm 淘宝镜像:npm config set registry https://registry.npm.taobao.org
.....
或
School.vue组件
<template>
<div class="demo">
<h2>学校名称:{{name}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
export default {
name:"School",
data() {
return {
name:"大学",
address:"四川"
}
},
}
script>
<style>
.demo{
background-color: gray;
}
style>
App.vue
<template>
<div>
<h1 ref="title">hello,{{name}}h1>
<button ref="btn" @click="showDom">点我输出上方的DOM元素button>
<School ref="sch">School>
div>
template>
<script>
import School from './components/School.vue'
export default {
name:"App",
components:{School},
data() {
return {
name:"蓝朽",
}
},
methods: {
showDom(){
console.log(this.$refs.title);//真实dom元素
console.log(this.$refs.btn);//真实dom元素
console.log(this.$refs.sch);//School的vc实例对象
}
},
}
script>
main.js
import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip=false;
new Vue({
el:"#app",
render:h=>h(App)
})
npm run serve 运行
这里示范了一下简单使用,在脚手架中使用的都是单文件组件。
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
<template>
<div>
<h1>hello,{{msg}}h1>
<h2>学生姓名:{{name}}h2>
<h2>学生性别:{{sex}}h2>
<h2>学生年龄:{{MyAge}}h2>
<button @click="MyAge++">点我年龄自增button>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
msg:"蓝朽",
MyAge:this.age
}
},
//简单声明接收
// props:['name','sex','age']
//接收的同时对类型进行限制,对不上控制台会报错
// props:{
// name:String,
// age:Number,
// sex:String
// }
//接收的同时对类型进行限制+必要值的设置+默认值设置
props:{
name:{
type:String, //name的类型
required:true //name属性必须传
},
age:{
type:Number,
default:90//默认值90
},
sex:{
type:String,
required:true
}
}
}
script>
通过
传值
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混合:
{
data(){....},
methods:{....}
....
}
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
定义mixin.js混合
import Vue from 'vue'
export const hunhe1 = {
methods: {
showName(){
alert(this.name);
}
}
}
export const hunhe2 = {
data(){
return {
x:100,
y:200
}
}
}
main.js全局混入
import Vue from "vue"
import App from "./App.vue"
import { hunhe1,hunhe2 } from "./mixin";
Vue.config.productionTip=false;
Vue.mixin(hunhe1,hunhe2)
new Vue({
el:"#app",
render:h=>h(App)
})
Student组件局部混入
<template>
<div>
<h2 @click="showName()">学生姓名:{{name}}h2>
<h2>学生性别:{{sex}}h2>
div>
template>
<script>
import { hunhe1, hunhe2 } from '@/mixin';
export default {
name:"Student",
data() {
return{
name:"蓝朽",
sex:"男"
}
},
mixins:[hunhe1,hunhe2]
}
script>
对象.install = function (Vue, options) {
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = xxxx
}
Vue.use()
定义插件
export default{
install(Vue,x,y,z){
console.log(Vue,x,y,z)
//全局过滤器
Vue.filter('mySlice',function(value) {
return value.slice(0,4);
})
}
}
使用插件
import Vue from "vue"
import App from "./App.vue"
//应用插件
import plugins from './plugins'
Vue.use(plugins,1,2,3)
Vue.config.productionTip=false;
new Vue({
el:"#app",
render:h=>h(App)
})
School组件
<template>
<div>
<h2>学校名称:{{name | mySlice}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
name:"b站大学hello world",
address:"四川"
}
}
}
script>
<template>
<div class="demo">
<h2>学校名称:{{name}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
name:"b站大学",
address:"四川"
}
}
}
script>
<style scoped>
.demo{
background-color: blue;
}
style>
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>Documenttitle>
head>
<body>
<h1>LocalStorageh1>
<button onclick="saveData()">点我保存数据button>
<button onclick="readData()">点我读取数据button>
<button onclick="deleteData()">点我删除数据button>
<button onclick="deleteAllData()">点我清空数据button>
<script>
let p = {name:"zhangsan",age:18}
function saveData() {
localStorage.setItem('msg','hello localstorage');
localStorage.setItem('person',JSON.stringify(p))
}
function readData() {
const res = localStorage.getItem('person')
console.log(JSON.parse(res))
}
function deleteData() {
localStorage.removeItem('msg')
}
function deleteAllData() {
localStorage.clear()
}
script>
body>
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>Documenttitle>
head>
<body>
<h1>sessionStorageh1>
<button onclick="saveData()">点我保存数据button>
<button onclick="readData()">点我读取数据button>
<button onclick="deleteData()">点我删除数据button>
<button onclick="deleteAllData()">点我清空数据button>
<script>
let p = {name:"zhangsan",age:18}
function saveData() {
sessionStorage.setItem('msg','hello localstorage');
sessionStorage.setItem('person',JSON.stringify(p))
}
function readData() {
const res = sessionStorage.getItem('person')
console.log(JSON.parse(res))
}
function deleteData() {
sessionStorage.removeItem('msg')
}
function deleteAllData() {
sessionStorage.clear()
}
script>
body>
html>
......
mounted(){
this.$refs.xxx.$on('lx',this.test)
}
App.vue
<template>
<div class="app">
<h1>{{msg}},{{studentName}}h1>
<School :getSchoolName="getSchoolName"/>
<Student v-on:lxwork="getStudentName" @demo="m1" @click.native="show"/>
div>
template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {
name:"App",
components:{Student,School},
data() {
return {
msg:'你好啊!',
studentName:''
}
},
methods: {
getSchoolName(name){
console.log("组件App收到了学校名:"+name)
},
getStudentName(name,...params){
console.log("组件App收到了学生名:"+name,params)
this.studentName = name
},
m1(){
console.log('demo事件被触发了')
},
show(){
alert(1123)
}
},
mounted() {
//绑定自定义事件
// this.$refs.student.$on('lxwork',this.getStudentName)
//绑定自定义事件,只被触发一次
// this.$refs.student.$once('lxwork',this.getStudentName)
},
}
script>
<style>
.app{
background-color: gray;
padding: 5px;
}
style>
Student.vue
<template>
<div class="demo">
<h2>学生姓名:{{name}}h2>
<h2 class="text">学生性别:{{sex}}h2>
<button @click="sendStudentName">把学校名给App组件button>
<button v-on:click="unbind">点我解绑lxwork事件button>
<button @click="death">销毁当前Student组件的实例(vc)button>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
name:"蓝朽",
sex:"男"
}
},
methods: {
sendStudentName(){
//触发Student组件实例身上的lxwork事件
this.$emit('lxwork',this.name,1,2,3)
this.$emit('demo')
},
unbind(){
// this.$off('lxwork')//解绑一个自定义事件
// this.$off(['lxwork','demo'])//解绑多个自定义事件
this.$off()//解绑所有自定义事件
},
death(){
this.$destroy()//销毁了当前Student组件的实例
//销毁后所有Student实例的自定义事件全都不奏效。
}
},
}
script>
<style scoped lang="less">
.demo{
background-color: orange;
padding: 5px;
margin-top: 30px;
.text{
font-family: 楷体;
}
}
style>
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
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//安装全局事件总线,在Vue的原型上面添加$bus属性
},
})
Student组件给School组件发送消息
School组件
<template>
<div class="demo">
<h2>学校名称:{{name}}h2>
<h2>学校地址:{{address}}h2>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
name:"b站大学",
address:"四川"
}
},
mounted() {
//绑定事件
this.$bus.$on('hello',(data)=>{
console.log("我是school组件:"+data)
})
},
beforeDestroy(){
//销毁事件
this.$bus.$off('hello')
}
}
script>
<style scoped>
.demo{
background-color: blue;
padding: 5px;
}
style>
Student组件
<template>
<div class="demo">
<h2>学生姓名:{{name}}h2>
<h2 class="text">学生性别:{{sex}}h2>
<button @click="sendStudentName">把学生名给School组件button>
div>
template>
<script>
export default {
name:"Student",
data() {
return{
name:"蓝朽",
sex:"男"
}
},
methods: {
sendStudentName(){
//触发hello事件
this.$bus.$emit('hello',this.name);
}
},
}
script>
<style scoped lang="less">
.demo{
background-color: orange;
padding: 5px;
margin-top: 30px;
.text{
font-family: 楷体;
}
}
style>
//编辑
handleEdit(todo){
if (todo.hasOwnProperty('isEdit')) {
todo.isEdit = true
} else {
this.$set(todo,'isEdit',true)
}
// todo.isEdit=true;
this.$nextTick(function() {
//获取焦点,也可以用setTimeout实现
this.$refs.inputTitle.focus()
})
},
作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。
写法:
包裹要过度的元素,并配置name属性:
你好啊!
<template>
<div>
<button @click="isShow=!isShow">显示/隐藏button>
<transition name="hello" :appear="true">
<h1 v-show="isShow" class="come">你好啊!h1>
transition>
div>
template>
<script>
export default {
name:'Test',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
.hello-enter-active{
animation: Mytest 1s linear;
}
.hello-leave-active{
animation:Mytest 1s linear reverse;
}
@keyframes Mytest {
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}
style>
多元素过渡
<template>
<div>
<button @click="isShow=!isShow">显示/隐藏button>
<transition-group name="hello" :appear="true">
<h1 v-show="isShow" class="come" key="1">你好啊!h1>
<h1 v-show="isShow" class="come" key="2">蓝朽h1>
transition-group>
div>
template>
<script>
export default {
name:'Test2',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
/* 利用过渡实现 */
/*进入的起点,离开的终点*/
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
transition: 1s linear;
}
/*进入的终点,离开的起点*/
.hello-enter-to,.hello-leave{
transform: translateX(0);
}
style>
使用第三方动画
<template>
<div>
<button @click="isShow=!isShow">显示/隐藏button>
<transition-group
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp"
appear
>
<h1 v-show="isShow" class="come" key="1">你好啊!h1>
<h1 v-show="isShow" class="come" key="2">蓝朽h1>
transition-group>
div>
template>
<script>
import 'animate.css'
export default {
name:'Test3',
data() {
return {
isShow:true
}
},
}
script>
<style scoped>
h1{
background-color: orange;
}
style>