一、MVVM
View,Model是Vue.js的核心。
实例化Vue的过程就是定义MVVM各个组成部分的过程。
1. 定义View
2. 定义Model
3. 创建一个Vue实例或"ViewModel",它用于连接View和Model
举例:
<!--这是View-->
<div id="app">{{message}}</div>
//创建一个Vue实例,它连接 View 与Model
new Vue({
el: '#app', (连接)
//这是Model
data:{
message:'Hello World!'
}
})
在vue中要使用data中定义的参数,用this.message
(angularjs中用$scope.message)
与angulajs的区别:angularjs需要ng-app和ng-controller,vue直接用id即可;angularjs定义数据$scope.参数名,vue要在data:中定义,方法也要在methods或者computed中定义,若要在方法中使用参数,要用this.参数名
二、指令
1.数据绑定
1)v-text={{}} (angular js 是 ng-bind和{{}})
(这两个是一样的,{{xxx}},这种情况是有弊端的,当网速很慢或者javascript出错时,会暴露{{xxx}})
<span v-text="message"></span>=
<span>{{message}}</span>
2).v-html
(有html标签,用v-text是输出不出来的)
<div v-html="message"></div>
new Vue({
el: '#app',
data: {
message: '<h1>菜鸟教程</h1>' } })
得到<div>
<h1>菜鸟教程</h1>
</div>
在生产环境中动态渲染HTML是非常危险的,因为容易导致XSS攻击。所以只能在可信的内容上使用v-html,永远不要在用户提交和可操作的网页上使用v-html。
2.判断
1)v-show(angularjs中是ng-show)
根据表达式之真假值,切换元素的 display CSS 属性。(DOM已经加载出来了)
2).v-if和v-else和v-else-if(angularis中是ng-if、ng-else)
v-else和v-if一起出现,且里面不用放参数,和if相反
用来判断是否加载html的DOM(DOM还没有加载出来)
- • v-if: 判断是否加载,可以减轻服务器的压力,在需要时加载。
- • v-show:调整css dispaly属性,可以使客户端操作更加流畅。
v-if的安全级别更高,v-show只是隐藏了,通过页面源代码还是可以看到,安全级别低、
v-if更高的切换消耗(切换消耗指从未加载到加载或者从加载到未加载的状况,需要添加或删除这个元素),v-show需要更高的初始化渲染消耗
因此如果需要频繁切换而对安性无要求,使用v-show;如果运行时,条件不能改变,使用v-if
3.循环v-for(angularjs是ng-repeat=“(key,value) in values”索引在前面)
(item,key)索引值放在后面!!
还可以(index, key,item)
<div v-for="(value, key, index) in object">
(自己试吧)
<li v-for="item in items">
{{item}}
</li>
v-for的应用:排序
用到了Vue的computed:或methods:属性。定义方法的属性
定义
var app =new Vue({
el:"#app",
data:{
items:[20,23,18,65,32,19,5,56,41]
},
computed:{
sortItems:function(){
//这个现成的sort方法只能给位数一样的进行排序,所以调用了sortNumber这个方法,这个方法在后面定义,记住这个方法即可
return this.items.sort(sortNumber);
}
},
methods:{
methodSort:function(){
return this.items.sort(sortNumber);
}
}
})
function sortNumber(a,b){
return a-b
}
直接用sort方法只能排序同样位数的,所以要用sortNumber
调用computed和methods的方法时,都可以不加()
计算属性 :和普通属性一样是在模板中绑定计算属性的,当data中对应数据发生改变时,计算属性的值也会发生改变。
Methods:methods是方法,只要调用它,函数就会执行。
相同:两者达到的效果是同样的。
不同:计算属性是基于它们的依赖进行缓存的,只有相关依赖会发生改变时才会重新求职。只要相关依赖未改变,只会返回之前的结果,不再执行函数。
<div>{{sortItems}}</div>
<div>{{methodSort}}</div>
v-for循环数组,对象都可以
students:[
{name:'jspang',age:32},
{name:'Panda',age:30},
{name:'PanPaN',age:21},
{name:'King',age:45}
]
<ul>
<li v-for="student in students">
{{student.name}} - {{student.age}}
</li>
</ul>
4.事件监听v-on
v-on:事件=“方法”
v-on: 还有一种简单的写法,就是用@代替。
<button @click="jianfen">减分</button>
<button v-on:click="jiafen">加分</button>
<button v-on:click="jianfen">减分</button>
var app=new Vue({
el:'#app',
data:{
count:1
},
methods:{
jiafen:function(){
this.count++;
},
jianfen:function(){
this.count--;
}
}
})
键盘回车事件v-on:keyup.enter,
回车:@keydown
常用:@keyup
@mousedown
@mouseover
@submit
https://www.cnblogs.com/xcsn/p/3413074.html
阻止冒泡:event.stopPropagation(); 或者直接 @click.stop="方法"(事件修饰符)
阻止默认事件:event.preventDefault() 或者直接@submit.prevent(事件修饰符)
5.数据双向绑定v-model(和angularjs中的ng-model是一样的)
必须用input框(或者其它textarea、 radio等), 使用时必须先在data中定义一下。
<input type="text" v-model="message">
6.属性v-bind(一切css样式都可以绑定)
可以省略写:
<a :href="url"></a>
<img v-bind:src="imgSrc" width="200px">
经常使用v-bind来绑定css样式
1)、直接绑定class样式
<div :class="className">1、绑定classA</div>
2)、绑定classA并进行判断,在isOK为true时显示样式,在isOk为false时不显示样式。
<div :class="{classA:isOk}">2、绑定class中的判断</div>
3)、绑定class中的数组
<div :class="[classA,classB]">3、绑定class中的数组</div>
4)、绑定class中使用三元表达式判断
<div :class="isOk?classA:classB">4、绑定class中的三元表达式判断</div>
5)、绑定style
<div :style="{color:red,fontSize:font}">5、绑定style</div>
6)、用对象绑定style样式
<div :style="styleObject">6、用对象绑定style样式</div>
var app=new Vue({
el:'#app',
data:{
styleObject:{
fontSize:'24px',
color:'green'
}
}
})
7.其它指令
1)v-pre指令
在模板中跳过vue的编译,直接输出原始值。就是在标签中加入v-pre就不会输出vue中的data值了。
<div v-pre>{{message}}</div>
页面会显示{{message}}
2)v-cloak指令( 类似ng-clock解决未加载完的问题)(不会用)
在vue渲染完指定的整个DOM后才进行显示。它必须和CSS样式一起使用,
[v-cloak] {
display: none;
}
<div v-cloak>
{{ message }}
</div>
3)v-once指令
在第一次DOM时进行渲染,渲染完成后视为静态内容,跳出以后的渲染过程。
<p>可以改变:{{ msg }}</p>
<p v-once>不可以改变:{{ msg1 }}</p>
(vue.js 较少用到自定义指令,因此就不放在这了)
三、组件(标签)(定义时data必须是function,return数据)(可以extend定义后,再用component,直接定义比较简单易懂)
Component组件
1、初始组件
组件就是制作自定义的标签,这些标签在HTML中是没有的。
1)、全局化注册组件(全局的也必须放在vue作用域的里面才管用)
<div id="app">
<jspang></jspang>
用<jspang></jspang>代替template中的内容
</div>
这种只能定义一个,一个组件名定义一个组件,所以是component
Vue.component('jspang组件名',{
template:`<div style="color:red;">全局化注册的jspang标签</div>`
})
var app=new Vue({
el:'#app',
data:{
}
})
2)、局部注册组件局部注册组件和全局注册组件是向对应的,局部注册的组件只能在组件注册的作用域里进行使用,其他作用域使用无效。
<div id="app">
<panda></panda>
</div>
var app=new Vue({
el:'#app',
可以定义多个,所以要加s
components:{
"panda":{
template:`<div style="color:red;">局部注册的panda标签</div>`
}
}
})
3)、组件和指令的区别
组件注册的是一个标签,而指令注册的是已有标签里的一个属性。之后会在标签中加属性。Angularjs 就擅长用指令,在实际开发中还是用组件比较多,指令用的比较少。因为指令看起来封装的没那么好。
2、父子组件间的传值
1)父传子
parent: <template id="p">
<sub :id="id"></sub>
</template>
new Vue({
el:"#p",
data:{ id:10} ,
sub: compoments:{
sub:template:"<h1>{{id}}</h1>",
props:["id"]
}
2)子传父
parent: <template id="p">
<sub @send="getdata"></sub>
</template>
new Vue({
el:"#p",
methods:{
getdata(input){
alert(input);
}
},
sub: compoments:{
sub:template:"<div><button @click="senddata"></button></div>",
methods:{
senddata(){
this.$emit("send","hello");
}
}
}
四、过滤器
内置过滤器全部取消
1、私有过滤器
<div id="app">
<td>{{col|capitalize}}</td>
</div>
new Vue({
el: '#app',
data: {
col:asdasd
},
filters: {
capitalize: function (value) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
},
});
2、全局过滤器
<div id="app">
<!-- 首字符串大写 -->
<div>首字母大写过滤器:{{str | upcase}}</div>
<!-- 给过滤器传入参数 -->
<p>求和过滤器:{{message | sum(10,20)}}</p>
</div>
//全局方法 Vue.filter()注册一个自定义过滤器,必须放在Vue实例化前面
// 注册一个首字母大写的过滤器
Vue.filter("upcase", function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
});
// 全局注册一个求和过滤器
Vue.filter('sum', function (value, a, b) {
return value + a + b;
});
var demo = new Vue({
el: "#app",
data: {
str:'hello',
message:12
}
五、路由
<div id="app">
<div class="content">
<router-link to="/goods">商品</router-link>
<router-link to="/ratings">评论</router-link>
<router-link to="/seller">商家</router-link>
</div>
<router-view></router-view>
</div>
import goods from 'components/goods/goods';
import ratings from 'components/ratings/ratings';
import seller from 'components/seller/seller';
var router = new VueRouter
({
routes:[
{ path: '/goods', component: goods },
{ path: '/ratings', component: ratings },
{ path: '/seller', component: seller },
{ path: '/', redirect: seller }
];
})
var app = new Vue({
el: '#app',
router
});
路由传参:
<router-link :to="'/news/newsinfo/'+item.id"> 这块有了参数
{path:"/news/newsinfo/:id",component:newsinfo},
接受参数:created(){
this.id=this.$route.params.id;
再根据这个id请求数据等操作
},
六、ajax请求数据
目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目都会使用 Vuex 来管理数据。使用 、cnpm install axios -S
安装其他插件的时候,可以直接在 main.js 中引入并 Vue.use(),但是 axios 并不能 use,只能每个需要发送请求的组件中即时引入
首先在 main.js 中引入 axios
import axios from 'axios'
Vue.prototype.$ajax = axios
就可以在其它组件中使用
this.$ajax({
method: 'post',
url: '/user',
data: {
name: 'wise',
info: 'wrong'
}
})
}
this.$ajax({
method: 'get',
url,
}).then((res)=> {
console.log(res);
this.list=res.body;
});
用=>是因为this不指代vue了,所以用this
还有一种办法是:// let that = this (不能用var)