组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码 组件是自定义元素(对象)
方式1:先创建组件构造器,然后由组件构造器创建组件 方式2:直接创建组件
<p id="itany"> <hello></hello> <my-world></my-world> </p> <script> /** * 方式1:先创建组件构造器,然后由组件构造器创建组件 */ //1.使用Vue.extend()创建一个组件构造器 var MyComponent=Vue.extend({ template:'<h3>Hello World</h3>' }); //2.使用Vue.component(标签名,组件构造器),根据组件构造器来创建组件 Vue.component('hello',MyComponent); /** * 方式2:直接创建组件(推荐) */ // Vue.component('world',{ Vue.component('my-world',{ template:'<h1>你好,世界</h1>' }); var vm=new Vue({ //这里的vm也是一个组件,称为根组件Root el:'#itany', data:{ msg:'网博' } }); </script>
Definition of components
分类:全局组件、局部组件
<p id="itany"> <my-hello></my-hello> <my-world></my-world> </p> <script> /** * 全局组件,可以在所有vue实例中使用 */ Vue.component('my-hello',{ template:'<h3>{{name}}</h3>', data:function(){ //在组件中存储数据时,必须以函数形式,函数返回一个对象 return { name:'alice' } } }); /** * 局部组件,只能在当前vue实例中使用 */ var vm=new Vue({ el:'#itany', data:{ name:'tom' }, components:{ //局部组件 'my-world':{ template:'<h3>{{age}}</h3>', data(){ return { age:25 } } } } }); </script>
Classification of components
将组件内容放到模板<template>中并引用,必须有且只有一个根元素
<p id="itany"> <my-hello></my-hello> <my-hello></my-hello> </p> <template id="wbs"> <!-- <template>必须有且只有一个根元素 --> <p> <h3>{{msg}}</h3> <ul> <li v-for="value in arr">{{value}}</li> </ul> </p> </template> <script> var vm=new Vue({ el:'#itany', components:{ 'my-hello':{ name:'wbs17022', //指定组件的名称,默认为标签名,可以不设置 template:'#wbs', data(){ return { msg:'欢迎来到南京网博', arr:['tom','jack','mike'] } } } } }); </script>
Reference template
<component :is="">组件 多个组件使用同一个挂载点,然后动态的在它们之间切换 <keep-alive>组件
<p id="itany"> <button @click="flag='my-hello'">显示hello组件</button> <button @click="flag='my-world'">显示world组件</button> <p> <!-- 使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建 --> <keep-alive> <component :is="flag"></component> </keep-alive> </p> </p> <script> var vm=new Vue({ el:'#itany', data:{ flag:'my-hello' }, components:{ 'my-hello':{ template:'<h3>我是hello组件:{{x}}</h3>', data(){ return { x:Math.random() } } }, 'my-world':{ template:'<h3>我是world组件:{{y}}</h3>', data(){ return { y:Math.random() } } } } }); </script>
Dynamic component
Define another component inside a component, called parent-child component
Child component can only be used inside the parent component
By default, Child components cannot access data in the parent component. The scope of each component instance is independent
a)在调用子组件时,绑定想要获取的父组件中的数据 b)在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据 总结:父组件通过props向下传递数据给子组件
Note: There are three forms of data in the component: data
, props
, computed
a)在子组件中使用vm.$emit(事件名,数据)触发一个自定义事件,事件名自定义 b)父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据 总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件
Data transfer between parent and child components and components
props是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来 而且不允许子组件直接修改父组件中的数据,报错 解决方式: 方式1:如果子组件想把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据 方式2:如果子组件想修改数据并且同步更新到父组件,两个方法: a.使用.sync(1.0版本中支持,2.0版本中不支持,2.3版本又开始支持) 需要显式地触发一个更新事件 b.可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间),推荐
One-way data flow
非父子组件间的通信,可以通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件 var Event=new Vue(); Event.$emit(事件名,数据); Event.$on(事件名,data => {});
Communication between non-parent-child components
本意:位置、槽 作用:用来获取组件中的原内容,类似angular中的transclude指令
slot content distribution
使用Vue.js开发SPA(Single Page Application)单页面应用 根据不同url地址,显示不同的内容,但显示在同一个页面中,称为单页面应用
Reference
bower info vue-router cnpm install vue-router -S
a.布局 b.配置路由
<p id="itany"> <p> <!-- 使用router-link组件来定义导航,to属性指定链接url --> <router-link to="/home">主页</router-link> <router-link to="/news">新闻</router-link> </p> <p> <!-- 路由出口 --> <!-- 路由匹配到的组件将渲染在这里 --> <!-- router-view用来显示路由内容 --> <router-view></router-view> </p> </p> <script> //1.定义组件 var Home={ template:'<h3>我是主页</h3>' } var News={ template:'<h3>我是新闻</h3>' } //2.配置路由 const routes=[ {path:'/home',component:Home}, {path:'/news',component:News}, {path:'*',redirect:'/home'} //重定向 ] //3.创建路由实例 const router=new VueRouter({ routes, //简写,相当于routes:routes // mode:'history', //更改模式 linkActiveClass:'active' //更新活动链接的class类名 }); //4.创建根实例并将路由挂载到Vue实例上 new Vue({ el:'#itany', router //注入路由 }); </script>
Basic routing usage
传参的两种形式: a.查询字符串:login?name=tom&pwd=123 {{$route.query}} b.rest风格url:regist/alice/456 {{$route.params}}
router.push() 添加路由,功能上与<route-link>相同 router.replace() 替换路由,不产生历史记录
Routing nesting and parameter passing, Animation
.vue文件,称为单文件组件,是Vue.js自定义的一种文件格式,一个.vue文件就是一个单独的组件,在文件内封装了组件相关的代码:html、css、js .vue文件由三部分组成:<template>、<style>、<script> <template> html </template> <style> css </style> <script> js </script>
浏览器本身并不认为.vue文件,所以必须对.vue文件进行加载解析,此时需要vue-loader 类似的loader还有许多,如:html-loader、css-loader、style-loader、babel-loader等 需要注意的是vue-loader是基于webpack的
webpack是一个前端资源模板化加载器和打包工具,它能够把各种资源都作为模块来使用和处理 实际上,webpack是通过不同的loader将这些资源加载后打包,然后输出打包后文件 简单来说,webpack就是一个模块加载器,所有资源都可以作为模块来加载,最后打包输出
webpack official website
webpack版本:v1.x v2.x webpack有一个核心配置文件:webpack.config.js,必须放在项目根目录下
webpack-demo
|-index.html |-main.js 入口文件 |-App.vue vue文件 |-package.json 工程文件 //npm init --yes |-webpack.config.js webpack配置文件 |-.babelrc Babel配置文件
cnpm install vue -S cnpm install webpack -D cnpm install webpack-dev-server -D cnpm install vue-loader -D cnpm install vue-html-loader -D cnpm install css-loader -D cnpm install vue-style-loader -D cnpm install file-loader -D cnpm install babel-loader -D cnpm install babel-core -D cnpm install babel-preset-env -D //根据配置的运行环境自动启用需要的babel插件 cnpm install vue-template-compiler -D //预编译模板 合并:cnpm install -D webpack webpack-dev-server vue-loader vue-html-loader css-loader vue-style-loader file-loader babel-loader babel-core babel-preset-env vue-template-compiler
import Vue from 'vue' //引入内置模块 import App from './App.vue' //引入自定义模块,需要加./ render:function(h){ //使用render函数(推荐)渲染组件,和compnents一样 return h(App); } /* scoped表示该样式只在当前组件中有效 */
npm run dev
webpack-demo
vue-cli是一个vue脚手架,可以快速构造项目结构 vue-cli本身集成了多种项目模板: simple 很少简单 webpack 包含ESLint代码规范检查和unit单元测试等 webpack-simple 没有代码规范检查和单元测试 browserify 使用的也比较多 browserify-simple
Official website installation example
cnpm install vue-cli -g vue --version vue list
语法:vue init 模板名 项目名
cd vue-cli-demo cnpm install
npm run dev //启动测试服务 npm run build //将项目打包输出dist目录,项目上线的话要将dist目录拷贝到服务器上
vue init webpack vue-cli-demo2 ESLint是用来统一代码规范和风格的工具,如缩进、空格、符号等,要求比较严格
Official website
问题Bug:如果版本升级到node 8.0 和 npm 5.0,控制台会报错: GET http://localhost:8080/__webpack_hmr net::ERR_INCOMPLETE_CHUNKED_ENCODING 解决方法: a)降低Node版本到7.9或以下 b)修改build/dev-server.js文件,如下: var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: () => {}, heartbeat:2000 //添加此行 }) 参考:https://github.com/vuejs-templates/webpack/issues/731
Refer to the Vue teaching video: Vue.js 2.0 family bucket series video courses (vue, vue-router, axios, vuex)
Related recommendations:
Detailed examples Chat room for parent-child communication between vue components
How to transfer data between vue.js components
The above is the detailed content of Detailed explanation of Vue components and data transfer. For more information, please follow other related articles on the PHP Chinese website!