成都网站建设需要多少钱,深圳网站建设外贸公司,网站地图怎么生成,wordpress添加flash游戏vue是根据数据来构建用户界面的一套框架
创建一个vue实例
!--
1.创建一个容器
2.引入vue.js开发版本#xff08;全局的#xff09;
3.创建实例对象
4.配置选项 完成渲染
--
div idapp{{ msg }}
/div
script srcvue.js!--
1.创建一个容器
2.引入vue.js开发版本全局的
3.创建实例对象
4.配置选项 完成渲染
--
div idapp{{ msg }}
/div
script srcvue.js/script
scriptconst app new Vue({el:#app,data:{msg: hello vue}})
/script插值表达式 {{ }}
利用表达式进行插值渲染到页面。所谓表达式就是有结果的一段代码。
语法{{ 表达式 }}
注意 1.使用的数据必须存在data 2.标签属性中不能使用
vue指令
指令带有v-前缀的特殊标签属性
动态的解析标签v-html“表达式”-innerHTML
v-show和v-if
作用控制元素的显示和隐藏 v-show“true/false”使用display:none实现的频繁切换显示隐藏的场景 v-if“true/false”通过判断条件来创建或移除元素节点要么显示要么隐藏不频繁切换的场景
v-else和v-else-if
作用辅助v-if进行判断渲染
v-on
作用注册事件 添加监听 提供处理逻辑 语法 v-on事件名“内联语句” v-on事件名“methods中的函数名” 事件名 “ ” 注意methods里的函数的this指向创建的实例如果要传参数这样写click“fn(参数1,参数2)”
v-bind
作用动态的设置html的标签属性 - src url title… 语法v-bind:属性名“表达式”有省略的写法 :属性名“表达式”
v-for
作用基于数据循环多次渲染整个元素 - 数组、对象、数字… 语法v-for“(item每一项,index下标) in 数组” v-for里面的key给列表项添加的唯一标识符便于vue进行列表项的正确排序复用 :key“唯一标识符” v-model
作用给表单元素使用双向数据绑定 - 可以快速获取或者设置表单元素内容 v-model 变量‘
指令修饰符
通过 “.” 指明一些指令后缀不同后缀封装了不同的处理操作 - 简化代码 eg: keyup.enter 键盘回车监听 v-model.trim 去除首位空格 v-model.number 转数字 事件名.stop 阻止冒泡 事件名.prevent 阻止默认行为
v-bind对于样式控制的增强 - 操作class :class“对象/数组” 对象键是类名值为true有这个类否则没有这个类
div classbox :class{类名1: 布尔值类名2: 布尔值}/div数组数组中所有的类都会添加到盒子上本质上就是一个class列表
div classbox :class[类名1类名2]/div计算属性
基于现有的数据计算出来的新属性。依赖的数据发生变化自动重新计算。
computed: {计算属性名 () {//基于现有的数据编写求值逻辑return 结果}
}computed计算属性 vs methods方法
computed 计算属性封装了一段对数据的处理求得一个结果
写在 computed 配置项中作为属性直接使用 - this.计算属性 {{ 计算属性 }}
methods 方法给实例提供一个方法调用以处理业务逻辑
写在methods 配置项中作为方法需要调用 - this.方法名() {{ 方法名() }} 事件名“方法名”
计算属性完整写法
计算属性默认简写只能读取访问不能修改要修改需要写计算属性的完整写法
computed: {计算属性名: {get() {一段代码逻辑计算逻辑return 结果},set(修改的值) {//当计算属性的值被修改时实行set 一段代码逻辑修改逻辑}}
}watch侦听器监视器
作用监视数据变化执行一些业务逻辑或者异步操作 简单写法-简单类型数据直接监视
data: {words: 苹果obj: {words: 苹果}
},watch: {//该方法会在数据变化时触发执行oldValue一般不用只有一个newValue数据属性名 (newValue,oldValue) {一些业务逻辑 或 异步操作},对象.属性名(newValue,oldValue) {一些业务逻辑 或 异步操作}
}完整写法 - 添加额外配置项 1deep: true 对复杂类型深度监视 2immediatetrue 初始化立刻执行一次handler方法
data: {obj: {words: 苹果lang: italy},
},watch: {对象名: {deep: true,immediate: true, //初始化就立即执行不必等到数据变化handler (newValue) {console.log(newValue)}}
}Vue生命周期和生命周期的四个阶段
vue生命周期一个vue实例从创建到销毁的整个过程
阶段
创建阶段准备响应式数据之后就可以请求后台的数据了挂载阶段渲染模板更新阶段修改数据更新视图这里可以循环进行销毁阶段销毁
生命周期函数钩子函数
概念vue生命周期过程中会自动运行一些函数 - 让开发者可以在特定阶段运行自己的代码
工程化开发和脚手架
传统核心包开发模式基于html、css、js文件开发vue 工程化开发模式基于构建工具如webpack的环境中开发vue vue CLI是vue官方的一个全局命令工具可以帮我们快速创建一个开发vue项目的标准化基础架子webpack配置 使用步骤
根据官方安装CLI检查vue版本vue -version创建项目架子vue create project-name启动项目npm run serve
脚手架目录文件项目运行流程
目录文件的截图 项目运行流程npm run开始启动项目之后加载 main.js该js文件将app.vue这个就是一开始学习写在标签里的模板根组件渲染到 index.html 容器中展示页面。
//文件核心作用导入App.vue基于App.vue创建结构渲染index.html
//1、导入 Vue 核心包
import Vue from vue
//2、导入 App.vue 根组件
import App from ./App.vue
//提示当前处于什么状态生产环境/开发环境
Vue.config.productionTip false
//1、Vue实例化。提供render方法 基于App.vue创建结构渲染index.html
new Vue({render: h h(App),
}).$mount(#app)//这一行的效果相当于 el: #app
组件化开发根组件 Vetur插件
组件化一个页面可以划分成一个个组件每个组件有着自己独立的结构、样式、行为。好处便于维护利于复用提升开发效率。
普通组件的注册使用
组件注册的两种方式
局部注册只能在注册的组件内使用 1 创建 .vue文件 2 在使用的组件内导入并注册
//比如在app.vue
//导入需要注册的组件
import 组件对象 from .vue文件路径
import HmHeaderr from ./components/HHmHeaderexport default {//局部注册components: {组件名: 组件对象HmHeader: HmHeader}
}全局注册所有组件内都能使用 1 创建 .vue 文件 2 main.js中进行全局注册
import HmButton from ./components/HmButton
// 调用Vue.component 进行全局注册
// vue.component(组件名,组件对象)
Vue.component(HmButton,HmButton)组件的三大部分组成
结构template只有一个根元素 样式style全局样式默认影响所有组件局部样式scoped下样式只作用于当前组件 逻辑scrriptel跟实例独有组件中的data是一个函数其他配置项一致
export default {data () {return {count: 999}}
}组件通信
1.父子关系 props 和 $emit 父组件通过props将数据传递给子组件子组件利用 $emit通知父组件修改更新 父组件先动态绑定属性值然后子组件通过prpos{‘属性名’}来接受父组件的值
vuex 2.非父子关系 provide inject eventbus vuex
prop
定义组件上注册的一些自定义属性 作用向组件传递数据 特点任意数量任何类型
props校验
props: {校验的属性名: 类型
}
props: {校验的属性名: {type: 类型,required: true,//是否必填default: 默认值,//默认值validator (value){//自定义校验逻辑return 是否通过校验}}
}prop data,单向数据流
单向数据流子组件要修改父组件传来的值只能告诉父组件让父组件改 prop外面传进来的值不能随便改 data自己的值随便改
非父子通信 - event bus 事件总线 非父子通信 - provide inject v-model 原理
div id appinput v-modelmsg typetextinput :valuemsg inputmsg $event.target.value typetext
/div表单类组件封装 v-model 简化代码
步骤
父传子数据由父组件通过props传递过来然后拆解v-model来绑定数据子传父监听输入将值再传递给父组件
//子组件Sun
select :valueCityId changehandleChangeoption value102/option
/select
props: {cityId: String
},
methods: {handleChange(e){this.$emit(事件名,e.target.value)}
}//父组件
faSelect :cityIdselected 事件名selected $event/faSelect以上代码的简化
子组件中props传值要给value触发事件为 input 事件父组件中v-model给组件直接绑定数据:value input
//子组件
select :valuevalue change“handle”option value102.option
/select
props: {value: Number
}
methods: {handle(e){this.$emit(input,e.target.value)}
}//父组件
select v-modelselectId /.sync 修饰符
作用可以实现子组件与父组件数据的双向绑定 特点prop属性名可以自定义非固定为value 场景封装弹框类的基础组件visible属性true显示fale隐藏
// 父组件
BaseDia :visible.syncisShow/
---------------------------------上下一样
BaseDia :visibleisShow update:visibleisShow $event/// 子组件
props: {visible: Boolean
},
this.$emit(update:visable,false)ref 和 $refs
作用利用ref和$refs可以用于获取dom元素或者组件实例 特点查找范围 当前组件内
获取DOM
第一步找到目标标签添加 ref 属性
div refcharRef111/div第二步恰当时机通过this.$refs.xxx获取目标元素
mounted () {console.log(this.$refs.charRef)
}获取组件实例
第一步找到目标组件添加 ref 属性
BaseForm refbaseForm/BaseForm第二步恰当时机通过 this.$refs.xx获取目标组件就可以调用组件对象里面的方法
this.$refs.baseForm.组件方法()vue异步更新dom $nextTick
Vue是异步更新DOM的想要在DOM更新完成之后做某件事可以使用$nextTick
//这段代码起不到作用第一句异步更新第二句会再第一句前面执行
handleEdit () {//1.显示输入框this.isShowEdit true//2.让输入框获取焦点this.$refs,inp.focus()
}
// 修改代码
handleEdit () {//1.显示输入框this.isShowEdit true//2.让输入框获取焦点this.$nextTick((){this.$refs,inp.focus()})
}自定义指令
全局注册
Vue.directive(指令名.{//inserted 会在指令所在的元素插入到页面中的时候出发inserted (el) {//el 就是指令所绑定的元素el.focus()}
})局部注册
directives: {指令名: {inserted () {//可以对el标签扩展额外功能el.focus()}}
}自定义指令 - 指令的值
需求实现一个color指令 - 传入不同的颜色给标签设置文字颜色
语法再绑定自定义指令时可以通过“等号”的形式为指令绑定具体的参数值
div v-colorcolor1我是内容/div通过binding.value 可以拿到指令值指令值修改会触发update函数
data () {return {color1: red}
},
directives: {color: {//提供的是元素被添加到页面中时的逻辑inserted (el,binding) {el.style.color binding.value},//指令的值的修改的时候触发提供值变化后dom更新的逻辑update (el,binding) {el.style.color binding.value}}
}插槽
作用让组件内部的一些结构支持自定义 用法 第一步将希望自定义组件的某部分使用 slot 占位
!--组件TodoList--
templatediv111/divslot/slotdiv/div
/template第二步在使用组件的地方自由定制
TodoList!--在这里自定义想要的内容--span我在这里自定义将在slot部位显示/span
/TodoList插槽默认内容的显示
只需要在 slot 部位写入默认值就可以当使用插槽的时候自定义的内容就会覆盖掉默认内容
具名插槽
作用组件内有多处需要自定义
!--MyDialog组件--
divslot namehead/slot
/div
divslot namecontent/slot
/div
divslot namefooter/slot
/divMyDialogtemplate v-slot:head自定义内容1/templatetemplate v-slot:content自定义内容2/templatetemplate #footer自定义内容3/template
/MyDialog作用域插槽
封装通用组件
VueRouter(5 2)
下载下载VueRouter模块到当前工程版本3.6.5
npm 引入
import VueRouter from vue-router安装路由对象
Vue.use(VueRouter)创建路由对象
const router new VueRouter()注入将路由对象注入到 new Vue 实例中建立关联
new Vue({render: h h(App),router
}).$mount(#app)两个核心的步骤
创建需要的组件views目录配置路由柜子 Find.vue My.vue Friend.vue
import Find from ./views/Find.vue
import My from ./views/My.vue
import Friend from ./views/Friend.vueconst router new VueRouter({routes: [{path: /find,component: Find},{path: /my,component: My},{path: /friend,component:Friend},]
})2.配置导航配置路由出口路径匹配的组件显示的位置
div classfooter_wrapa href#/find发现音乐/aa href#/my我的音乐/aa href#/friend朋友/a
/div
div classtoprouter-view/router-view
/div组件存放目录问题组件分类
src/views 文件夹页面组件-页面展示-配合路由使用src/components文件夹复用组件-展示数据-常用于复用
路由封装
将原来在main.js中的路由代码剪切到 src/router/index.js 文件中方便管理原来的路径可以写成绝对路径 代表 src 目录
声明式导航 - 导航链接
vue-router 提供了一个全局组件 router-link取代a标签 能实现跳转配置 to 属性来指定路径必须相比于a标签省略 # 自带高亮类名可以通过css手动设置高亮类型 router-link-active 模糊匹配 to“/my可以匹配 /my /my/a /my/b … router-link-exact-active 精确匹配 to”/my 只可以匹配 /my 如何自定义这两个类名
const router new VueRoouter({routes:[...],linkActiveClass:类名1,linkExactiveClass:类名2
})声明式导航-跳转传参
查询参数传参适合传多个参数
to “/path?参数名值”对应页面组件接受传递过来的值 $router.query.参数名
动态路由传参 (单个)
配置动态路由
const router new VueRouter({routes: [...,{path: /search/:参数名,component: Search}]
})配置导航链接 to“/path/参数值”对应页面组件接受传递过来的值 $route.params.参数名 可选符 ? 如果按照第一步那样配置参数名的话在跳转链接的时候就必须有参数名如后面增加可选符的话有没有参数就都可以 path: ‘/search/:参数名?’, 路由重定向
问题网页打开后url是默认路径 / 未匹配到组件时会出现空白 重定向匹配到某一路径的时候强制跳转到某一路径
const router new VueRouter({routes: [{path: /,redirect: /home},{path: /home,component: Home},]
})路由 404
作用当路径找不到匹配时给一个提示页面 位置在路由地址配置项的最后
const router new VueRouter({routes: [{path: /,redirect: /home},{path: /home,component: Home},{path: *,component: NotFind} //当前面两个选项都匹配不到的时候就轮到这行了]
})路由模式
hash 路由默认history路由常用上线需要服务端支持
const router new VueRouter({routes: [{path: /,redirect: /home},{path: /home,component: Home},{path: *,component: NotFind} //当前面两个选项都匹配不到的时候就轮到这行了],mode: history
})编程式导航 - 按钮基本跳转
methods: {goSearch() {//通过路径的方式跳转// 1this.$router.push(/search)// 2this.$router.push({path: /search })}
}//通过命名路由的方式跳转适合名字长的
const router new VueRouter({routes: [{path: /,redirect: /home},{name: search path: /home,component: Home},{path: *,component: NotFind} //当前面两个选项都匹配不到的时候就轮到这行了],mode: history
})
methods: {goSearch() {this.$router.push({name: search})}
}编程式导航 - 路由传参
// 通过路径参数传参
data () {return {inpvalue: }
},
methods: {goSearch() {//通过路径的方式跳转// 1this.$router.push(/search?key${this.inpvlaue})// 2this.$router.push({path: /search,query: {key: this.inpValue }})}
}
//接受key
{{this.$route.query.key}}// 动态路由传参
methods: {goSearch() {//通过路径的方式跳转// 1this.$router.push(/search/${this.inpValue})// 2this.$router.push({path: /search/${this.inpValue}})}
}
//接受
$route.pramas.words组件缓存 keep-alive
概念是Vue的内置组件当他包裹动态组件的时候会缓存不活动的组件实例而不是销毁他同时有了新的钩子函数同时他是一个抽象组件自身不会渲染DOM元素。 能解决的问题在组件切换过程中可以避免组件的多次重复渲染减少了加载时间提高用户体验 三个属性
include组件名数组只有匹配的组件会被缓存exclude组件名数组只有匹配的组件会被缓存max最多可以缓存多少组件实例
新的两个生命周期钩子
actived激活时组件被看到时触发deactived失活时离开页面组件不看见
vuex概述
1.是什么 vuex是一个vue的状态数据管理工具。vuex是一个插件可以帮我们管理vue通用的数据多组件共享的数据 2.场景 某个状态在很多个组件来使用多个组件共同维护一份数据
新建一个空仓库
安装 vuex新建 store/index.js 专门存放 vuex注册 Vue.use(Vuex) 创建仓库 const store new Vuex.Store()main.js 中导入挂载
//创建数据
const store new Vuex.Store({state: {count: 100 }
})
// 使用方法
// 模板中 {{$store.state.xxx}}
// 逻辑组件中this.$store.state.xxx
// JS模块中store.state.xxx以上代码可以通过辅助函数 mapState() 帮助我们把store中的数据自动映射到组件的计算属性中
// 在需要的组件中先导入这个函数
import {mapState} from vuex
// 计算属性中使用
computed: {...mapState([count])
}
// 模板中使用 {{ count }}核心概念 - mutations同步
vuex同样遵循单向数据流组件中不能直接修改仓库里的数据(strict: ture可以开启严格模式)
mutations可以来修改state数据。state数据的修改只能通过它
const store new Vuex.Store({state: {count: 100 },mutations: {add (state) {state.count 1}}
})
// 组件中调用mutations
this.$store.commit(add)mutations的传参语法
mutations: {add (state,n) {state.count n}
}// 组件提交中调用
this.$store.commit(add,10)mapMutations把位于mutations中的方法提取出来映射到组件methods中
mutations: {add (state,n) {state.count n}
}
// 组件中直接调用这个方法
import {mapMutations} from vuex
methods: {...mapMutations({add})//相当于组件中有了这个函数
}核心概念 - actions
相比于mutations同步处理数据便于监测数据变化记录调试actions能处理异步操作
// 组件中调用actions中的方法
methods: {change () {this.$store.dispatch(方法名载荷) }
}
// 提供actions方法
actions: {方法名 (context, 载荷) {setTimeout((){context.commit(m中的方法,载荷)}) }
}
// mutations 中接受 actions
mutations: {m中方法 (state,载荷){state.count 载荷}
}mapActions…也是映射到组件的methosd方法中
核心概念-getters
类似于之前的计算属性,有时候我们还需要从state中派生出一些状态这些状态依赖state此时会用到getters
getters: {filterList (state) {return state.list.filter(item item 5)}
}组件中访问getters的方法有两种 底层{{ $store.getters.filterList }} 通过辅助函数在计算属性中注册在模版中直接插入表达式 辅助函数小结 state和getters都是在组件的计算属性中注册 mutations和actions是在组件的方法中注册 核心概念-模块module
解决的问题因项目太大而导致的state臃肿不以维护从而将他拆解成多个模块。
// 创建小的模块 store/modules/user.js
const state {userInfo: {name: ‘zjx’age: 18 }
}
const mutations {}
const actions {}
const getters {}
export default {state,mutations,actions,getters
}
// 将小的模块挂载到main.js中的store中
import user from ‘./modules/user’const store new Vuex.Store({modules: {user}
})模块中state的访问方法
直接通过模块名访问 $store.state.模块名.xxx通过mapState映射 根级别的映射 mapState([‘模块名’]) 模块名.小组.小组成员子模块的映射需要在模块文件中开启命名空间 namespaced: true ) mapState(‘组件民’,[’ 小组 ]) 小组.小组成员
模块中getters的访问方法
原生方法直接通过模块名访问 $store.getters[’ 模块名 / xxx ]mapGetters映射与state相同
模块中mutation的访问方法
默认模块没有开启命名空间mutation 和 actions会被挂载到全局只有开启命名空间才会挂载到子模块
原生方法 $store.commit( ’ 模块名/mutation中方法 , 额外参数 )mapMutations映射 mapMutations([’ xxx ])mapMutations(‘模块名’[‘xxx’]),需要开启命名空间
模块中action的访问方法与mutation类似
基于json-server工具模拟后端接口服务环境
安装全局工具仅一次json-server代码根目录新建一个 db 目录将资料 index.json 移入db目录进入 db目录执行命令启动后端接口服务访问接口测试 http://localhost:3000/