使用Vue脚手架
下载node.js
安装nodejs的目录不能有中文以及空格
检查node版本:node -v
全局安装cnpm工具
npm install-g cnpm --registry=https://registry.npm.taobao.org
安装vue-cli脚手架(最新版本)
//全局安装
npm install -g @vue/cli
创建项目
vue create 项目名
选择vue版本
第三行是自定义(新手不建议),回车确定
启动服务
npm run sreve
成功启动页面
这样就成功使用vue脚手架创建了一个项目(它自己默认的简单项目)
分析脚手架
|-- node_modules 放置node模块
|-- public
| |__ favicon.ico 页签图标
| |__ index.html 主页面
|-- src 项目源码
| |-- asserts 存放静态资源(图片等)
| |-- component 存放组件
| | |__HelloWorld.vue
| |-- App.vue 所有组件的父组件
| |-- main.js 入口文件
|-- .gitignore git版本管制忽略的配置
|-- babel.config.js babel的配置文件
|-- package-lock.json 包版本控制文件
|-- package.json 应用宝配置文件
|-- READEME.md 应用描述文件
|-- vue.config.js 配置文件
index.html文件
-
让ie浏览器以最高的渲染级别渲染页面
-
<%= BASE_URL %> public文件夹
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<!-- 让ie浏览器以最高的渲染级别渲染页面 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- <%= BASE_URL %> public文件夹 -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!-- 当浏览器不支持js时 这个标签里面的html会被渲染 -->
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<!-- 容器 -->
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.js文件
在我们引入vue时,它的文件是vue.runtime.xxx.js,不是vue.js,所以需要使用render函数,即模板解析器。
- vue.js和vue.runtime.xxx.js的区别:
- vue.js是完整的Vue: 核心功能 + 模板解析器
- vue.runtime.xxx.js是运行版的vue: 核心功能
- vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容
// 该文件是整个项目的入口文件
//引入Vue
import Vue from 'vue'
//引入App组件 是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false
//创建vue实例对象
new Vue({
//将App组件放入容器中
render: h => h(App) ,
}).$mount('#app')
vue.config.js文件
使用vue inspect > output.js 命令可以查看到Vue脚手架的默认配置。
使用vue.config.jsi可以对脚手架进行个性化定制,详情见官网。
ref属性
- 被用来给元素或子组件注册引用信息(id的替代者)
- 应用在html标签上获取的是真实的DOM元素,应用在组件标签上是组件实例对象(vc)
- 使用方式:
- 打标识:
<h1 ref="xxx">...<h1> 或 <School ref="xxx"></School>
- 获取:this.$refs.xxx
- 打标识:
案例:App.vue
<template>
<div>
<h1 v-text="msg" ref="title"></h1>
<button ref="btn" @click="showDom">点我输出上方的DOM元素</button>
<School ref="sch"></School>
</div>
</template>
<script>
//引入School组件
import School from './components/School'
export default {
name:'App',
components:{School},
data() {
return {
msg:'好好学习'
}
},
methods: {
showDom() {
console.log(this.$refs.title);
console.log(this.$refs.btn);
console.log(this.$refs.sch);
}
}
}
</script>
props配置
-
让组件接收外部传过来的数据
-
传递数据:
-
接收数据:
-
只接收:props:[‘name’]
-
限制类型:props:{name:String}
-
限制类型、限制必要性、指定默认值“
props:{ name:{ typeString, //类型 required:true,//必要性 default:'007'//默认值 } }
props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告。若业务确实需要修改,那么请复制props的内容到data中一份,然后修改data中的数据。
-
案例:Student.vue
<template>
<div>
<h1>{{msg}}</h1>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{myAge+1}}</h2>
<button @click="updateAge">尝试修改收到的年龄</button>
</div>
</template>
<script>
export default {
name:'Student',
data() {
console.log(this)
return {
msg:'我是一个尚硅谷的学生',
myAge:this.age
}
},
methods: {
updateAge(){
this.myAge++
}
},
//简单声明接收
// props:['name','age','sex']
//接收的同时对数据进行类型限制
/* props:{
name:String,
age:Number,
sex:String
} */
//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
props:{
name:{
type:String, //name的类型是字符串
required:true, //name是必要的
},
age:{
type:Number,
default:99 //默认值
},
sex:{
type:String,
required:true
}
}
}
</script>
mixin(混入)属性
-
可以把多个组件共用的配置提取成一个混入对象、
-
使用方式:
-
定义混入
{ data(){}, methods:{}, ... }
-
使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:[‘xxx’]
-
案例:
mix.js 定义了两个混入方法
export const hunhe = {
methods:{
showName(){
alert(this.name)
}
},
mounted() {
console.log('你好啊!')
}
}
export const hunhe2 = {
data() {
return {
x:200,
y:499
}
},
}
main.js 全局混入
//引入混入属性
import {hunhe,hunhe2} from './mixin'
//使用混入
Vue.mixin(hunhe)
Vue.mixin(hunhe2)
Student.vue
<template>
<div>
<h2@click="showName'">学生姓名:{{name}</h2>
<h2>学生性别:{{sex}</h2>
</div>
</template>
<script>
//1、引入混入
//import {hunhe,hunhe2}from '../mixin'
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男'
}
},
/2、使用局部混入
//mixins:[hunhe,hunhe2]
}
</script>
插件 plugin.js
定义插件:plugin.js
export default {
install(Vue, x, y, z){
console.log(x,y,z);
//定义全局过滤器
Vue.filter('mySlice', function(value){
return value.slice(0,4);
})
//定义全局指令
Vue.directive('fbind',{
//指令与元素成功绑定时
bind(element, binding) {
element.value = binding.value;
},
//指令所在元素插入页面时
insert(element,binding) {
element.focus();
},
//指令所在模板被重新解析时
update(element,binding) {
element.value = binding.value;
}
})
//定义混入
Vue.mixin({
data() {
return {
x:100,
y:200
}
}
})
//给Vue原型上添加一个方法
Vue.prototype.hello = ()=>{alert('你好啊')}
}
}
使用插件:Vue.use() 在创建Vue实例前应用插件
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import plugins from './plugins'
//关闭Vue的生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(plugins,1,2,3)
//创建vue实例
new Vue({
el:'#app',
render:h => h(App)
})
scoped样式
-
让样式在局部生效,防止冲突
-
当
style
标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。 -
<style scoped>
<template>
<div>
<h1 class="title">你好啊</h1>
<School/>
<Student/>
</div>
</template>
<script>
import Student from './components/Student'
import School from './components/School'
export default {
name:'App',
components:{School,Student}
}
</script>
<style scoped>
.title{
color: red;
}
</style>
TodoList案例
静态实现(页面)
-
首先拆分页面,把页面划分为一个父组件App.vue和四个子组件
-
拆分之后,建立对应的文件,注册引用组件
-
进行每个组件的编码
动态实现(数据改变)
- 数据的存放位置
- 获取数据,进行修改 ,页面随之变化
总结TodoList案例
- 组件化编码流程
- 拆分静态组件:组件要按照功能点进行拆分,命名不能与html元素冲突
- 实现动态组件:考虑好数据的存放位置,数据是一个组件在用还是一些组件在用
- 一个组件在用,数据放在组件自身
- 一些组件再用,放在组件的共同父组件上(状态提升)
- 实现交互:从绑定事件开始
- props适用于:(1)父组件 ==> 子组件 通信 (2)子组件 ==> 父组件 通信 父组件先给子组件一个函数
- 使用v-model时:v-model绑定的值不能是props传过来的值,因为props是不可以修改的
- 修改props中的值的情况:props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这种方式
- 数据在哪里,操作数据就在哪里
浏览器本地存储
webStorage
- 存储内容大小一般支持5MB左右(不同浏览器可能不一样)
- 浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
- 相关API(4个):
- xxxStorage.setItem(‘key’, ‘value’); 此方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在则更新其对应的值
- xxxStorage.getItem(‘person’); 该方法接收一个键名作为参数,返回键名对应的值
- xxxStorage.removeItem(‘key’); 该方法接收一个键名作为参数,并把该键名从存储中删除
- xxxStorage.clear(); 该方法清空存储中的所有数据
- 注意
- localStorage存储的内容需要手动清除才会消失
- sessionStorage存储的内容会随着浏览器窗口的关闭而消失
- xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那getlteml的返回值是null
- JSON.parse(nul1)的结果依然是null
给TodoList添加本地存储
data() {
return {
//由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)
todos:JSON.parse(localStorage.getItem('todos')) || []
}
},
//深度监视
watch: {
todos:{
deep:true,
handler(value){
localStorage.setItem('todos',JSON.stringify(value))
}
}
},