Vue 是渐进式框架,它的数据是响应式的,基于数据是可变的,数据双向绑定,通过watch对属性进行监听,Vue通过数据劫持结合发布订阅者模式来实现数据双向绑定,它遍历data中的所有属性,通过Object.defineProperty 来劫持各个属性的 setter和getter,在数据变动时,以Dep算法遍历所有订阅者,发布消息触发回调,完成视图更新。
使用须知
文中举例,默认 yarn 和 @vue/cli 是已经安装了,如果没有安装,请先运行以下命令安装后;
npm install yarn -g
npm install @vue/cli -g || yarn add global add @vue/cli
开启项目
vue create xxx
cd xxx
yarn add vue-router
yarn add vuex
yarn add es6-promise //可选,兼容低版本IE
示例代码
import 'es6-promise/auto' //引入低版本兼容polyfill
import Vue from 'vue' //引入vue
import router from './Router' //对路由的放在一个文件里
import store from './vuex' //将vuex放在一个文件里管理
Vue.config.productionTip=false //阻止vue启动生产消息
const App=()=><router-view></router-view> //显示的是当前路由渲染的界面
new Vue({
render: h=>h(App), //render方法渲染
router,
store
}).$mount('#app')
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 组件
import Home from './components/Home.vue'
import Hello from './components/Hello.vue'
import Word from './components/Word.vue'
import Nofined from './components/Nofined'
const routes=[
{path:'/',component:Home},
{path:'/hello',component:Hello, //嵌套路由
children:[
{path:'word',component:Word},
]
},
{path:"*",component:Nofined} //404页面
]
const router=new VueRouter({
routes
})
// 转跳滚动条初始化
router.beforeEach((to, from, next) => {
document.body.scrollTop = 0
document.documentElement.scrollTop = 0
window.scrollTo(0, 0)
next()
})
export default router
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const moduleA = { // modulle管理
state:{}, getters:{}, mutations:{}, actions:{},
}
const store = new Vuex.Store({ //以 Vuex.Store 方法创建实例
state:{ //状态
name:"战争",
},
getters:{ //计算
newName:state=>{
state.name=="1"?return '21':return '11';
}
},
mutations:{//事件 commit
newName(state,data){ //设置名称
state.name=data
}
},
actions:{ //行为 dispatch
newName:function(context,data){
context.commit('newName',data)
}
},
modules:{
one:moduleA
}
})
export default store
相关扩展
在项目中配置模块的相关目录
src/
|——api/ (所有请求:用户相关,功能相关等)
|——user.js
|——assets/ (静态资源:图片,视频,字体等)
|——images/
|——components/ (所有组件:主页,登录,注册等)
|——Home.vue
|——config/ (所有配置项:网关,路由字体大小等)
|——geteway.js
|——router.js
|——store/ (Vuex的数据中心)
|——index.js
|——utils/ (工具集合:请求,常用函数等)
|——require.js
min.js
在手机端设置区分前进后退的代码
//区分前进后退,主要是为了在移动端添加不同的动画
Vue.prototype.push = function(url){ //路由前进
let old=this.$router.currentRoute.path
if(old==url){
this.$router.go(0);
}else{
Vue.prototype.transitionName = "slide-left"; //通过设置不同的class触发动画
this.$router.push(url);
}
};
Vue.prototype.pop = function(n=-1){ //路由后退
Vue.prototype.transitionName = "slide-right";
let path = this.$router.currentRoute.path;
if (path == "/") { return;}
this.$router.go(n);
}
在本地项目中配置proxy解决跨域请求
这是 vue-cli
工具的配置,在项目的根目录创建 vue.config.js
module.exports = {
devServer: { //请求配置
proxy: {
"/user": { //将路径匹配为 /user 的请求转发到该路径
target: 'https://uat.happit.cn/', //转发路径
changeOrigin:true
},
"/api":{
target: 'http://112.126.99.105:8010/',
changeOrigin:true,
pathRewrite:{ //重写路径,将所有api重写为空
'^/api':''
}
},
}
}
}
在项目中配置接口请求和数据异步处理
yarn add axios
yarn add vue-axios
import Vue from 'vue'
import axios from 'axios'
import vueAxios from 'vue-axios'
Vue.use(vueAxios,axios)
import Vue from 'vue'
import axios from 'axios'
//请求拦截器
axios.interceptors.request.use(function (config) {
//添加身份验证
// if(config.headers.Authorization === undefined) {
// config.headers.Authorization = 'Bearer ' + store.state.token
// }
return config;
}, function (error) {
console.log(error)
return Promise.reject(error);
});
function require(option){
return new Promise((fulfill,reject)=>{
Vue.axios(option).then((res)=>{
fulfill(res)
}).catch((rej)=>{
if(rej.response){
reject(rej.response)
}else if(rej.require){
reject(rej.require)
}else{
reject(rej.message)
}
})
})
}
export default require;
// export const network='https://api.ixiaowai.cn'
export const network='' //通过vue-cli设置服务器代理,在上线前需要改正
export const auto='api'
module.exports={
devServer:{
proxy:{
"/api":{
target: 'https://api.ixiaowai.cn/',
changeOrigin:true,
pathRewrite:{ //重写请求路径,将api标记清除
'^/api':''
}
},
}
}
}
import requires from '@/utils/require'
import {network,auto} from '@/config/geteway'
export const saying=function(params){ //接口请求
return require({
url:`${network}/${auto}/ylapi.php`,
method:'GET',
params
})
}
生产代码上路由按需加载
基于vue-cli
// 通过路由切割
const Home=()=>import('@/components/Home.vue')
const routers=[
{path:'/',component:Home}, //在通过路由进行引用,就可以对路由进行切割
]
// 通过异步组件切割:使用 import按需加载的方式也可以进行切割,但如果网络不好就会空白一片,
// 所以需要显示加载中的话就需要用到异步组件的方式
const AsyncComponent = () => ({
component: import('@/MyComponent.vue'), // 需要加载的组件 (应该是一个 `Promise` 对象)
loading: LoadingComponent, // 异步组件加载时使用的组件
error: ErrorComponent, // 加载失败时使用的组件
delay: 200, // 展示加载时组件的延时时间。默认值是 200 (毫秒)
timeout: 3000 // 超时时间和组件加载都超时, 则使用加载失败时使用的组件。默认值是:`Infinity`
})
设置生产打包路径
默认打包路径为根目录,所有需要设置 assetsPublicPath
为 ./
当前路径
module.exports = defineConfig({
//...
publicPath:"./",
})
部分页面或组件进行缓存处理
通过 keep-alive 包裹组件,会缓存不活动的路由。
<!-- include 表示符合该正则的路由组件会缓存 -->
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
{
path: '/account',
name: 'Account',
meta: {keepAlive: true}, // 通过路由的meta参数进行缓存配置
component: () => import('../views/account')
}
问题
Uncaught TypeError: Cannot read properties of undefined (reading ‘install‘)报错,页面全空白
vue-router
的版本问题,vue-router4区别于3 ,没有了默认导出export default的模块,需要使用 import {createrRouter} from ‘vue-router’的方式进行导入;之后在页面引用<router-view>
的时候同样需要进行模块引入;vue.use();建议将vue-router 替换成 3.1.3版本;
在Vue 中 import 引入的路径中的 @ 指代什么?
import require from '@/utils/require'
在Vue中,@ 是指代 /src 目录,是为了防止复杂路径导致的出错;
请求报错 No ‘Access-Control-Allow-Origin’?
该错误很大可能是属于请求跨域报错,需要使用vue-cli设置代理,在根目录创建 vue.config.js
```js vue.config.js
module.exports={
devServer:{
proxy:{
‘user/‘:{
target:”https:xxxx”,
changeOrigin:true,
}
}
}
}