Vue项目笔记
使用脚手架工具常见Vue项目
安装 Vue-cli脚手架工具
npm install -g @vue/cli
# OR
yarn global add @vue/cli
还可以用这个命令来检查其版本是否正确
vue --version
创建Vue项目
vue create 项目名
运行项目
cd 项目名 //计入项目目录
运行
yarn serve
出现以下内容未成功
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.0.104:8080/
项目目录双明
Vue-Router的使用
安装
npm install vue-router@4
创建路由在router目录项创建index.js文件
//引入vue
import vue from 'vue'
//引入VueRouter
import VueRouter from 'vue-router'
//告诉vue要是用vueRouter插件
Vue.use(VueRouter)
创建路由
const router =[
{
path:"/",
redirect:"/money"
},
{
path:'/money',
component:Money
},
{
path:"/labels",
component:Labels
},
{
path:"/labels/tag/:id",
component: TagLable
},
{
path:"/statistics",
component:Statistics
},
{
path:"*",
component: onFile
}
]
//导出路由
const router = new VueRouter({
routes
})
export default router
在src目录项的 main.ts引入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
引入vue中
new Vue({
router
render: h => h(App)
}).$mount('#app')
router-link
请注意,我们没有使用常规的 a 标签,而是使用一个自定义组件 router-link 来创建链接。这使得 Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。我们将在后面看到如何从这些功能中获益。
使用
<div id="app">
<h1>Hello App!</h1>
<p>
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
</div>
router-view
router-view 将显示与 url 对应的组件。你可以把它放在任何地方,以适应你的布局。
<div id="app">
<h1>Hello App!</h1>
<p>
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
路由参数的设置合和获取
设置
const router=[
{
path:"/labels/tag/:id",
component: TagLable
},
]
传参
<div>
<router-link to="/labels/tag/124">Go to Home</router-link>
</div>
在vue项目中获取路由的参数
TagLable组件
<template>
<div >
{id}
</div>
</template>
<script>
export default {
data(){
return {
getId:''
}
},
created(){
this.getId=$route.params.id
}
}
</script>
在vue项目中创建.vue为后缀的文件
注意:在vue组件中temlate标签中只能有一个父元素
<temlate>
<div>
我是一个组件<sapn>{{ name }}</sapn>
</div>
</temlate>
<script>
//在vue组件中data只能用函数星驰
export default{
data(){
return{
name:'小明'
}
}
}
</script>
注意lang='scss'表示样式使用scss
scoped表示样式只能在这里生效
<style lang="scss" scoped>
div{
border:1px solid red;
sapn{
color:red;
}
}
</style>
全局组件的声声明
全局组件在任何地方都可以使用
import Vue from 'vue';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
import store from './store';
//首先引入组件
import Nav from "@/components/Nav.vue";
import Layout from "@/components/Layout.vue";
import icon from "@/components/Icon.vue";
Vue.config.productionTip = false;
//注册组件
Vue.component("Nav", Nav);
Vue.component("Layout", Layout);
Vue.component("Icon", icon);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
vue局部组件
<template>
<div>
//使用组件
<Tag></Tag>
</div>
</template>
<script>
//使用import引入组件
import Tag from '@/compontents/tag.vue'
export default{
//注册组件让其可以被使用
compontents:{tag}
}
</script>
<style>
div{
background:red;
}
</style>
父子组件的传值
在项目中父组件子组件以属性绑定的方式传值给子组件,子组件一个props接受
父组件以属性的方式传值给子组件
<template>
<div>
<Tag name='小明'></Tag>
</div>
</template>
============
子组件
<template>
<div>
{{ name }}
</div>
</template>
<script>
export default {
props:['name']
}
</script>
子组件向父组件创智
在项目中子组间自定义事件,由父组件触发该自定义事件进行传参
<template>
<div>
{{ name }}
<Tag name='小明' @update:name=“setName”></Tag>
</div>
</template>
<script>
export default{
data(){
return{
name:''
}
},
methods:{
setName(value){
this.name = value
}
}
}
</script>
============
子组件
<template>
<div>
<span @click='go('good')'>向父组件传值</span>
</div>
</template>
<script>
export default {
props:['name'],
methods:{
go(value){
this.$emit('update:name',value)
}
}
}
</script>
图标
下载的svg文件,放置到src/assets/icons目录下
安装svgo-loader,svg-sprite-loader -D
进行webpack的配置如下:(其实在@vue/cli文档的 webpack部分有提示)
//vue.config.js文件中
const path = require("path");
module.exports = {
lintOnSave: false,
//这里是配置内容
chainWebpack: config => {
const dir = path.resolve(__dirname, 'src/assets/icons')
config.module
.rule('svg-sprite')
.test(/\.svg$/)
.include.add(dir).end()
.use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end()
//svg区fill解决方案
.use('svgo-loader').loader('svgo-loader')
// .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]}))
.end()
config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'),[{plainSprite: true}])
config.module.rule('svg').exclude.add(dir)
}
}
报错:
当在 vue.config.js 中:
const path = require("path");
提示报错:
error: Require statement not part of import statement
解决方案如下:
//.eslintrc.js文件
rules: {
'@typescript-eslint/no-var-requires': 0,
},
进行上述三个步骤后,使用 svg 标签,然后svg标签内使用 use 标签
<svg>
<use xlink:href="#label" />
</svg>
import 引入icon图标目录
上面的步是单独引入对应的svg文件 因为项目用到的图标很多,所以要引用整个icon目录。为了方便使用,将svg标签和use标签封装进Icon组件,并全局注册Icon组件,其中的use的href部分接受外部数据,
//Icon.vue组件
<template>
<svg class="icon" aria-hidden="true">
<use xlink:href="#xiong"></use>
</svg>
</template>
<script lang="ts">
//引入icon图标目录
let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {importAll(require.context('../assets/icons', true, /\.svg$/));} catch (error) {console.log(error);}
export default {
props:['iconName']
}
</script>
<style scoped >
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
使用Icon组件即可
<Icon icon-name="xiong"></Icon>
去 fill 属性
svg 自带的 fill 属性使图标有颜色,只要在iconfont阿里矢量图标库里执行批量去色操作即可。
报错:__WebpackModuleApi is not defined no-undef
引入icon目录的操作在显示的时候没有问题,但是提交时报错:__WebpackModuleApi is not defined no-undef。
//.eslintrc.js文件
module.exports={
……
rules:{……},
"globals":{ //与上方的rules是同级的
"__WebpackModuleApi": true
},
}
在vue项目中使用typescript
<template>
<div class="home">
<Ts :age="age "></Ts>
<button @click="go"> 按钮</button>
</div>
</template>
<script lang="ts">
//引入
import {Component, Vue, Watch} from 'vue-property-decorator';
import Ts from "@/components/Ts.vue"; // @ is an alias to /src
//使用组件器
@Component({
//添加组件
components: {
Ts,
},
})
export default class Home extends Vue {
//添加data数据
age = '25';
//事件函数
go() {
this.age = '65'
}
//watch使用方法 val改变后的值,oldVal之前的值
@Watch('age')
onAgeChanged(val: string, oldVal: string) {
console.log(val)
console.log(oldVal)
}
}
</script>
//Ts.vue文件
<template>
<div>
姓名:{{ name }} 年龄:{{ age }}
</div>
</template>
<script lang="ts">
import Vue from "vue";
import {Component, Prop} from "vue-property-decorator";
@Component
export default class Ts extends Vue {
name = '小明';
//接收外部参数
@Prop() age!:string
}
</script>
<style lang="scss" scoped>
</style>
vuex中state和mutations基本用法
vuex相当于全局数据管理工具
// /src/store/index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
//告诉vue要使用vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name:"小明"
},
mutations: {
}
})
// src/index.js文件
import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
//映入store
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
在store.vue中使用
<template>
//state相当于data属性
//state中的数据this.$store.state.属性名
//使用this.$store.state.name(获取state中的name)
<div>{{ this.$store.state.name }}</div>
<button @click="update"></button>
</template>
<script lang="ts">
import Vue from "vue";
export default class store extends Vue {
update(){
//mutations相当于methods
//使用this.$store.commit(('updateNname','小红')
//调用mutations中的方法
// this.$store.commit(('方法名','参数')
this.$store.commit('updateNname','小红')
}
}
</script>
<style lang="scss" scoped>
</style>