本文共 13619 字,大约阅读时间需要 45 分钟。
特点:遵循MVVM模式代码简洁、体积小、运行效率高与其他框架的关联:借鉴angular的模板和数据绑定技术借鉴react的组件化和虚拟Dom技术通常我们一些程序设计语言,其中相关代码都是局限在指定的环境下编写;同样,vue框架可以通过相关的vue指令属性,在html视图层进行一些代码操作;如vue环境中(vm对象)内部可以编写一些方法、属性; 方法中可以进行各种变量和各种逻辑结构操作;而只要在html标签中设定一些vue指令属性,那么就可以在html视图模块中也可见vue环境中操作的一些数据或者内容了。(1)比如vue对象中创建了一个变量 tmp:“abc”; 而在html标签中通过v-model = “tmp” 就可以获取到vue环境中创建的这个tmp变量了; (2)同理vue环境中创建了一个方法,在html标签中可以通过@click = “xxx”直接获取该方法的响应结果,变成了回调函数;这两个案例当伪代码理解,理解其思想。
import Vue from 'vue'// main.js 为入口文件,并与app.vue组件向关联使此组件为跟组件// 是所有的内容都在app.vue 上面呈现。import App from './App'// 在router里配置路由,将app组件相关联import router from './router'Vue.config.productionTip = false/* eslint-disable no-new */// 生成vue的根实例;创建每个组件都会生成一个vue的实列,并且会用到根实例上面的所有属性new Vue({ el: '#app', router, // 声明模版 template: '', // 注册成组件 components: { App }})
Vue是一个MVVM架构;其中Vue实例对象作为Vm、实例中数据data模块作为M(model)、html页面模块作为V(view);
其中M的数据可以在V中直接使用访问和双向交互;但是如何完成的呢?这一切就是依赖VM(ViewModel)。
VM本质完成两个操作: DOM监听(监听v中数据的变化) 、 数据绑定(将m的内容绑定到v上)
V(View)—— 视图、模板页面(动态页面),不是静态页面奥!!!简单说就是用来显示数据的 在V层,Vue框架对模板页面有两种语法格式: 一个是指令属性:v-xxx的属性、还有一个是双括号表达式:用于显示数据
M(model) —— 模型,数据对象(data),上面v是动态页面,需要读取数据,那些动态数据就是取自这里
VM(ViewModel) —— 视图模型(Vue的实例),两个功能: (1)数据绑定:实现视图页面或者模板页面可以从M中读取到数据,即被绑定的变量发生变化会传递过去的。(2)DOM监听:视图层有些数据的变化也会影响到数据层;需要对视图层有监听
整个框架结构本质就是声明式开发,何为声明式开发?整个流程不需要我们处理,只需要根据框架限定的语法写一些特定格式就可以了。即基于框架后,按照别人的语法做一些声明的定义就可以完成某些功能
而命令式开发,需要写整个功能的过程,整个流程所有事情都需要我们做,就是命令式。区别于声明式!
首先模板页面V的理解:就是动态的html页面,简单说就是静态Html页面中包含了一些JS语法代码、双括号表达式、vue相关的标签属性。
上面两个细节注意:
一般在标签内容区显示变量数据需要有双括号,而在Vue指令属性出绑定数据变量,是不需要其他操作的,直接当做变量显示的 //通过vue的指令符v-model进行模板页面V和数据层M之间数据的动态绑定 姓: 名:{
{ xing}}-{ { ming}}
效果: 输入框中分别输入姓和名;最后下面显示内容
这边的数据属性是vue实例下data属性中的对象的属性;为了和用户定义的数据属性区分开,vue实例本身也有自身的实例属性和方法,他们的调用都会有前缀$表示;
关键字: 数据属性、实例属性、实例方法
vue中计算属性方式: vue实例属性——computed;这个属性中定义一个计算数据属性的方法,然后这个方法有返回内容,在视图模板中可以将这个方法名当成新的属性来显示数据属性计算的结果; 细节:计算属性的一个方法,这个方法的返回值作为属性值使用,属性名就是方法名。computed:{ operateParam:function(){ return this.xing+" "+this.ming } }------------------------------------------{
{ operateParam}}
通过v-bind:html的某个属性;来给html属性绑定一个灵活的变量,通过变量来改变html属性的属性值;
test...可以在data数据模型中定义一个dynamicId/color变量,这个dynamicId/color变量可以灵活改变
vue组件的注册是通过Vue.component的函数来声明和创建一个全局的vue的组件,紧接着用new vue({el:“#container”})在模板页面中指定一个容器元素,那些定义的全局组件可以在这容器中直接使用。
组件当成一个标签单元的话:内部有: 模板属性————(template中定义原生HTML标签的内容 + vue的指令属性) 方法属性————(html标签中包含的动态方法部分) 数据属性————(html标签中包含的动态数据部分)vue组件化开发核心思想: 组件类似函数,然后组件之间交互,类似函数的传参。类似于我们java的web开发的分层,controller、service、dao层,不同层之间是独立、各司其职的;vue的组件化也是:首先根组件——app.vue,然后就是各种拆分后的子组件,完成不同的任务,每个子组件好像一个封装体,内部有自己的内部属性、方法等,这些属于自己内部局部数据,如果各个子组件之间相互调用,就通过组件的标签属性——props内部定义参数,这个参数就类似于组件函数的入参,用于组件之间数据的传输或者交互,这个参数类型可以是:字符串、基本类型Number、数组Array、对象Object、函数Function等等子组件虽然看作一个封装函数,内部常见的四个操作:props、data、computed、methods。(1)props:作为组件之间交互参数props:{ 参数名:参数类型, //类型可能是:Array、Function、Object、Number 参数名:参数类型, 参数名:参数类型}(2)data: 用来定义作为组件内部局部数据(3)computed:用来作为内部数据变化的计算和监控(4)methods:用来作为组件内部方法的操作
vue中组件:(1)首先需要注册一个组件、然后用一个对象来描述这个组件【这个组件内的使用的局部数据、组件标签的属性(作为外部数据参数)和组件表示的模板内容】,即创建一个组件过程。(2)上面是创建组件的过程,下面是组件的使用,组件使用过程就是:在另一个容器中,像html标签一样,使用就可以了,但是1.需要导入指定组件,还有2.声明该指定组件后,才能在那个容器中使用
(3)将组件进行模块化开发后————组件的创建和调用时分开的,一般在一个vue文件中创建组件,然后在另一个需要使用组件的容器中使用组件,但是这个vue实例容器必须要引入该组件的声明,即vue实例的components属性中描述需要的哪个组件名,自此才可以在该vue实例容器(模板页面中)像html标签一样使用该组件标签奥!!!
vue的组件模块化开发,一个难点在于:数据在哪个组件呢? 不同组件数据的更新操作(方法或者函数)在哪呢?组件之间数据的关联如何完成呢?
App.vue是最外层组件,一般对最外层组件内部各组件进行搭建好后,就将这个最外层组件导入main.js入口函数中,去创建这个最外层组件的虚拟dom,最终将这个虚拟dom挂载到容器中就可以了;注意子组件之间互相过程:(1)首先导入该子组件位置,(2)然后在当前组件实例的components属性中声明一下,(3)最后在当前组件的模板中就可以像使用自定义html标签一样使用了
vue中可以自定义组件;这个组件本质就类似于定义一个自定义的html标签,可以在页面模板中像使用html标签一样使用;vue中自定义组件标签,当然可以设置这个标签具有什么属性,同时向普通html标签一样,进行数据绑定和Dom监听。
简单说vue组件——就是将一模块的html原生标签的操作封装,为了复用而封装成一个自定义名称的标签,这个自定义标签内部封装了某些功能的元素html标签的特有功能交互。
组件间通信的方式:(1)通过prop属性(一般是父组件通过该属性传递数据给子组件)、(2)自定义事件(子组件怎么跟父组件通信呢?);前面两个都是子组件和父组件之间的交互,但是主动方向不同。 (3)消息订阅和发布(此方式可实现任意关系组件间通信)、(4)slot插槽,在子组件A中通过作为占位,然后在父或者其他组件中调用组件A内部通过slot属性< div slot=“xxx”>xxxx…将整个div插入那个slot占位符对应的位置。
组件中使用自定义事件—— 核心两点:(1)父组件上进行监听事件(在父组件中给子组件标签上绑定事件监听)——在父组件上使用子组件标签时,在子标签上使用@事件名=“事件回调方法”;【 $ on(事件名,回调函数),这种是通过vm实例实现的绑定监听,注意需要找到目标标签对象奥!绑定事件的对象.$ on(事件名,回调函数)】(2)子组件进行事件触发(在子组件需要的地方触发事件)——事件回调方法在父组件中实现,但是需要在子组件内部进行事件的触发;在子组件内部通过【this.$emit(事件名,传递的参数) 】
组件之间的通信规则:父组件传递数据给子组件通过props; 而子组件传递数据给父组件通过自定义事件父->子,通过属性(也就是参数呀)子->父,通过回调函数,子组件调用父组件传递的函数,来改变父组件的状态绑定事件监听、触发事件 ———— (1)在上层给子组件标签上绑定事件,还有该事件的回调函数; (2)然后在子上面设置触发同时传递数据过去就可以了
订阅消息类似于绑定事件监听、发布消息类似于触发事件 ———— (1)在上层进行消息的订阅(订阅消息就是接收消息),设置好消息名,还有该消息触发的回调函数; (2)然后在子上面需要的地方进行消息的发布,这样一发布,就会触发上面订阅该消息的回调函数
订阅和发布是需要第三方包—— pubSub-js初期vue组件化过程不是很熟悉,可以使用套路:
default
// main.js是入口文件import Vue from 'vue'import AppTest from './App.vue' Vue.config.productionTip = falsenew Vue({ render: h => h(AppTest),}).$mount('#sun') // createElement 函数是用来生成 HTML DOM 元素的,也就是上文中的 generate HTML structures, // 也就是 Hyperscript,这样作者才把 createElement 简写成 h。
创建的组件,可以在vue根(实例)容器中像元素html标签一样直接使用;vue实现的模板页面: dom监听 + 数据绑定; 一般两种方式:第一种:传统的在原生html标签的模板页面中,通过vue的一些指令属性,完成和vue中定义的变量数据或者方法的绑定;第二种:基于传统元素HTML标签来封装自定义组件(标签);将某些可复用功能模块的原生HTML页面模板封装成组件,通过组件名(自定义标签名)直接的相互调用,完成模板页面的动态交互。 组件核心:(1)组件的创建和定义,(2)组件内数据和回调方法的操作,(3)组件之间如何灵活调用,(4)还有和vue根实例如何建立关联。》》》》》》》》》》》》》》》 组件声明和创建细节: 《《《《《《《《《《《《《《《(1)组件也可以理解为是vue实例,但区别于vue根实例,组件中可以有数据属性data、方法属性methods,但是没有el属性,el是根独有的,且组件的数据属性部分是相互独立的,可以理解为是组件函数内部局部数据,组件数据属性是一个函数,这样不同组件之间,即每个实例可以维护一份被返回对象的独立的拷贝:data: function () { return { count: 0 }}(2)在template模板中定义模板包含的HTML结构时,必须遵循一个前提: every component must have a single root element (每个组件必须只有一个根元素)。你可以将模板的内容包裹在一个父元素内。 下面模板内容是错误的:Vue.component('blog-post', { props: ['title'], //给该组件声明一个属性,这个属性算这个组件的全局数据属性,可以组件之间交互数据的。 template: '{ { title }}
'})正确的形式如下: template: '' 必须有一个根元素包含 (3)子组件可以使用 props设置自定义标签的属性名,可用来接收父组件的数据 (4)vue进行组件创建好后,可用在任何创建的vue根实例的模板中使用这些自定义组件标签奥,类似html原生标签那样使用,就行组件创建过程:new vue({ el:“#app”,data:{ xxx:x},methods:{ xx:function(){ xxxxx}}components:{ //细节————————这里面是将其他组件实例映射成标签,以供在当前实例中以标签形式使用这些组件。组件名:{ 组件相关信息—— 组件模板、组件内部data数据、方法等等,和vue实例中属性差不多定义 template:“{ { title }}
h2......
”, methods:{ }}}})(5)组件注册后,调用的范围: 如果一个组件A想要调用组件B,那么首先需要在组件A中通过在components属性中声明组件B;然后导入组件B的包,最后才可以在组件A的模板中直接使用组件B标签奥!!!在组件A的模板中就像用原生html标签一样使用组件B标签================================================================================import Vue from 'vue'import AppTest from './App.vue'new Vue({ render: h => h(AppTest), }).$mount('#sun')上面翻译后结构就是如下://表示创建一个AppTest组件,挂载到id为sun的容器内; 比如就是如下结构/**/ (6)new Vue({ render: h => h(App),}).$mount('#app') 其中:render: h => h(App)含义是创建一个虚拟dom节点;render: function (createElement) { return createElement(App);} //createElement 是 Vue.js 里面的 函数,这个函数的作用就是生成一个 VNode节点(虚拟节点)// createElement 函数是用来生成 HTML DOM 元素的,也就是上文中的 generate HTML structures, // 也就是 Hyperscript,这样作者才把 createElement 简写成 h。 //让vue实例控制或者管理网页中某个区域的过程,称之为挂载。$mount('#app'): 表示挂载,即vue根实例挂载到id为app的dom中vue核心是通过模板语法声明式的将数据渲染进DOM的系统;vue创建实例后,第一个就是指明el属性,这个就是指定要进行数据渲染的DOM容器范围(目标),(7)在vue中,可以利用{ { }}执行实例中定义好的方法,也可以用v-on指令或者v-on指令的缩写@执行实例中定义好的方法,两者的区别是{ { }}中调用的方法要方法名+()才能执行,而v-on或者@指令直接写方法名可以执行、方法名+()也能执行!(8)const常量的意思是:其变量的栈地址不可变更,但是其引用的对象在堆存里,对象的属性是可以增删改查的
vue实例本质是实现视图模板页面层(V)和数据层(M)之间的Dom监听和数据绑定;
(1)js代码中组件模板注册 Vue.component('blog-post', { props: ['title'], template: '{ { title }}
' })----------------------------(2)在html代码块中,使用新注册的自定义标签:----------------------------(3)视图页面显示结果: My journey with Vue Blogging with Vue Why Vue is so fun上面是最基本的新创建自定义标签组件的使用;实际上自定义的标签和原生html标签写的模板页面形式一样使用;下面是使用模板进行的一个简单的demo实例 --------------------------------------------视图页面显示结果: My journey with Vue Blogging with Vue Why Vue is so fun
(1)
(2)
(3)
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。npm i element-ui -S
============================================而组件库中需要全局使用,所以需要全局注册组件为标签,局部组件使用,一般导入和注册过程在当下组件中,而全局组件的导入和注册最好在入口js中;即有new vue根组件的文件中;这样注册的组件,才可以在下面的任何新创建的VUe根实例的模板中使用;组件全局注册的语法:Vue.component('my-component-name', { // ... 选项 ...})Vue.component("el-xxx",xxx)如:import { Button, Select } from 'element-ui';Vue.component("el-button", Button);Vue.component("el-select", Select);Vue.component(Button.name, Button); //默认的name属性就是"el-button"或者如下方式进行全局注册/* 或写为 * Vue.use(Button) * Vue.use(Select) */
非路由组件在被导入后,被component属性注册成标签,然后当成标签使用;而路由组件在被导入后,被router注册成路由路由,然后通过路由标签的路由链接来使用。
首先创建一个路由器实例:new VueRouter({//配置项—— 如路由配置routers:[{},{},{}]})然后将创建的路由器注册进vue组件中。路由器组件相关标签:路由链接标签【】、路由组件界面标签【 】
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter) // 1. 定义 (路由) 组件。// 可以从其他文件 import 进来const Foo = { template: 'foo' }const Bar = { template: 'bar' }// 2. 定义路由; 将路由组件映射成路由路径 ——> 这一步和自定义组件那边引入别的组件,然后注册组件为标签的过程一样奥!// 每个路由应该映射一个组件。 其中"component" 可以是// 通过 Vue.extend() 创建的组件构造器,// 或者,只是一个组件配置对象。// 我们晚点再讨论嵌套路由。const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar }]// 3. 创建 router 实例,然后传 `routes` 配置// 你还可以传别的配置参数, 不过先这么简单着吧。const router = new VueRouter({ routes // (缩写) 相当于 routes: routes})// 4. 创建和挂载根实例。// 记得要通过 router 配置参数注入路由,// 从而让整个应用都有路由功能const app = new Vue({ router}).$mount('#app')// 现在,应用已经启动了!
Hello App!
Go to Foo Go to Bar
就是通过js代码的方式实现页面路径的跳转:传统a标签方式,而js本质是window.location=‘url’;
路由对象中有相关路由跳转的方法
vue中核心三点:
数据绑定:核心就是data中属性数据变化了,界面上对应的属性也发生了改变;原理思想:就是对界面中每个属性都会有一个监视器,这个监视器会监听每个数据的变更,会触发一个回调函数,这个回调函数有旧值和新值参数, 在回调函数中找到属性数据的所属节点对象,然后对这个节点进行dom操作,用新值替换掉属性表达式的旧值。数据绑定中有dep和watcherwatcher对应属性在模板中使用次数;属性表达式使用一次就对应一个watcher;dep对应属性表达式的层次,模板中出现多少不同的属性,就有多少个dep,如{ {mes.name}} 表示对应一个watcher,两个dep (一个mes属性,一个name属性)
模板解析:核心就是对dom结构中指令属性和大括号表达式的解析; ———— 将el对应的dom结构中所有节点加到fragment碎片对象(类似于一个特殊的容器)中,然后在这个fragment对象中对各个层次的子节点(文本节点,元素节点)进行操作——元素节点进行指令属性的解析、文本节点进行大括号表达式的解析【正则表达式进行大括号表达式的解析,从data中获取表达式对应的属性值,将属性值设置为文本节点的textContent】
指令属性的解析:事件指令解析和一般指令解析;事件指令属性【v-on:click=“show”】解析【就是解析这个事件属性名(“v-on:click”)和属性值(“show”)】;然后通过dom原生的节点对象.addEventListener(“click”,)
事件指令解析:
模板解析中,标签内一般指令属性的解析:
转载地址:http://uhdxi.baihongyu.com/