搭建并启动项目
脚手架搭建项目
vue init webpack my-project
vue init webpack-simple my-project(简单配置)
vue-cli3之后有变化,看下面这篇搭建过程
https://www.cnblogs.com/qq1272850043/p/9812421.html
安装依赖模块
npm install
启动项目
npm run dev
打包项目
npm run build
生成dist文件夹
关闭eslint校验
打开build中的webpack.base.conf.js文件,去掉下面的部分
基础语法
赋值:{{}}
渲染代码片段:v-html
双向数据绑定:v-model
绑定属性:v-bind:src :src
判断:
v-if=“true或false” 移除元素 相当于display:none
v-show=“true或false” 样式隐藏,不会移除元素
循环:v-for="(item,key) in list"
注意:vue只是监听数组,而不是在监听数组中数据的变化,所以直接改变数组中的值不会变化。
vue渲染数组包括两部分:1、调用原生方法,2、更新页面视图
点击事件:v-on:click @click
事件对象:@click=“eventFn($event)”
取消默认事件:@click.prevent=" "
阻止事件冒泡:@click.stop=" "
按键修饰符:@click.enter=" " @click.13=" "
DOM节点获取:ref
计算属性:computed (初始化的时候执行/相关数据改变的时候执行)
computed:{
方法名(){
retrun 数据的变动
},
对象:{
getter(){ //获取值
retrun 得到的数据
},
setter(value){ //监视,value为修改后的值
//进行值的设置
}
}
}
监视属性:watch
watch:{
监视值:function(新值,旧值) {
//注意这儿的this需要指向vm,如果用箭头函数则会有问题
数据处理
}
}
过滤器:
封装:
import moment from 'moment'
var filters = {
dateString(value,format){
return moment(value).format(format||'YYYY-MM-DD HH:mm:ss')
}
}
export default filters;
引入:
import filters from './model/filter.js'
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
使用:
<p>{{date | dateString}}</p>
<p>{{date | dateString('YYYY-MM-DD')}}</p>
<p>{{date | dateString('HH:mm:ss')}}</p>
自定义指令:
封装:
//自定义指令
var directives = {
'upper-text'(el,binding){
//el是标签
//binding是自定义标签的相关内容
el.textContent = binding.value.toUpperCase()
},
'lower-text'(el,binding){
el.textContent = binding.value.toLowerCase()
}
}
export default directives;
main.js引入:
//引入封装好的自定义指令
import directives from './model/directive.js'
Object.keys(directives).forEach(key => {
Vue.directive(key,directives[key])
})
使用:
<p v-upper-text="msg"></p>
<p v-lower-text="msg"></p>
render渲染函数
https://segmentfault.com/a/1190000015970367?utm_source=tag-newest
自定义插件:
封装自定义插件:
//封装自定义插件
var MyPlugin = {};
MyPlugin.install = function (Vue, options) {
//添加全局方法或属性
Vue.myGlobalMethod = function () {
console.log(111)
}
//添加全局资源
Vue.directive('my-directive', function (el, binding){
console.log(el)
el.innerHTML = binding.value.toUpperCase()
})
//添加实例方法
Vue.prototype.$showMessage = function (methodOptions) {
console.log(222)
}
}
export default MyPlugin;
使用插件:
//引入封装好的自定义插件
import MyPlugin from './model/myPlugin.js'
Vue.use(MyPlugin)
Vue.myGlobalMethod()
生命周期:
初始化数据,只执行1次=======================
beforeCreate():模板创建之前
created():模板创建之后
beforeMount():编译之前
mounted():编译之后
更新数据,可执行多次========================
beforeUpdate():数据更新之前
updated():数据更新之后
销毁数据===================================
beforeDestroy():销毁之前
destroyed():销毁之后
异步请求数据
vue-resource
axios
fetch-jsonp
语法实例
<template>
<div id="basic">
<!--Vue是MVVM框架,即数据和视图的互相渲染-->
<!--数据渲染-->
<h2>{{msg}}</h2>
<div v-html='html'></div>
<br>
<hr>
<br>
<!--绑定属性-->
<div :class="{box:isShow}" :style="color"></div>
<br>
<hr>
<br>
<!--判断-->
<p v-if="isOk">男</p>
<p v-else>女</p>
<p v-show="isOk">老</p>
<p v-show="!isOk">少</p>
<button @click="isOk=!isOk">更换</button>
<br>
<hr>
<br>
<!--循环渲染-->
<ul>
<li v-for="(item,key) in list">
{{key+1}}---{{item}}
</li>
</ul>
<ul>
<li v-for="(item,key) in list1">
{{key+1}}---{{item}}
</li>
</ul>
<button @click="update()">更新数据</button>
<h2>过滤排序</h2>
<input type="text" v-model="searchName">
<ul>
<li v-for="(item,index) in filPersons">
{{index}}--{{item.name}}--{{item.age}}
</li>
</ul>
<button @click="sortPer(1)">升级排序</button>
<button @click="sortPer(2)">降级排序</button>
<button @click="sortPer(0)">原本排序</button>
<br>
<hr>
<br>
<!--双向数据绑定-->
{{inputVal}}
<br>
<input type="text" v-model='inputVal'>
<br>
<hr>
<br>
<!--事件方法-->
<button @click="getMsg()">获取数据</button>
<button @click="setMsg()">设置数据</button>
<button data-aid='123' @click="eventFn($event)">获取事件对象</button>
<button ref="btn" @click="getDom()">Dom节点获取</button>
<button @click="getContent($event)">我是内容哦</button>
<h2>取消默认事件</h2>
<a href="http://www.baidu.com" @click.prevent="noLink()">跳转到百度</a>
<h2>阻止事件冒泡</h2>
<div style="width:200px;height:200px;background:red" @click="out()">
<div style="width:100px;height:100px;background:blue" @click.stop="inner()"></div>
</div>
<h2>按键修饰符</h2>
<input type="text" @keyup.enter="enter($event)" value="">
<br>
<hr>
<br>
<h2>计算和监视属性</h2>
<input type="text" v-model="firstName"><br>
<input type="text" v-model="lastName"><br>
(单向)<input type="text" v-model="fullName"><br>
(单向)<input type="text" v-model="fullName1"><br>
(双向)<input type="text" v-model="fullName2"><br>
<br>
<hr>
<br>
<h2>动画</h2>
<button @click="show=!show">显示隐藏</button>
<transition name="fade">
<p v-show="show">vue动画显示离开</p>
</transition>
<br>
<hr>
<br>
<h2>过滤器</h2>
<p>{{date}}</p>
<p>{{date | dateString}}</p>
<p>{{date | dateString('YYYY-MM-DD')}}</p>
<p>{{date | dateString('HH:mm:ss')}}</p>
<br>
<hr>
<br>
<h2>自定义指令</h2>
<p v-upper-text="msg"></p>
<p v-lower-text="msg"></p>
</div>
</template>
<script>
import filter from '../model/filter.js'
export default {
name: 'Basic',
component:'Basic',
data () {
return {
msg: 'Hello World',
html: '<div>这是代码片段</div>',
color: 'background:red',
isShow: true,
show:true,
isOk: false,
list: [],
list1:[
{name:'晓红',age:24},
{name:'逸轩',age:1},
{name:'逸筱',age:2}
],
persons:[
{name:'xiaohong',age:32},
{name:'yixiao',age:2},
{name:'yixuan',age:4},
{name:'yilian',age:1},
{name:'star',age:33}
],
searchName:'',
sortNum: 0 ,
inputVal: '我是model数据',
firstName:'A',
lastName:'B',
fullName1:'A B',
date:new Date()
}
},
methods:{
getMsg(){
alert(this.msg)
},
setMsg(){
for(var i=0;i<10;i++){
this.list.push('这是第'+i+'条数据')
}
},
eventFn(e){
console.log(e)
//获取对象本身e.srcElement
e.srcElement.style.background = 'red'
//获取自定义属性
alert(e.srcElement.dataset.aid)
},
getDom(){
console.log(this.$refs.btn)
this.$refs.btn.style.background='blue'
},
getContent(event){
alert(event.target.innerHTML)
},
noLink(){
alert('单纯点击,不跳转')
},
out(){
alert('我是外面的')
},
inner(){
alert('我是里面的')
},
enter(event){
alert(event.target.value)
},
update(){
//vue只是监听list,而不是在监听list中数据的变化,所以直接改变数组中的值不会变化
this.list1.splice(1,1, {name:'逸轩',age:2})
},
sortPer(sortNum){
this.sortNum = sortNum
}
},
computed:{
fullName(){
return this.firstName + ' ' + this.lastName
},
fullName2:{
get(){//获取
return this.firstName + ' ' + this.lastName
},
set(value){//监视
const arr = value.split(' ')
this.firstName = arr[0]
this.lastName = arr[1]
}
},
filPersons(){
const {persons,searchName,sortNum} = this;
let filPerson;
//按照名字过滤
filPerson = persons.filter(p => p.name.indexOf(searchName) !== -1)
//排序
if(sortNum!==0){
filPerson.sort((p1,p2)=>{
if(sortNum==1){
return p1.age - p2.age
}else{
return p2.age - p1.age
}
})
}
return filPerson;
}
},
watch:{
firstName:function(newVal,oldVal){
this.fullName1 = newVal + ' ' + this.lastName
},
lastName:function(newVal,oldVal){
this.fullName1 = this.firstName + ' ' + newVal
}
}
}
</script>
<style>
.box{
width:400px;
height:400px;
}
.fade-enter,.fade-leave-to{
opacity:0;
}
.fade-enter-active,.fade-leave-active{
transition:opacity .5s;
}
</style>
父组件向子组件传值
父组件通过子组件模板向子组件传递数据、方法甚至自身
子组件通过props接收传值
父:
<template>
<div id="parent">
<v-child :msg='msg' :run='run' :parent='this'></v-child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
name:'Parent',
component:'Parent',
data(){
return {
'msg':'我是父组件'
}
},
components:{
'v-child':Child
},
methods:{
run(data){
alert('子组件调用父组件的方法,传值是' + data)
}
}
}
</script>
<style>
</style>
子:
<template>
<div id="child">
{{msg}}
<button @click="run('123')">调用父组件的方法</button>
{{this.parent.msg}}
</div>
</template>
<script>
export default {
props:['msg','run','parent'],
mounted(){
this.parent.run()
}
}
</script>
<style>
</style>
父组件主动获取子组件的数据、方法
<v-child ref="child"></v-child>
this.$refs.child.runChild()
this.$refs.child.msg
子组件主动获取父组件的数据、方法
this.$parent.runParent()
this.$parent.msg
非父子组件间的传值
var brother = new Vue()
$emit广播
brother.$emit('toBrother2',this.msg)
$on接收
brother.$on('toBrother2',data=>{
console.log(data)
})
路由
1.安装
npm install vue-router --save / cnpm install vue-router --save
2、引入并 Vue.use(VueRouter) (main.js)
import VueRouter from 'vue-router'
Vue.use(VueRouter)
3、配置路由
1、创建组件 引入组件
2、定义路由 (建议复制s)
const routes = [
{
path: '/foo',
component: Foo,
children:[//子路由,嵌套路由
{path:'children1',component:Children1},
{path:'children2',component:Children2}
]
},
{ path: '/bar', component: Bar },
{ path: '*', redirect: '/home' } /*默认跳转路由*/
]
3、实例化VueRouter
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
4、挂载
new Vue({
el: '#app',
router,
render: h => h(App)
})
5 、根组件的模板里面放上这句话 <router-view></router-view>
6、路由跳转
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
动态路由
1.
path: '/Content/:aid',
<router-link :to="'/Content/'+key"></router-link>
新页面获取aid:this.$route.params.aid
2.get方法
path: '/Content',
<router-link :to="'/Content?aid='+key"></router-link>
新页面获取aid:this.$route.query.aid
3.编程是导航即Js跳转路由
除了上面的router-link跳转路由,还可以用JS通过点击事件去跳转
this.$router.push('/Content')
this.$router.push('/Content/aid')
移动端组件库-Mint UI
http://mint-ui.github.io/#!/en
安装
npm install mint-ui --save
引入
main.js中全局引入
import MintUI from ‘mint-ui’
import 'mint-ui/lib/style.css
Vue.use(MintUI)
PC端组件库-Element UI
http://element-cn.eleme.io/#/zh-CN
安装
npm install element-ui --save
引入
main.js中全局引入
import ElementUI from ‘element-ui’;
import ‘element-ui/lib/theme-chalk/index.css’;
Vue.use(ElementUI);
Vuex
https://blog.csdn.net/weixin_40970987/article/details/81909531
两个用途:
1.组件之间共享数据;
2.持久化存储数据
用法:
store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {//存储数据
count:1
}
const mutations = {//用于改变数据
incCount(){
++state.count
}
}
const actions = {//触发mutations中的方法
increment(context) {
context.commit('incCount')
}
}
const getters = {//计算属性,直接返回计算之后的结果
incComputed () {
return state.count * 2
}
}
export default new Vuex.Store({//暴露出去
state,
mutations,
actions,
getters
})
模板中使用:
<template>
<div id="page1">
{{this.$store.state.count}} 获取state中的值
{{this.$store.getters.incComputed}} 获取展示getters计算返回的数据
<el-button type="primary" @click="incCount()">+</el-button>
<el-button type="primary" @click="increment()">+</el-button>
</div>
</template>
<script>
import store from '../../vuex/store.js'
export default {
store,
methods:{
incCount(){
//对应mutations
this.$store.commit('incCount')
},
increment(){
//对应actions
this.$store.dispatch('increment')
}
}
}
</script>