前言· vue-cli脚手架的的好处
-
脚手架可以大大提高开发效率;
-
可以使用主流的ECMAScript语法;
-
通过Webpack实现编译查看效果(非浏览器编译);
-
自动更新,可实时查看最新效果;
1、安装vue-cli和创建项目
安装vue-cli:
全局安装: npm install -g @vue/cli
创建项目:
-
1、vue create [project name]
-
2、手动选择配置(Manually select features)
-
3、(babel) 转换语法
-
4、选择依赖包的文件 (package.json) 用来管理项目中所用到的文件
-
5、是否保存你要配置的模版(no)
-
6、安装中···
-
7、进入文件夹:cd vuecli-demo 启动项目:npm run serve
2、目录介绍
# vuecli-demo
## Project setup
安装项目依赖包
npm install
### Compiles and hot-reloads for development
启动当前项目
npm run serve
### Compiles and minifies for production
对当前的项目进行打包
npm run build
-
package.json
{
"name": "vuecli-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve", //启动
"build": "vue-cli-service build" //打包
},
"dependencies": { //依赖的插件
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": { //依赖的插件
"[@vue](/user/vue)/cli-plugin-babel": "~4.4.0",
"[@vue](/user/vue)/cli-service": "~4.4.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
-
babel.config.js
//此文件对最新的es6·· 语法转换 本文件用来编译成浏览器识别的语法
module.exports = {
presets: [
'[@vue](/user/vue)/cli-plugin-babel/preset'
]
}
-
.gitignore
上传github仓库里面时,用来过滤或者忽略某些文件
-
/public/index.html
主入口文件
<div id="app"></div>
-
/src文件
/src/assets 用来存放静态文件
/src/components 用来组件
App.vue 根组件 最顶级的组件
main.js 是我们逻辑的入口文件
程序识别顺序
index.html => main.js =>App.vue
3、组件嵌套
-
先来一个子组件 User.vue
<template>
<div class="users">
<ul>
<li v-for="(user,index) in users" :key="index">{{user}}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
users: ["路飞", "香吉士", "索罗"]
};
}
};
</script>
<style scoped>
</style
(1)、注册全局组件
一定是在main.js里面, 这是我们逻辑入口文件。 全局注册的组件 ,在任何地方都可以使用。
import Vue from 'vue'
import App from './App.vue'
//注册全局组件在main.js ,在任何地方都可以使用该组件
// 首先第一步引入组件
import User from './components/User'
//2、注册全局组件
Vue.component('users', User);
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
然后我们的父组件 直接引用 <users />
<template>
<div id="app">
<!-- 调用组件 -->
<users />
</div>
</template>
<script>
export default {
name: "App",
components: {
}
};
</script>
<style>
#app {
}
</style>
(2)、注册局部组件
<template>
<div id="app">
<users />
</div>
</template>
<script>
//局部注册和引用组件
//引入组件
import users from "./components/User";
export default {
name: "App",
components: {
//注册组件
users
}
};
</script>
<style>
#app {
}
</style>
4、组件css样式
- style 加上scoped 就说明此样式作用在本组件中
<style scoped>
h1 {
color: green;
}
</style>
5、组件属性传值
- (1)父传子 propos
父组件 App.vue
<template>
<div id="app">
<Header />
<h1>App.vue</h1>
<users :Users="users" />
<Footer />
</div>
</template>
<script>
//局部注册和引用组件
//引入组件
import users from "./components/User";
import Header from "./components/Header";
import Footer from "./components/Footer";
export default {
name: "App",
components: {
//注册组件
users,
Header,
Footer
},
data() {
return {
users: [
{ name: "yaobinggt1", wechat: "492413983", show: false },
{ name: "yaobinggt2", wechat: "492413983", show: true },
{ name: "yaobinggt3", wechat: "492413983", show: false },
{ name: "yaobinggt4", wechat: "492413983", show: false },
{ name: "yaobinggt5", wechat: "492413983", show: true },
{ name: "yaobinggt6", wechat: "492413983", show: true }
]
};
}
};
</script>
子组件 User.vue
<template>
<div class="users">
<h1>User.vue</h1>
<ul>
<li @click="user.show=!user.show" v-for="(user,index) in Users" :key="index">
<h2>{{user.name}}</h2>
<p v-show="user.show">{{user.wechat}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
//props: ["Users"],
props: {
Users: {
type: Array,
required: true
}
},
data() {
return {};
}
};
</script>
- (2)传值和传引用
属性传值:值有两种情况: 1.传值 2、引用(对象、数组)
App.vue
<template>
<div id="app">
<Header :title="title" />
<h1>App.vue</h1>
<!-- 属性传值:值有两种情况: 1.传值 2、引用(对象、数组) -->
<users :Users="users" />
<br />
<users :Users="users" />
<Footer :title="title" />
</div>
</template>
<script>
//局部注册和引用组件
//引入组件
import users from "./components/User";
import Header from "./components/Header";
import Footer from "./components/Footer";
export default {
name: "App",
components: {
//注册组件
users,
Header,
Footer
},
data() {
return {
users: [
{ name: "yaobinggt1", wechat: "492413983", show: false },
{ name: "yaobinggt2", wechat: "492413983", show: true },
{ name: "yaobinggt3", wechat: "492413983", show: false },
{ name: "yaobinggt4", wechat: "492413983", show: false },
{ name: "yaobinggt5", wechat: "492413983", show: true },
{ name: "yaobinggt6", wechat: "492413983", show: true }
],
title: "Vue yaobinggt"
};
}
};
</script>
User.vue
<template>
<div class="users">
<ul>
<li @click="user.show=!user.show" v-for="(user,index) in Users" :key="index">
<h2>{{user.name}}</h2>
<p v-show="user.show">{{user.wechat}}</p>
</li>
</ul>
<!-- 传引用 -->
<button @click="deleteUser">deleteUser</button>
</div>
</template>
<script>
export default {
//props: ["Users"],
props: {
Users: {
type: Array,
required: true
}
},
data() {
return {};
},
methods: {
deleteUser() {
this.Users.pop(); //pop() 方法用于删除并返回数组的最后一个元素。
}
}
};
</script>
Header.vue
<template>
<div class="header" @click="changeTitle">
<h1>{{title}}</h1>
</div>
</template>
<script>
export default {
props: {
title: {
type: String
}
},
data() {
return {
title: " vue component demo"
};
},
methods: {
changeTitle() {
this.title = "yaoUU 好好学习";
}
}
};
</script>
- (3)子传父
子组件想要修改父组件的东西的话,必须通过事件的方式,而这个事件使我们要自己注册的,再让对应的地方进行一个调用;
要修改对应数据,就要到对应的组件里面进行修改(虽然在子组件里面进行操作,并成功了但是这并不允许);
<template>
<div id="app">
<Header @titleChange="updateTitle" :title="title" />
<h1>App.vue</h1>
<!-- 属性传值:值有两种情况: 1.传值 2、引用(对象、数组) -->
<users :Users="users" />
<br />
<users :Users="users" />
<Footer :title="title" />
</div>
</template>
<script>
//局部注册和引用组件
//引入组件
import users from "./components/User";
import Header from "./components/Header";
import Footer from "./components/Footer";
export default {
name: "App",
components: {
//注册组件
users,
Header,
Footer
},
data() {
return {
users: [
{ name: "yaobinggt1", wechat: "492413983", show: false },
{ name: "yaobinggt2", wechat: "492413983", show: true },
{ name: "yaobinggt3", wechat: "492413983", show: false },
{ name: "yaobinggt4", wechat: "492413983", show: false },
{ name: "yaobinggt5", wechat: "492413983", show: true },
{ name: "yaobinggt6", wechat: "492413983", show: true }
],
title: "Vue yaobinggt"
};
},
methods: {
updateTitle(updateTitledTitle) {
//console.log(updateTitledTitle);
this.title = updateTitledTitle;
}
}
};
</script>
<template>
<div class="header" @click="changeTitle">
<h1>{{title}}</h1>
</div>
</template>
<script>
export default {
props: {
title: {
type: String
}
},
data() {
return {
//title: " vue component demo"
};
},
methods: {
changeTitle() {
//this.title 不能这样强行进行修改
//this.title = "yaoUU 好好学习";
//this.$emit 表示我要开始注册事件了
//$emit(参数1:事件名称,参数2:对应修改的值 ,)
this.$emit("titleChange", "yaobinggt通过emit到App.vue修改了title值");
}
}
};
</script>
6、生命周期
//生命周期函数
beforeCreate() {
alert("这个时候实例还没有被创建,所以你无法知道data,也无法用watch监听");
},
created() {
alert("这时实例已经创建,可以得到data,调用watch监听,但是页面还是空白的");
},
beforeMount() {
alert("页面挂载前。此页面依然是空白的。这时render函数首次被调用。");
},
mounted() {
alert("页面已挂载,可以看到页面的内容,也可以访问dom");
},
beforeUpdate() {
alert("数据更新前,也就是虚拟DOM打补丁之前。这时访问的DOM还有原有的DOM");
},
updated() {
alert("数据已经更新完毕");
},
beforeDestroy() {
alert("页面离开之前被调用,这里可以清楚定时器,或者三方的一些DOM结构");
},
destroyed() {
alert("实例已经完全被销毁");
}
7、slot 插槽
什么是插槽?
- 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
- 插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
父组件
<template>
<div id="app">
<FormHelper>
<!-- 标签在哪里属性传值就在那里 -->
<h2 slot="hh2">{{title}}</h2>
<p slot="ppp">yaobinggtyaobinggtyaobinggtyaobinggtyaobinggt</p>
</FormHelper>
</div>
</template>
<script>
import FormHelper from "./components/FormHelper";
export default {
name: "App",
components: {
FormHelper
},
data() {
return {
title: "this is yao title"
};
},
methods: {}
};
</script>
子组件
<template>
<div>
<slot name="hh2"></slot>
<h1>2020年7月8日11时25分,高考文科综合/理科综合科目考试将要结束时,平顶山市一中考点一考生突然情绪失控,先后抓其右边、后边考生答题卡,造成两位考生答题卡损毁。考场两位监考教师及时制止,并稳定了考场秩序,市一中考点按程序启用备用答题卡,按规定补足答题卡被损毁的两位考生耽误的考试时间,两位考生将损毁卡的内容誊写在新答题卡上。</h1>
<slot name="ppp"></slot>
</div>
</template>
<script>
export default {
data() {
return {
//title: "this is yao title"
};
}
};
</script>
8、动态组件和缓存
(1)component 动态组件
渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。
(2)keep-alive 缓存
<keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
App.vue
<template>
<div id="app">
<keep-alive>
<component :is="component"></component>
</keep-alive>
<!-- <form-one />
<form-two />-->
<button @click="component='form-one'">show form one</button>
<button @click="component='form-two'">show form two</button>
</div>
</template>
<script>
import FormOne from "./components/FormOne";
import FormTwo from "./components/FormTwo";
export default {
name: "App",
components: {
"form-one": FormOne,
"form-two": FormTwo
},
data() {
return {
component: "form-one"
};
},
methods: {}
};
</script>
<style scoped>
h1 {
color: purple;
}
</style>
FormHelper
<template>
<div>
<h1>填充一下表单内容</h1>
<form>
<div id="form-header">
<slot name="form-header"></slot>
</div>
<div id="form-fields">
<slot name="form-fields"></slot>
</div>
<div id="form-controls">
<slot name="form-controls"></slot>
</div>
<div id="useful-links">
<ul>
<li>
<a href="#">link 1</a>
</li>
<li>
<a href="#">link 2</a>
</li>
</ul>
</div>
</form>
</div>
</template>
<script>
export default {
components: {},
data() {
return {};
},
methods: {}
};
</script>
<style scoped>
h1 {
text-align: center;
}
form {
width: 100%;
max-width: 960px;
margin: 0 auto;
}
#userful-links ul {
padding: 0;
}
#userful-links li {
display: inline-block;
margin-right: 10px;
}
form > div {
padding: 20px;
background: #eee;
margin: 20px 0;
}
#form-header {
background: #dddddd;
border: solid 1px #bbb;
}
</style>
form -two
<template>
<div>
<form-helper>
<div slot="form-header">
<h3>Form One - Contact Us</h3>
<p>填写一下内容</p>
</div>
<div slot="form-fields">
<input type="text" placeholder="name" required />
<label>随便说点啥</label>
<textarea></textarea>
</div>
<div slot="form-controls">
<button @click="handleSubmit">发送</button>
</div>
</form-helper>
</div>
</template>
<script>
import formHelper from "./FormHelper";
export default {
components: {
"form-helper": formHelper
},
data() {
return {};
},
methods: {
handleSubmit() {
alert("thanks for submitting form one & contacting us");
}
}
};
</script>
<style scoped>
body {
margin: 0;
font-family: "Nunito SemiBold";
}
</style>
form -two
<template>
<div>
<form-helper>
<div slot="form-header">
<h3>Form Two - Login</h3>
<p>随便写点啥</p>
</div>
<div slot="form-fields">
<input type="text" placeholder="username" required />
<input type="password" placeholder="password" required />
</div>
<div slot="form-controls">
<button @click="handleSubmit">发送</button>
</div>
</form-helper>
</div>
</template>
<script>
import formHelper from "./FormHelper";
export default {
components: {
"form-helper": formHelper
},
data() {
return {};
},
methods: {
handleSubmit() {
alert("thanks for login (form two)");
}
}
};
</script>
<style scoped>
body {
margin: 0;
font-family: "Nunito SemiBold";
}
</style>
```<p style="line-height: 20px; color: #ccc">
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者: yaobinggt
原文链接:<a href='https://juejin.im/post/6847902225033854990'>https://juejin.im/post/6847902225033854990</a>
</p>