文章目录
Vue2学习day04
现在我们开始使用@vue/cli
脚手架来搭建项目。Vue CLI官方文档
脚手架搭建
想要使用Vue CLI首先要安装包在cmd中运行如下命令
npm install -g @vue/cli
我这里安装的版本是4.5.11,想要指定版本安装也很简单,只需在后面添加@版本号
即可
安装成功之后,我们进入想要创建项目的文件夹,执行命令
vue create hello-world
此为Vue2学习笔记,自己装的是vue2,选着如下选项,babel可以将ES6转为ES5,eslint进行语法检查
项目创建完成后,我们使用VSCode打开
分析脚手架
脚手架结构:
├── 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:包版本控制文件
下面我们将上篇博客最后的单文件组件的案例整合到项目中,逻辑都是一样的,不再做具体说明
首先将components
目录下的HelloWorld
组件删除,我们用不到,而后在其下构建School组件和Student组件直接复制上述案例中的代码即可,建议命名Student.vue
,School.vue
之后修改src
目录下App.vue
中的代码同样直接复制我们上篇博客最后单文件组件的案例中的即可
index.html
和main.js
中的代码我们直接用脚手架给我们创建的HelloWorld案例中的即可,不需修改,因和我们上个案例中书写的不大一致,下面将对这两个部分的代码进行分析
index.html
中的代码分析,其在public
目录下
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<!-- 针对IE浏览器的特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 开启移动端的理想视口 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- 配置页签图标 -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 配置网页标题 -->
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!-- 当浏览器不支持js时noscript中的元素就会被渲染 -->
<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 是一个不能解析template配置项的vue
import Vue from 'vue'
// 引入App组件,他是所有组件的父组件
import App from './App.vue'
// 关闭vue的生产提示
Vue.config.productionTip = false
/*
关于不同版本的Vue:
vue.js与vue.runtime.js的区别:
vue.js是完整版的Vue,包含:核心功能+模板解析器
vue.runtime.xxx.js是运行版的Vue,只包含:核心功能:没有模板解析器
因为Vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容
*/
// 创建Vue的生产提示
new Vue({
el:'#app',
// 完成了这个功能:将App组件放入容器中
// render是一个函数,Vue调用,传递了createElement函数,创建具体的函数,编写具体的内容
/*render(createElement){
return createElement('h1','你好啊')
}*/
// render函数可以简写,因未用到this故可以简写为箭头函数
/*render:(createElement)=>{
return createElement('h1','你好啊')
}*/
// 传递的参数只有一个因此括号可以去掉,箭头函数只有一句函数体,并且还要return可简写为
//render:createElement=>createElement('h1','你好啊')
// 继续简写将createElement使用一个简单参数名替代
// render: h => h('h1''你好啊')
render: h => h(App),
})
下面我们来运行下我们的项目
首先在VSCode中打开终端,在VSCode中开启终端快捷键Ctrl + Esc下方的键
在终端中输入npm run serve
运行项目, 将直接运行src目录下的main.js
关于不同版本的Vue
修改默认配置
官网文档
vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。会与webpack配置结合
- 使用
vue inspect > output.js
可以查看到Vue脚手架的默认配置。 - 使用
vue.config.js
可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh
ref属性
- 被用来给元素或子组件注册引用信息(id的替代者)
- 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
- 使用方式:
- 打标识:
<h1 ref="xxx">.....</h1>
或<School ref="xxx"></School>
- 获取:
this.$refs.xxx
- 打标识:
- 示例:
<template> <div> <h1 v-text="msg" ref="title"></h1> <button ref="btn" @click="showDOM">点我输出上方的DOM元素</button> <School ref="sch"/> </div> </template> <script> // 引入School组件 import School from './components/School' export default { name:'App', components:{ School }, data(){ return{ msg:'Vue学习之ref属性' } }, methods:{ showDOM(){ console.log(this.$refs.title) // 真实DOM元素 console.log(this.$refs.btn) // 真实DOM元素 console.log(this.$refs.sch) // School组件的实例对象(vc) } } } </script>
配置项props
- 功能:让组件接收外部传来的数据
- 传递数据:
<Demo name="xxx" />
- 接受数据:
-
第一种方式(只接收)
props:['name']
-
第二种方式(限制类型):
props:{ name:String, age:Number }
-
第三种方式(限制类型、限制必要性、指定默认值)
props:{ name:{ type:String,// 类型 required:true,// 必要性 default:'老王' // 默认值 } }
-
- 备注:
- props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据
- 示例:
- 组件:Student.vue
<template> <div class="school"> <h1>{{msg}}</h1> <h2>学生姓名:{{name}}</h2> <h2>学生性别:{{sex}}</h2> <h2>学生年龄:{{age+1}}</h2> <h2>传递的年龄属性更改:{{myAge+1}}</h2> <button @click="updateAge()">点我修改收到的age</button> </div> </template> <script> export default { name:'Student', data(){ return{ msg:'正在学习尚硅谷Vue', // name:'张三', // sex:'男', // age:20 // 就是要改 第一步 myAge:this.age } }, methods:{ updateAge(){ // 接受到的prop不能更改 警告 //this.age = 22 // 就是要改 第二步 this.myAge++ } }, // props相比data中的属性优先级更高 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>
- App.vue
<template> <div> <!-- 三个组件对象,互不影响 --> <Student /> <hr> <Student name="张三" sex="男" age="20" /> <hr> <Student name="李四" sex="女" :age="18" /> </div> </template> <script> // 引入School组件 import Student from './components/Student' export default { name:'App', components:{ Student } } </script>
mixin(混入)
- 功能:可以把多个组件共用的配置提取成一个混入对象
- 使用方式:
-
第一步定义混合,例如:
{ data(){...}, methods:{....} ..... }
-
第二步使用混入,例如:
- 全局混入:
Vue.mixin(xxx)
- 局部混入:
mixins:['xxx']
- 全局混入:
-
- 示例:
- 在src目录下创建
minix.js
// 分别暴露 export const hunhe = { methods:{ showName(){ alert(this.name) } }, mounted() { console.log("mounted") }, } export const hunhe2 = { data() { return { x:100, y:200 } }, }
- 组件:
School.vue
<template> <div class="school"> <h2 @click="showName()">学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> </div> </template> <script> // 局部引入一个hunhe //import {hunhe,hunhe2} from '../minix' export default { name:'School', data(){ return{ name:'曲师大', address:'曲阜', // 和hunhe2中的冲突,自定义的为主 x:666 } }, // 局部 /*mixins:[hunhe,hunhe2], mounted(){ // hunhe中有,组件中也有都要 console.log('Vue学习之mixin') }*/ } </script>
- 组件:
Student.vue
<template> <div class="school"> <h2 @click="showName()">学生姓名:{{name}}</h2> <h2>学生性别:{{sex}}</h2> </div> </template> <script> // 引入一个hunhe 局部,全局的去main.js中配置 //import {hunhe,hunhe2} from '../minix' export default { name:'Student', data(){ return{ name:'张三', sex:'男', } }, // 局部 //mixins:[hunhe,hunhe2] } </script>
- 全局引入时
main.js
中需要增加的配置// 全局的 import {hunhe,hunhe2} from './minix' // 全局hunhe Vue.mixin(hunhe) Vue.mixin(hunhe2)
- 在
App.vue
中使用组件测试即可
- 在src目录下创建
插件
- 功能:用于增强Vue
- 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
- 定义插件:
对象.install = function (Vue, options) { // 1. 添加全局过滤器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加实例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
- 使用插件:Vue.use()
- 示例:
- 在src目录下创建
plugins.js
export default{ install(Vue){ console.log('@@@install',Vue) // 全局过滤器 Vue.filter('mySlice',function(value){ return value.slice(0,4) }) // 定义全局指令 Vue.directive('fbind',{ // 指令与元素成功绑定时 bind(element,binding){ element.value = binding.value console.log('bind') }, // 指定所在元素被插入页面时 inserted(){ element.focus() console.log('inserted') }, // 指令所在模板被重新解析时 update(){ element.value = binding.value console.log('update') } }) // 定义混入 Vue.mixin({ data() { return { x:100, y:200 } }, }) // 给Vue原型上添加一个方法(vm和vc就都能用了) Vue.prototype.hello = () => {alert('你好啊')} } }
- 在
main.js
中增添如下配置// 引入插件 import plugins from './plugins' // 使用插件 Vue.use(plugins)
- 这样就可以在项目中直接使用上述配置了,配置的过滤器、自定义指令、混入、方法在之前的学习中已经学过了如何使用,这里不在重复,忘记的可以去看我前面关于Vue2的学习记录博客
- 在src目录下创建
scoped样式
- 作用:让样式在局部生效,防止冲突。
- 写法:
<style scoped>
- 可以使用
lang="css"
或者lang="less"
来指定语法,但是需要先安装less-loader
包- 由于脚手架自动帮我们引入的webpack版本为4.46.0,而less-loader版本8,9,10是针对webpack5的,所以在安装时需要指定less-loader的版本号,这里我们安装7版本的,在VSCode终端中安装less-loader命令
安装完成即可使用了npm install less-loader@7