vue介绍
vue是一个渐进式的JavaScript框架。渐进式:可插拔式、可扩展。
我们刚开始只需要使用最核心的核心库,后期可以自己去增加新库。
vue引入
vue提供了非常详细的官方文档,我们完全可以通过官方文档来学习vue.vue官方文档
xx.vue文件组成结构:
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
在chrome中安装vue开发工具
该插件可以在chrome浏览器中充当vue的调试工具
mvvm简介
html使用vue
<script type="text/javascript">
var vm = new Vue({
el:'',
data:{
},
methods:{
},
computed:{
},
directives:{
},
watch:{
},
components:{
},
filters:{
}
})
</script>
var vm = new Vue({});
创建一个vue的实例
当我们导入包之后在浏览器的内存中,就多了一个Vue的构造函数
注意:我们new出来的这个vm对象就是我们mvvm中的vm调度者
el
表示,当前我们 new的这个vue实例,要控制页面上的哪一个区域
data
data属性中,存放的时el中索要用到的数据,形式是采用
key:value
的形式这里的data 就是mvvm中的m,专门用来保存页面数据的
通过 vue提供的指令,很方便的就能把数据渲染到页面上,程序员不需要手动操作dom元素了【前端的vue之类的框架,不提倡我们区手动操作dom元素了】
data中定义的变量是全局变量,所有vue对象都可以使用
computed中的返回值也作为data中的一部分
methods
定义方法
computed
进行计算,初始时自动加载,和变量是共享的(在data中定义的变量,就不能再在computed中定义)它中方法的返回值,也作为data变量存在:方法名就是变量名,返回值就是它的值。
当data数据发生改变时也会执行。
computed中定义的data变量(类似方法的形式)只会被计算一次,之后会加入缓存中,之后在取值时,直接从缓存中获取。
computed:{ ageAndName(){ return this.name+this.age; }
}
directives
定义局部指令
watch
进行监听,将html中的数据放到data中(mvvm中 v–>m),当数据发生变化时,触发监听
watch:{ name:function(value){ this.name1= value; } }
components
定义组件
filters
定义过滤器
生命周期的函数
语法
插值表达式 {{}}
显示内容,只会替换自己的这个占位符,不会吧整个元素的内容清空
<h1>{{name}}2222222</h1>
name:"helloword"
输出
helloword2222222
v-clock:
能够解决插值表达式闪烁的问题
出现的原因:跟生命周期有关
vue会先加载html文件,然后加载js文件,最后进行替换(vue数据)
解决方案:先将元素隐藏,当加载完毕之后在进行显示
定义
<style> [v-clock] { display: none; } </style>
使用
<p v-cloak>{{msg}}</p>
使用v-clock能够解决插值表达式闪烁的问题,当网络较慢的时候{{msg}}会显示在页面中
v-text:
显示内容,但是会覆盖元素中的原本内容
<h1 v-text="name">222222</h1>
name:"helloword"
输出
helloword
v-html:
带渲染的显示,节点操作
<h1 v-html="site"></h1>
site:"<a href='https://www.baidu.com'>百度</a>",
v-bind:
或 :
给html标签的属性绑定值
他的缩写是 :
<a v-bind:href="link">百度</a>
<a :href="link">百度</a>
v-on:
或 @
事件的绑定
<button v-on:click="sayHello">sayHello</button>
<button @click="sayHello">sayHello</button>
<button @click="sayHelloName('ssss')">sayHelloName</button>
无参函数中的()
可写可不写
有参函数需要传参的时候需要加上()
v-model
可以实现 表单元素和model中的数据实现双向绑定
用户名:<input type="text" v-model="name"/>
注意:
将data中的数据传到html中 插值表达式
{{}}
,v-text:
,v-html:
,等方式将html中的数据传到data中:
通过监听watch
通过vue对象
vm.$watch('name', function(value){ this.age= value; })
vue引入css
通过class
定义css
<style> .mystyle1{ background-color: blue ; width: 100px; height: 100px; } </style>
css绑定到data
css1 : 'mystyle1'
html元素使用css
<h3 :class="mystyle1">1111111</h3>
注意
vue的css样式引入可以与传统的css样式引入共存
<h3 class="mystyle3" :class="css1">info:{{info}}</h3>
:class的值 是一个对象
{k1:v1,k2:v2...}
如果对象中的变量值true,则生效;否则不生效<h3 :class="{mystyle1:istrue, mystyle3:isfalse}" >111111</h3>
istrue和isfalse在data中定义,根据他们的值来判断样式是否生效,当
istrue=true;isfalse=false;
时,mystyle1生效,mystyle3不生效值可以同时为true或false
绑定数组
[]
<h3 :class="['mystyle1', 'mystyle3']">11111</h3>
同时生效
vue取值有一个特点:取的值是变量,变量名是在data中定义的。
通过style
语法:
:style={样式名:样式值(<从data中获取>),x:x,...}
<h3 :style="{backgroundColor:x,color:y}">info000000:{{info}}</h3>
x:'lightgray' ,
y:'purple',
注意:
属性的名字不能使用xxx-yyyy(中间使用-
符号),而需要使用 xxxYyyy(驼峰命名)
条件渲染
v-if
和v-else
<h3 v-if="istrue">1111</h3>
<h3 v-else>222</h3>
isture在data中定义,当为真时显示111,为假时显示222
v-show
<h3 v-show="isture">111</h3>
<h3 v-show="!isture">222</h3>
注意:v-if
和v-show
的区别
v-show可以在源码中追踪到隐藏的元素,即隐藏的元素可以在源码中找到;
v-if无法追踪,即隐藏的元素,在源码中找不到;
循环遍历
<!-- 遍历一个具体对象 (一个对象有很多属性:name age )-->
<ul>
<li v-for="(value,name) in students[2]" :key="name" >
{{value}} --{{name}}
</li>
</li>
</ul>
value
:对象属性的值
name
:对象的属性名
students[2]
:对象数组中的一个元素(即一个对象)
遍历对象
遍历对象数组
<ul>
<li v-for="(s,index) in students" :key="index" >
{{index}} - {{s.name}} - {{s.age}}
</li>
</ul>
students: [
{name:'zs', age:23},
{name:'ls', age:24},
{name:'ww', age:25},
{name:'zl', age:26},
{name:'sq', age:27}
] //对象数组
s
:数组的每一个元素
index
:下标
students
:数组
:key
:唯一值
注意:想要获取data中的数据,需要通过this.
来获取
删除数组元素:splice
//删除完毕后,数组元素 会自动重新排序
this.students.splice(index,1);
从下标index起删除1个
更新数组元素:splice
this.students.splice(index,1,stu);
将下标为index的数组元素更新为stu对象
筛选
组成:查询的条件,新数组
定义查询条件(即定义data中数据)
queryname: “ //筛选条件
具体实现方法(在computed中定义,函数名就是变量,即新数组)
//筛选后的新数组 queryStuentsResult(){ // 新数组的值 var queryStudents ;//s //筛选条件 // var queryname = data中定义的queryname ; // var student2 = data中定义的数组students ; var {queryname,students} = this ;//this 就是data //根据查询条件,筛选出新数组 queryStudents = students.filter( stu=>stu.name .indexOf(queryname ) > -1 ) return queryStudents ; }
排序
定义升降序变量(0:升序,1:降序)
ordered: 0
对queryStudents对象数组中的元素,根据
age
属性进行排序//排序 queryStudents.sort( function(s1,s2) { if(ordered ==0){//升序 return s1.age - s2.age }{//降序 return s2.age -s1.age } })
升序:第一个 - 第二个
降序:第二个 - 第一个
别忘了
return
传播行为与事件
传参当前对象
<input type="button" value="按钮1" @click="myclick" />
<!--错误行为-->
<!-- <input type="button" value="按钮" @click="myclick()" /> -->
<input type="button" value="按钮2" @click="myclick2($event)" />
传当前对象时,要么不写,要么添加($event)
,不能只写()
这样会报错
获取对象
myclick(event){
alert( event.target.value )
},
myclick2(event){
alert(event.target.value )
},
event.target:当前对象
注意:在vue中结尾符;
可写可不写(要么都写,要么都不写)
事件的传播行为(propogation)
<div :class="css1" @click='myclick3()'>
outer
<div :class="css2" @click='myclick4()'>
inner
</div>
</div>
myclick4(){
alert('inner' )
},
myclick5(){
alert('link...' )
},
结果:
点击:inner时,会触发outer的点击事件
阻止行为:
<div :class="css1" @click='myclick3()'>
outer
<div :class="css2" @click.stop='myclick4()'>
inner
</div>
</div>
阻止默认行为
<a href="https://www.baidu.com" @click.prevent='myclick5()'>百度</a>
myclick5(){
alert('link...' )
},
注意:.xxx可以嵌套着使用
键盘点击事件
keydown
按键 按下事件
<input @keydown='myclick6'>
myclick6(event){
//event.target :当前dom对象
//event.keyCode:按键的值 a : 65
alert( event.keyCode +'--'+ event.target.value )
},
keyup
按键弹上去事件
指定按键触发事件
<input @keyup.13='myclick6' >
指定的按键按下抬起时才触发的事件
每一个键盘的按键都对应着一个键码值
表单输入绑定
<form action="" @submit.prevent="mysubmit">
用户名:<input type="text" v-model="user.username" ><br>
密码:<input type="password" v-model="user.password" ><br>
性别:
<input type="radio" value="male" v-model="user.password">男<br>
<input type="radio" value="female" v-model="user.password">女<br>
兴趣:
<input type="checkbox" value="football" v-model="user.hobbies">足球,
<input type="checkbox" value="basketball" v-model="user.hobbies">篮球,
<input type="checkbox" value="pingpang" v-model="user.hobbies">乒乓球,
城市:
<select name="" id="" v-model="user.city">
<option :value="c.id" v-for="c in optionalCities">
{{c.name}}
</option>
</select>
<input type="submit" value="注册">
</form>
data:{
user:{
username: '' ,
passowrd: '' ,
sex: 'male',
hobbies: [] ,
city: '' //选中
},
//可选
optionalCities: ["js","bj","sh"]
},
这里只列出了部分的用法详细的用法参考官网手册(http://doc.vue-js.com/v2/guide/forms.html)
意义:如果给后台传递一个form表单的数据,不用再 一个一个的获取每个input等元素的值;而可以一次性传递一个对象
生命周期
作用
生命周期的作用:某个动作 都有一个流程,当执行到该流程的某一个阶段时,会自动触发一些函数
注意:生命周期函数与methods和el等标签同级
详细的说明参见官方文档(https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA)
动画效果
显示:Enter
隐藏:Leave
三个阶段:
初始阶段:
v-enter/v-leave
过渡阶段:
v-enter-active / v-leave-active
结束阶段:
v-enter-to/v-leave-to
v-
是这些类名的前缀。使用 <name="my-transition">
可以重置前缀,比如 v-enter
替换为 my-transition-enter
。
过滤器
{{ message | filterA | filterB }}
{{msg | 过滤器1 | 过滤器2 }}
moment.js
时间格式化,去官网下载js文件
引入
注册过滤器
//过滤:注册->使用 (西方日期 ->格式) //es6:函数默认参数值
Vue.filter('dateFilter' , function(value, dateFormat='YYYY-MM-DD HH:mm:ss' ){
return moment(value).format(dateFormat) ;
})
使用过滤器
{{ now | dateFilter('YYYY-MM-DD')}}
自定义指令
v-text-upper
v-text-lower
定义指令的名字是v-
是不需要我们写的,只需要写右边的部分即可
全局指令
与var vm = new Vue({})
同级(与全局变量定义类似)
注册全局指令
Vue.directive('text-upper',function(el,binding){ el.innerHTML= binding.value.toUpperCase(); })
使用
<p v-text-upper="myVariable"></p> myVariable : "Hello World",
局部指令
在var vm = new Vue({})
中定义 (与局部变量定义类似)
注册局部指令
//注册局部指令 directives:{ 'text-lower' :{ bind(el,binding){ el.innerHTML= binding.value.toLowerCase(); } } }
使用
<p v-text-upper="myVariable"></p> myVariable : "Hello World",
自定义插件
详细参见官方文档
开发插件
例
(function(){
const MyPlugin = {} ;
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
alert('全局方法或属性');
}
// 2. 添加全局资源
Vue.directive('my-directive', {//v-text-upper
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
})
// 3. 注入组件选项 .每次实例vue对象中调用一次
Vue.mixin({
created: function () {
// 逻辑...
alert('mixin');
}
})
// 4. 添加实例方法(局部)
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
alert('局部') ;
}
}
//将插件 暴露给外部使用
window.MyPlugin = MyPlugin ;
})()
使用插件
引入(js文件)
使用插件
Vue.use(MyPlugin); //全局:static //类名.静态方法() Vue.myGlobalMethod(); //对象.方法() vm.$myMethod();
vue脚手架开发
vue脚手架指的是vue-cli,它是一个专门为单页面应用快速搭建繁杂的脚手架,它可以轻松的创建新的应用程序而且可用于自动生成vue和webpack的项目模板。
安装
npm install -g vue-cli
下载模板
vue init webpack my_vue_cli
需要配置一些基本信息,不配置的话就一路回车
注意: 根据提示 安装附加组件,安装时输入项目名时不能包含大写字母。安装时,不要随意点鼠标,点击鼠标右键可以恢复。
根据提示
cd my_vue_cli
npm run dev
打包运行项目
生成dist目录
npm run build
安装服务组件(静态服务)
npm install -g serve
运行 serve dist
动态服务(tomcat)
配置
webpack.prod.conf.js
output: { ... publicPath: '/myvue/' -->配置访问时的项目名
打包成dist
将dist拷贝到tomcat/webapps中,并且再将dist修改成myvue
启动tomcat,运行
vuecli源码解读
npm run dev 触发了哪些文件
dev ->package.json ->build/webpack.dev.conf.js ->./webpack.base.conf ->./src/main.js引用时的名字叫app
根据web基础知识可知:
http://localhost:8080
实际是访问http://localhost:8080/index.html
index.html:
<div id="app"></div>
->会被src/App.vue中的<div id="app">
内容注入:
src/App.vue中内容
<router-view/>
:路由,映射关系 localhost:8080/b–> xxx本项目的映射: localhost:8080/ –>HelloWorld.vue配置路由:
<router-view/>
: router/index.js 文件
小结
npm run dev -> main.js
localhost:8080 / :index -> router -> HelloWorld.vue中的内容
app.vue中直接引入helloworld.vue
引入helloworld.vue
<script> import HelloWorld from './components/HelloWorld'
将引入的文件打成一个组件
export default{ xxxxxx, components:{ HelloWorld } }
使用组件
以标签的形式使用
<HelloWorld></HelloWorld>
ESlint
代码规范检查工具,官网
可以检测
- 空格个数
- 空行
- 变量名
- 代码是否未被使用
- …
如果不规范,则警告 或报错
检测规则
- “off” 或 0 - 关闭规则
- “warn” 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
- “error” 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
设置某些检查规则:.eslintrc.js
文件
全局设置是否启用ESlint:.eslintignore
文件
注意:
初学:关闭
真实的开发项目:打开,帮助规范代码的编写
vue文件
组成
<template>
<script>
<style>
export default {
name: '名字' ,
data(){
return msg: 'xxx'
},
omputed:{},
methods:{},
components:{//组件}
}
vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。 vuex中文官网
根据官网的流程图来理解Vuex
状态自管理应用包含以下几个部分:
- state, 驱动应用的数据源;
- view,以声明方式将state映射到视图;
- actions, 响应在view.上的用户输入导致的状态变化。
他们时单向不可逆的,我们已简单的数字自增来举例,在state中定义一个变量count,显示在view组件上,通过actions来操作state,state变化后,view中也随之改变。
但实际中vuex还有一个部分 mutations,根据官网的第二张图,我们发现action通过commit调用了Mutations,Mutations通过Mutate调用State,State通过Render来调用view,view通过dispatch来调用Action。此时就有点像mvc模式,actions和Mutations的关系就像service和dao的关系一样,Mutations会执行一些原子性的操作,而actions会做一些带逻辑性的操作;如删除操作,Actions会先判断存不存在,当存在的时候在进行删除,而Mutations则只进行删除操作。
开发一个简单的状态管理
安装vuex依赖
npm install --save vux
新建./src/store.js文件
import Vue from 'vue'
import Vuex from 'vuex'
//使用vuex
Vue.use(Vuex)
//定义共享变量
const state = {
count :0
}
//直接操作共享变量的对象
const mutations={
mulincreases(state){
state.count++;
}
}
//操作mutations的对象
const actions={
actioncrease({commit}){
commit('mulincreases');
}
}
//将store.js中的对象暴漏给外界 ,用于其他组件的共享
export default new Vuex.Store({
state,
mutations,
actions
})
封装对象
我们发现要想将对象暴漏给外界,当需要暴漏的对象太多的时候,就会很麻烦,因此我们可以将要暴漏的对象给封装起来。
在前面我们可知,程序在启动时会自动触发src/main.js文件。因此,思路:可以将store.js中暴露的多个对象,封装到main.js中。
例:
//引入准备封装的文件
import store from "./store"
new Vue({
//xxxx
store//注入store对象
})
此时我们需要引用需要暴漏的对象时只需要使用store.xxx
即可使用。
新建组件使用变量
组件其实就是一个.vue的文件
我们在app.vue中使用变量
src/main.js -》store ->App.vue
程序的启动顺序,先main.js(store) ->App.vue 因此,在使用App.vue时,已经加载过了store,因此在App.vue中可以直接使用store,使用方式:$store
{{$store.state.count}}
通过这种方式使得变量count显示在页面上
{{$store.state.count}}
<button @click="countinc">+</button>
<script>
export default{
methods:{
countinc(){
//注意$store是一个全局对象需要使用this来拿
return this.$store.dispatch('actioncrease')
}
}
}
</script>
通过this来获取$store对象
执行
npm run dev
异步实现自增 acioncrease
只需要添加并使用此方法
//异步自增
asyncincrease({commit}){
setTimeout(()=>{
commit('mulincreases')
},2000)
}
两种取值方式
{{$xxx}}
方式{{$store.state.count}}
数据来自store.js–>getters–>isAudlt(){…}
方法取值
<button @click="countinc">+</button>
数据来自:store.js–>actions–>actincrease({commit}){}
优化取值
直接使用isAudlt(){…}和actincrease({commit}){}进行取值
vuex中自带了两个对象
import {mapGetters,mapActions} from 'vuex'
- mapGetters 可以获取getters中的方法
- mapActions 可以获取Actions中的方法
如
computed:mapGetters({
isAudlt : 'isAudlt'//将store.js中getters中的isAudlt()映射成isAudlt对象(前面的是属性,后面的是getters中的方法)
})
methods:mapActions(['actioncrease','asyncincrease']),
使用
{{isAudlt}}
<button @click="actioncrease">同步+</button>
<button @click="asyncincrease">异步+</button>
思路:
以前需要通过$store获取store. js中的getter方法和actions方法现在可以直接通过mapGetters, mapActi ons获取store. js中的getter方法和actions方法
vue-resource的使用
官网 相当于ajax、axios
get(url, [config])
post(url, [body], [config])
请求的方式config的作用,当表单发送请求时,需要加上{emulateJSON:true},默认不加也行,但是为了防止某些特殊的情况建议还是加上。在前端,表单提交时一般加上:application/x-www.form-urlencoded,两者作用相似
body参数时传递的参数值;一般是采用对象的方式进行传参
this.$http.get("请求地址",{},{emulateJSON:true}).then(reponse=>{
consolg.log(resoonse);
})
- jsonp(url, [config])
支持跨域
如果前台和后台的地址、端口、协议不一致(只要任何一个不一致)就称为跨域请求。为了安全,浏览器一般都禁止跨域请求
解决:使用js技术替代了传统的http请求
使用node.js搭建服务器
const http = require('http')
const urlModule = require('url')
//localhost:8080/myrequest?cb=myshow
//localhost:8080/myrequest2
//创建服务
let server = http.createServer();
//servlet: doGet(request,resposne)
server.on('request', function(req,res){
console.log('abcc')
const { pathname ,query } = urlModule.parse( req.url ,true)
if( pathname == '/myrequest'){
var data = {
id : 1,
name :"zs",
age :23
}
//响应到哪里?
//localhost:8080/myrequest?cb=myshow
//myshow(data) //data->json
//响应到:myshow方法,并响应的数据:data
var result = `${query.cb}( ${JSON.stringify(data)} )`
res.end(result)
}
})
server.listen(8888,function(){
console.log('sever running...')
})
客户端
<html>
<head>
<meta charset="utf-8">
<title>111</title>
<script src="./js/vue.js"></script>
<script src="./js/vue-resource.js"></script>
<script>
function myshow(data){
console.log(data)
}
</script>
<script src="http://localhost:8888/myrequest?cb=myshow"></script>
</head>
<body>
</body>
</html>
客户端仅仅是引入了一个文件并没有发送请求
Promise的使用
将嵌套方式变成链式写法
读取多个文件的嵌套写法
const fs = require('fs')
const path = require('path')
//读取文件的内容
function myReadFile(fpath,frsuccess,frerror){
//读取文件时,如果由异常:err
//数据正常保存data
fs.readFile(fpath,"utf-8",(err,data)=>{
if(err) return frerror(err)
frsuccess(data)
})
}
//调用 js/file1.txt
//先读取file1.txt,之后读取file2。txt
//读取file1.txt-->成功之后读取-->file2.txt
myReadFile(path.join(__dirname,'./file1.txt'),(data)=>{
console.log(data)
myReadFile(path.join(__dirname,'./file2.txt'),(data)=>{
console.log(data)
},(err)={})
},(err)=>{console.log(err.message)})
读取文件的链式写法
const fs = require('fs')
const path = require('path')
function myReadFile(fpath){
return new Promise((resolve,reject)=>{
fs.readFile(fpath,'utf-8',(err,data)=>{
if(err) return reject(err)
resolve(data)
})
})
}
//调用
// ./代表根目录
myReadFile('./js/file1.txt').then((data)=>{
console.log(data)
return myReadFile('./js/file2.txt')
},(error)=>{
console.log(error)
}).then((data)=>{
console.log(data)
}).catch((e)=>{
console.log(e)
})
.catch 可以统一处理错误
promise的核心:return+then跳出递归
vue组件
vue的三大组成部分
<template> html(组件)
<script> 存放js
<style> 存放css
定义一个简单的组件
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="./js/vue.js"></script>
</head>
<div id="myvue">
<mycom></mycom>
</div>
<script>
Vue.component('mycom',{template:"<h1>这是我的组件</h1>"})
new Vue({
el:'#myvue'
});
</script>
</html>
注意:
组件名不要使用驼峰命名法,如果使用,则使用该组件的时候使用-
符号隔开
组件定义方式
官网方式
Vue.component('mycom',{template:"<h1>这是我的组件</h1>"})
完整写法
Vue.component('mycom',Vue.extend({template:"<h1>这是我的组件</h1>"})
官网方式的id引用的方式
<template id="mytemp1"> <h1>这是我的组件</h1> </template> Vue.component('mycom',{template:"#mytemp1"})
完整方式的id引用方式
<template id="mytemp1"> <h1>这是我的组件</h1> </template> Vue.component('mycom',Vue.extend({template:"#mytemp1"})
注意:定义组件时template:""
的值和 <template></template>
标签中的内容必须是标签,否则会出错
这种方式定义的组件是全局组件,在所有的Vue对象中都可以使用。
私有组件/局部组件:只能在选定的Vue对象中使用
new Vue({
el:'#myvue2',
components:{
'mycom1':{template:"<h1>这是我的组件</h1>"}
}
});
其它的创建方式如上
除了定义组件内容之外还可以在组件中定义数据,定义数据的方式如下:
data:function)(){
return {
count:0
}
}
注意:定义的数据必须是function,因为function中定义的变量是局部变量,为了防止多个组件之间共享数据,从而使得定义的组件的数据是独立的。
特殊特性 is
vue中自带一个标签<component></component>
是一个组件标签,占位符
<component :is="'comp'"></component>
<!-- 或 -->
<component :is="c"></component>
data:{
c:'comp'
}
一般vue:xx=xxx
值一般是变量,而我们定义的组件名是一个常量,要想将一个常量值变成一个变量值,只需要添加''
即可。而变量值是在data中定义的,如果不加''
只需要在data中定义变量,其值为组件名即可。
实现动态组件
只需要将:is
绑定的值改变,就能实现动态组件。而:is
中的值在data中定义,一次只需要改变data中变量的值即可。
<span @click="c='coma'">切换A</span>
<span @click="b()">切换A</span>
methods:{
b(){
this.c="comb"
}
}
注意:行内写法不需要加this
,而函数写法需要加this
什么时候加this
在Vue对象中除了
data
之外的所有区域使用data
中的数据时,都需要使用this
在页面中使用
{{}}
取data
中值是可加this也可不加this
一般结论:大多数的情况下,只要获取data
中的变量的时候都需要使用this
,除了个别特殊的情况,如:行内式写法、
组件的过渡效果和参数传递的问题
将过度组件放入
<transition></transition>
标签中编写样式在
<style></style>
标签中编写css样式<style> .v-enter, .v-leave-to{ opacity: 0 ; transform: translateX(100px) ; } .v-enter-active, .v-leave-active{ transition: all 1s ease ; } </style>
<transition>
的mode="out-in"
属性可以设置出现的顺序,这样的话能避免重合。
传参
<coma :msg="aname"></coma>
Vue.component('coma',
{
template:" <p>这是我的组件A {{msg}}</p>",
props: ['msg']
}
)
data:{
aname :"你好,世界"
}
:msg
,msg是自己定义的属性名,他的值是一个变量aname
,在data
中定义。组件在使用msg
属性的值的时候不能直接使用,需要借助props
中转,然后进行使用。
注意:组件中参数引用的位置一定要在标签中,否组Vue不认识它。
组件的简化写法
公有组件
var comc = { template: '<p>这是组件C</p>' } Vue.component('comc',comc) <comc></comc>
共有组件与Vue对象同级,在Vue对象的外面写
私有组件
var mycomc = { template: '<p>这是组件C</p>' } components:{ 'mycomc': mycomc } <mycomc></mycomc>
注意:当组件名和变量名是同一个时可简化,只写组件名或变量民即可。
例上面可以简化为:
components:{
mycomc
}
小结:简化的核心就是使用var变量保存组件,然后通过引用变量实现自定义组件。
调用组件内部的方法
普通的方法调用
<button @click="aa()">点击事件</button>
methods:{
aa(){
alert("hahahah")
}
}
调用的方法时vue中的methods中定义的方法
定义的组件的方法的调用
组件常用的定义方式
定义组件内容
<template id="mytempid"> <button @click="myclick">方法调用</button> </template>
完善组件结构
var com = { template : '#mytempid' , data(){//局部变量 ,xx(){return {k:v}} return { comdata:{ num:1 } } }, methods:{ myclick(){ this.$emit('mycomclick',this.comdata.num) //myshow(a) } } }
注册到Vue中
公有组件
Vue.component('com',com)
私有组件
components:{ //com:com com } }
使用
通过标签使用
<com @mycomclick='myshow'></com>
组件中的单击事件调用的不是Vue中的Methods中定义的方法,而是组件中methods中定义的方法。
调用组件内部按钮中的方法:单击–>组件中的method–>vue中的method
小结:组件的单击事件<button @click="myclick">
调用组件中的methods
中定义的单击函数myclick
;组件中定义的函数通过this.$emit
触发组件自定义的事件 <com @mycomclick>
, 组件的自定义事件调用Vue中定义的事件函数
myshow
,从而实现事件的点击。
核心思路:
普通的Html对象:直接调用Vue中的Methods中定义的函数
如果是组件,则调用组件中methods定义的方法,接着通过组件中的methods调用Vue中的methods
细节:组件中传递方法时: 发:自定义事件 收:$emit
当函数需要传参时this.$emit('mycomclick','hello')
hello就是第一个参数,传多个参数时,通过,
隔开
this所在位置
当在组件中使用this时,代表当前组件,当需要使用data中的数据时需要通过this.comdata.xxx
来获取变量
当在Vue中使用this代表当前Vue对象,想要使用data中的数据时,需要使用this.xxx
来获取变量。
refs
相当于jquery中的选择器
在jquery中:
定义
id="myid"
使用
$("#myid")
在vue中:
定义
ref="myref"
使用
this.$refs.myref
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="./js/vue.js"></script>
</head>
<div id="myvue">
<!--普通元素-->
<div ref="mydiv">
这是div元素...
</div>
<!-- 组件-->
<com ref="mycom"></com>
<button @click='myVueShow'>调用vue中的方法</button>
</div>
<template id="mytempid">
<div>普通组件...</div>
</template>
<script>
var com = {
template : '#mytempid' ,
data(){
return {
mymsg:'组件内部的数据'
}
},
methods:{
myComponentShow(){
alert('这是组件中的方法...')
}
}
}
const vm = new Vue({
el : "#myvue",
data:{
},
methods:{
myVueShow(){
//alert('myvueshow...');
//alert(this.$refs.mydiv.innerText)
//获取组件中定义的mymsg数据
//alert(this.$refs.mycom.mymsg)
//调用组件中定义的方法
this.$refs.mycom.myComponentShow()
}
},
components:{
//com:com
com
}
}
);
</script>
</html>
refs的作用:获取某个元素、组件,调用组件中的属性、方法、数据等信息
render函数
把组件模板(template)渲染成html(替换之前的内容)
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="./js/vue.js"></script>
</head>
<div id="myvue">
<div>
这是div元素...
</div>
</div>
<template id="mytempid">
<span>普通组件...</span>
</template>
<script>
var com = {
template : '#mytempid'
}
const vm = new Vue({
el : "#myvue",
data:{
},
methods:{
},
render:function(createElements){
return createElements(com) //该方法的参数,就可以将组件渲染成html
}
}
);
</script>
</html>