Here, you can get source code.
Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable.
Vue
Using IDEA plugin:
Using Vue, You can create an index.html
file and include Vue with:
or:
Declarative Rendering
At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax:
{{ message }}
You can offer the data by:
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
Run it:
Hello Vue!
The data and the DOM are now linked, and everything is now reactive. How do we know? Open your browser’s JavaScript console (right now, on this page) and set app.message
to a different value. You should see the rendered example above update accordingly.
Note that we no longer have to interact with the HTML directly. A Vue app attaches itself to a single DOM element (#app
in our case) then fully controls it.
In addition to text interpolation, we can also bind element attributes like this:
Hover your mouse over me for a few seconds
to see my dynamically bound title!
var app2 = new Vue({
el: '#app-2',
data: {
message: 'You loaded this page on ' + new Date().toLocaleString()
}
})
Hover your mouse over me for a few seconds to see dynamically bound title.
Here we are encountering something new. The v-bind
attribute you are seeing is called a directive. Directives are prefixed with v-
to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here, it is basically saying “keep this element’s title
attribute up-to-date with the message
property on the Vue instance.”
If you open up your JavaScript console again and enter app2.message = 'some new message'
, you’ll once again see that the bound HTML - in this case the title
attribute - has been updated like before.
Conditionals and Loops
It’s easy to toggle the presence of an element, too:
Now you see me
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
result:
Now you see me
Go ahead and enter app3.seen = false
in the console. You should see the message disappear.
There are quite a few other directives, each with its own special functionality. For example, the v-for
directive can be used for displaying a list of items using the data from an Array:
-
{{ todo.text }}
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
]
}
})
result:
In the console, enter app4.todos.push({ text: 'New item' })
. You should see a new item appended to the list.
Handling User Input
To let users interact with your app, we can use the v-on
directive to attach event listeners that invoke methods on our Vue instances:
{{ message }}
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
Note that in this method we update the state of our app without touching the DOM - all DOM manipulations are handled by Vue, and the code you write is focused on the underlying logic.
Vue also provides the v-model
directive that makes two-way binding between form input and app state a breeze:
{{ message }}
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
Composing with Components
The component system is another important concept in Vue, because it’s an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components. If we think about it, almost any type of application interface can be abstracted into a tree of components:
In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward:
// Define a new component called todo-item
Vue.component('todo-item', {
template: 'This is a todo '
})
var app = new Vue(...)
Now you can compose it in another component’s template:
But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let’s modify the component definition to make it accept a prop:
Vue.component('todo-item', {
// The todo-item component now accepts a
// "prop", which is like a custom attribute.
// This prop is called todo.
props: ['todo'],
template: '{{ todo.text }} '
})
Now we can pass the todo into each repeated component using v-bind
:
Vue.component('todo-item', {
props: ['todo'],
template: '{{ todo.text }} '
})
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})
run it:
This is a contrived example, but we have managed to separate our app into two smaller units, and the child is reasonably well-decoupled from the parent via the props interface. We can now further improve our
component with more complex template and logic without affecting the parent app.
In a large application, it is necessary to divide the whole app into components to make development manageable. We will talk a lot more about components later in the guide, but here’s an (imaginary) example of what an app’s template might look like with components:
Vue-Axios
Axios是一个开源的可以在浏览器端和NodeJS的异步通信框架,主要作用是实现Ajax异步通信。
准备一份JSON文件:
{
"name": "Q",
"url": "https://hellooooo.top",
"page": 1,
"liangzai": true
}
使用Vue的钩子函数进行Axios异步请求:
var vue = new Vue({
el: '#app',
data: {
message: "Hello"
},
//钩子
mounted(){
axios.get('/Vue/vue-first/data.json').then(response => console.log(response.data));
}
});
结果:
将Axios得到的数据与页面进行绑定:
var vue = new Vue({
el: '#app',
data() {
return{
info: {
name: null,
url: null,
liangzai: null
}
}
},
//钩子
mounted(){
// axios.get('/Vue/vue-first/data.json').then(response => console.log(response.data));
axios.get('/Vue/vue-first/data.json').then(response => this.info = response.data);
}
});
页面:
{{info.name}}
{{info.url}}
{{info.liangzai}}
结果:
计算属性
有缓存的味道。
var vm = new Vue({
el: '#app',
data: {
message: "Hello"
},
methods: {
currentTime: function (){
return Date.now();
}
},
//计算属性
//注意methods和computed尽量不要重名
computed: {
currentTime2: ()=>{
return Date.now();
}
}
});
current: {{currentTime()}}
current: {{currentTime2}}
运行:
可以看到currentTime方法输出的时间都在变化,而currentTime2每次都输出相同的时间戳。
内容分发
Vue.component("todo",{
template: '' +
' ' +
'' +
' ' +
'
' +
''
});
Vue.component("todo-title", {
props: ['title'],
template: '{{title}}'
});
Vue.component("todo-items", {
props: ['item'],
template: '{{item}} '
});
var vm = new Vue({
el: '#app',
data: {
title: "liang",
todoItems: [
'Liang0',
'Liang1',
'Liang2',
'Liang3'
]
}
});
下面的":"是"v-bind:"的简写,":title"相当于"v-bind:title"。
效果:
如果需要在每个项目之后增添一个删除按钮:
Vue.component("todo-items", {
props: ['item'],
template: '{{item}} ',
methods: {
remove: ()=>{
alert("Choose delete.")
}
}
});
var vm = new Vue({
el: '#app',
data: {
title: "liang",
todoItems: [
'Liang0',
'Liang1',
'Liang2',
'Liang3'
]
},
methods:{
removeItems: (index)=>{
console.log("Will remove: " + this.todoItems[index]);
//删除当前
this.todoItems.splice(index, 1);
}
}
});
可以做到监听,但是组件无法做到调用Vue实例的removeItems方法删除数据。
即组件如何删除Vue实例中的数据?
自定义事件
this.$emit
Vue.component("todo",{
template: '' +
' ' +
'' +
' ' +
'
' +
''
});
Vue.component("todo-title", {
props: ['title'],
template: '{{title}}'
});
Vue.component("todo-items", {
props: ['item', 'index'],
template: '{{index}}:{{item}} ',
methods: {
remove: function (index){
// alert("Choose delete.")
this.$emit('remove', index);
}
}
});
var vm = new Vue({
el: '#app',
data: {
title: "liang",
todoItems: [
'Liang0',
'Liang1',
'Liang2',
'Liang3'
]
},
methods:{
removeItems: function (index){
console.log("Will remove: " + this.todoItems[index]);
//删除当前
this.todoItems.splice(index, 1);
}
}
});
Vue-Cli
官方提供的一个脚手架。
先安装Node.js,安装完成后,打开CMD:
C:\Users\Q>node -v
v10.18.0
C:\Users\Q>npm -v
6.13.4
安装淘宝镜像加速器:
# -g 全局安装
npm install cnpm -g
如果不想安装可以在安装的时候增加如下参数:
npm install --registry=https://registry.npm.taobao.org
安装vue-cli:
cnpm install vue-cli -g
查看:
vue list
创建第一个vue-cli应用程序
在命令行执行:
vue init webpack myvue
myvue为项目名称.
初始化并且运行:
cd myvue
npm install
npm run dev
Webpack
安装Webpack:
npm install webpack -g
npm install webpack-cli -g
查看版本:
webpack -v
webpack-cli -v
新建文件夹webpack-study并进入:
mkdir webpack-study
cd webpack-study
新建modules:
mkdir modules
在其内新建一个Hello.js:
//暴露一个方法
exports.sayHi = ()=>{
document.write("Liangzai
")
};
新建一个main.js:
var hello = require("./hello");
hello.sayHi();
在webpack-study内新建一个webpack.config.js:
module.exports = {
entry: './modules/main.js',
output: {
filename: "./js/bundle.js"
}
};
在命令行输入:
webpack
自动生成了bundle.js:
测试使用:
新建index.html:
Hello
Vue-Router
进入自己项目根目录,安装:
npm install vue-router --save-dev
声明使用Vue-Router
import VueRouter from "vue-router";
//显式声明使用Vue-Router
Vue.use(VueRouter);
简单使用:
新建两个Component,一个Content,一个Main:
Content
Main
在src目录下新建router目录,并添加index.js作为配置文件:
import Vue from "vue";
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";
//安装路由
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes: [
{
// 路由路径
path: '/content',
name: "content",
// 跳转组件
component: Content
},
{
// 路由路径
path: '/main',
name: "main",
// 跳转组件
component: Main
}
]
})
编辑main.js配置路由:
//自动扫描里的路由配置
import router from './router';
...
//在Vue实例内配置路由
new Vue({
el: '#app',
//在Vue实例配置路由
router,
components: { App },
template: ' '
})
配置App.vue,添加路由跳转:
靓仔
Main
Content
其他保持不变,运行测试:
Vue + ElementUI
创建一个名为hello-vue的工程:
vue init webpack hello-vue
进入hello-vue安装vue-router,element-ui,sass-loader和node-sass:
npm install vue-router --save-dev
npm i element-ui -S
#安装依赖
npm install
#安装SASS加载器
npm install sass-loader node-sass --save-dev
#启动测试
npm run dev
准备Main页面以及Login页面,
Main:
MAIN
Login:
欢迎登录
登录
请输入账号和密码
路由配置:
import Vue from "vue";
import VueRouter from "vue-router";
import Main from "../views/Main";
import Login from "../views/Login";
Vue.use(VueRouter);
export default new VueRouter({
routes: [
{
path: '/login',
component: Login
},
{
path: '/main',
component: Main
}
]
});
App.vue配置展示界面:
main.js配置:
import Vue from 'vue'
import App from './App'
import router from "./router";
import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(router);
Vue.use(Element);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App),
components: { App },
template: ' '
})
如果报错:
ERROR Failed to compile with 1 errors
可能是sass版本太高所致:
卸载当前sass版本:
npm uninstall sass-loader
npm install [email protected] --save-dev
结果:
路由嵌套
替换Main.vue:
用户管理
个人信息
用户列表
内容管理
分类管理
内容列表
个人信息
退出登录
个人信息
退出登录
我这代码抄得有点问题,但是大致还能看看。
在views下新建user目录并添加List .vue和profile.vue:
UserList
Profile
配置路由组件router/index.js:
import List from "../views/user/List";
import Profile from "../views/user/Profile";
...
export default new VueRouter({
routes: [
{
path: '/login',
component: Login
},
{
path: '/main',
component: Main,//嵌套路由
children: [
{
path: '/user/profile',
component: Profile
},
{
path: '/user/list',
component: List
}
]
}
]
});
测试:
参数传递及重定向
个人信息页面应该因人而异。
修改Main.vue的个人信息的
个人信息
这里的name是路由配置router/index.js中添加的name:
{
path: '/user/profile/:id',
name: 'UserProfile',
component: Profile
}
Profile.vue展示这个数字:
Profile
{{$route.params.id}}
还可以通过props达到目的
关于重定向:
GoHOME
编辑路由配置index.js:
routes: [
{
path: '/login',
component: Login
},
{
path: '/main',
component: Main,//嵌套路由
children: [
{
path: '/user/profile/:id',
name: 'UserProfile',
component: Profile
},
{
path: '/user/list',
component: List
},
{
path: '/goHome',
redirect: '/main'
}
]
}
]
通过redirect进行即可,结果:
比如,我们登录之后需要把用户名展示在页面,我们可以这样。
将用户名放在main路径之后:
修改Login.vue
//使用 vue-router路由到指定页面,该方式称之为编程式导航
this.$router.push("/main" + "/" + this.form.username);
修改index.js:
path: '/main/:name',
component: Main,//嵌套路由
props: true,
children: [
...
修改Main.vue,展示用户名:
{{name}}
...
export default {
props: ['name'],
name: "Main"
}
运行:
如何去除访问路径中的‘#’?
编辑路由配置文件:
export default new VueRouter({
mode: 'history',//hash
...
将模式修改为'history'即可。
404
如何统一展示404?
在views下新建NotFound.vue:
404,Not Found
在路由配置中添加该组件:
import NotFound from "../views/NotFound";
同时配置路径:
routes: [
{
path: '/login',
component: Login
},
...
{
path: '*',
component: NotFound
}
]
测试:
此外,Vue还提供了各种钩子回调:
export default {
name: "Profile",
beforeRouteEnter: (to, from, next) => {
console.log("进入路由之前");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("进入路由之后");
next();
}
}
到时候可以再看。
参考
- Vue
- 【狂神说Java】Vue最新快速上手教程通俗易懂
- # Vue项目 报错TypeError 【ERR INVALID ARG TYPE】: The “path“ argument must be of type string