(二十二)、组件(Compontents)
1.组件_非单文件
- 单文件与非单文件的区别:
单文件组件
: 一个文件就是一个组件,而且文件后缀是.vue
非单文件组件
: 所有组件,都定义在一个文件中,文件的后缀不是.vue
我们正常开发中一定使用的是单文件组件,我们实列用的.html .js都是非单文件组件。
- 组件的调用
组件的参数和new Vue()一样是一个配置对象,但是在这个配置对象中: el不能被写在这里,data在这里必须是一个方法而不能是一个对象。如果是一个对象就会报错!目的是为了确保组件中的属性不会被干扰。
组件的使用基本流程: 1.定义组件 2.注册组件: (1).全局注册 // 全局注册组件Vue.component(组件名,组件) Vue.component('School',School) // 自定义组件名、组件 (2).局部注册 components:{// 局部注册组件 School } 3.定义一个Vue的实列 const vm=new Vue({ el:'#root', components:{ // 局部注册组件 School } }); 4.组件标签展示 <div id="root"> <School></School> </div>
全局注册组件可以供多个Vue实列共享,局部全局注册组件只能供一个使用
<!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>非单文件组件</title> <script src="../js/vue.js"></script> </head> <body> <!-- 组件的使用基本流程: 1.定义组件 2.注册组件: (1).全局注册 (2).局部注册 3.定义一个Vue的实列 4.组件标签展示 --> <div id="root"> <School></School> </div> <script> Vue.config.productionTip = false // 定义一个School组件。 //1. 如何定义一个组件? -- 使用Vue.extend(options)去创建 //2.School的本质是一个构造函数,我们以后写<School/>,Vue帮我们new School //3.Vue.extend(options), options -->是一个配置对象,这个配置对象几乎和new Vue时的哪个options一样。 // (1). 不能写el去指定容器? // 所有组件实列最终要被一个vm所管理,vm中会指定好一个el,即组件放入哪个容器 // (2). data必须写成函数,不能写成对象。 // 即利用return。 原因是:如果是一个对象,那么修改一个属性,后面调用的这个属性都会变化成我们修改的属性。而函数的话只会调用修改的函数,没调用的不会被修改 // (3).组件的模板结构, //3.1 要配置在template属性中,值为html字符串,而且要用模板字符串:"``" ->反引号 //3.2 模板结构必须只有一个跟标签。 //4.所有的组件定义后,必须注册后才能够使用。 //5.特别注意: // (1). School确实是构造函数,但不是我们亲手写的School,而是Vue.extend生成的。 // (2).Vue.extend()的返回值是: VueComponent 构造函数,所以new School其实就是在 new VueComponent() // (3).所有的组件实列,都是VueComponent创建的实列,简称:"vc"。 所有Vue的实列都是Vue创建的实列,简称:"vm" //6.一个非常重要的关系 // (1). VueComponent继承了Vue,所以Vue原型上的属性和方法,VC都能够看得到。 ⭐⭐ const School = Vue.extend({ data(){ return{ name:'CKQN', address:'河南周口' } }, // template中配置组件的模板结构 template:` <div> <h2>{{name}}</h2> <h2>{{address}}</h2> </div> ` }) // 这里的extend和extends继承是有关系的。 // 全局注册组件Vue.component(组件名,组件) // Vue.component('School',School) // 自定义组件名、组件 // 定义一个Vue的实列去管理组件 const vm=new Vue({ el:'#root', components:{ // 局部注册组件 School } }); const s=new School(); console.log(s); </script> </body> </html>
组件对象都是VueComponent创建的,简称:"vc"。VueComponent继承了Vue。
继承的实质: 就是让子类的原型对象指向父类的实列
2.组件_单文件
1.非单文件弊端。
- 模板编写没有提示并且不高亮。
- 没有构建过程,无法将ES6转换成ES5。
- 不支持组件的CSS。
- 真正的开发根本用不到。
组件与组件之间可以嵌套。
- 创作vue组件-但未成功!!
创建单文件数据组件
/* 这里写完并不是说我们创建好了一个组件,只能说写完了一个组件的全部配置。因为没有调用Vue.extend()*/ /* 配置组件模板结构 */ <template> <!-- div 会跑到页面上去 --> <div> <h2 class="title">学校名: {{ name }}</h2> <h2 class="info" @click="showInfo">学校地址: {{ address }}</h2> </div> </template> /* 配置组件数据、交互、时间等等*/ <script> // 此处只是暴露一个组件的配置,⭐并没有去创建组件⭐,因为没有调用Vue.extend(); export default { // data区域 data: { name: "CKQN", address: "河南周口", }, // 方法区域 methods: { showInfo() { // 这里的this是vc 并不是vm了 alert(this.address); }, }, }; </script> /* 配置组件样式 */ <style> .title{ background-color: blue; } .info{ background-color: brown; } </style>
内嵌单文件组件
// 配置组件模板的结构 <template> <div> <h2>我是APP: {{car}}</h2> <school></school> </div> </template> // 配置组件的交互、事件等信息 <script> // 引入School组件 import School from './components/School' // 暴露组件 export default{ data() { return { car:'宝马' } }, components:{SchoolSchool} } </script> <style> </style>
index.html
<!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>Document</title> <script src="../js/vue.js"></script> </head> <body> <div id="root"> <App></App> </div> <script> import App from './App.vue' new Vue({ el:'#root', components:{App} }) </script> </body> </html>
运行结果: 失败!!
(二十三).使用Vue脚手架
脚手架的作用: 解析ES6模块、解析vue组件、以及自动调用Vue.extend()
1.使用脚手架创建模板项目
- 说明
- vue-cil是vue官方提供的脚手架工具。
- 3.x相对于2.x的版本相差特别大,我们利用vue-cli 4.0版本。
- 在线文档:
- 创建vue项目
第一步: 安装Vue脚手架:
npm install -g @vue/cli
第二步: 进入我们需要使用脚手架项目的目录下:
打开cmd,在桌面的目录上..
vue create '自定义名字'
选择2
创建完毕之后: 会显示下面的页面
3.根据提示进入它指定的位置:
cd vue_staging
4.运行 脚手架
npm run serve
浏览器输入网址:显示下面的页面也就是成功了
Vue脚手架只需安装一次即可。然后终身受益
2.分析Vue脚手架
查看我们下载的Vue脚手架
汇总组件
├── 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:包版本控制文件
- 修改源代码
HelloWorld.vue
<template> <div> <h2>Hello,{{name}}</h2> </div> </template> <script> export default { data() { return { name:'CKQN' } }, }; </script> <style> h2{ background-color: aquamarine; } </style>
App.vue
<template> <div> <h1>欢迎学习:{{text}} </h1> <HelloWorld/> </div> </template> <script> // 引入外壳组件 import HelloWorld from './components/HelloWorld.vue' export default { components:{HelloWorld}, // 这个名字是: 我们引入的 {HelloWorld} data(){ return { text:'Vue' } } } </script> <style> </style>
main.js
import Vue from 'vue' import App from './App.vue' // 关闭生产提示 Vue.config.productionTip = false new Vue({ // 相当于 局部注册组件 components:{App} render: h => h(App), }).$mount('#app')
index.html
<!DOCTYPE html> <html lang=""> <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"> <!-- 网站图标定制路径 --> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <!-- 自动读取包下package.json的名字 --> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div id="app"> <App></App> </div> </body> </html>
在控制台中断输入:
npm run serve
- 运行报错的解决办法:
运行的时候出错:
解决办法
1)搜索powershell,右键以管理员身份运行 2)输入:set-ExecutionPolicy RemoteSigned 然后:输入 y 3)关闭命令窗口 即可
在package.json中添加
"rules": { "vue/no-unused-components": "off", "no-unused-vars":"off" }
- 成功解决
3.关于main.js中的h说明
- render与compontents的区别
只能使用h这个属性
import Vue from 'vue' import App from './App.vue' // 关闭生产提示 Vue.config.productionTip = false new Vue({ // 相当于 局部注册组件 components:{App},但是不能换成在局部注册组件 render: h => h(App), }).$mount('#app')
不能切换成我们熟悉的局部注册组件
import Vue from 'vue' import App from './App.vue' // 关闭生产提示 Vue.config.productionTip = false new Vue({ // 相当于 局部注册组件 components:{App} // render: h => h(App), components:{App} }).$mount('#app')
会报错:
- 为什么会报错?
原因是:脚手架引用的vue库是简化版本的,没有模板解析器
import Vue from 'vue' import App from './App.vue' // 关闭生产提示 Vue.config.productionTip = false /* vue.js与vue.runtime.common.js的区别 vue.runtime.common.js (项目中用的多) 1. 不包含模板解析器,打包后体积校 2.配置项中的不能写template, 要用render: h=>h(App) vue.js 1.包含模板解析器,打包后体积大 2.配置可以写template */ new Vue({ // 这里的h函数是官方写的,不是我们写的 render: h => h(App), // components:{APP}. // Template:`<App></App>` }).$mount('#app')
h函数相当于:下面那俩行+模板解析器